Nginx漏洞利用與安全加固
本文主要分為兩大部分,第一部分介紹了Nginx的一些常見安全漏洞的形成原因、利用方法,并給出了相應(yīng)的解決辦法;第二部分介紹了Nginx安全加固時需要關(guān)注的主要內(nèi)容。
Nginx(發(fā)音同engine x)是一款輕量級的Web服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,由俄羅斯的程序設(shè)計師Igor Sysoev所開發(fā),可以穩(wěn)定地運行在Linux、Windows等操作系統(tǒng)上,其特點是占用內(nèi)存少,并發(fā)能力強。
同其他軟件一樣,Nginx也出現(xiàn)過一些安全漏洞,利用這些漏洞可以對Web服務(wù)器進行滲透攻擊。
下面我們通過實例來介紹幾個關(guān)于Nginx的安全漏洞,以及相應(yīng)的漏洞利用方法。
Nginx漏洞分析實例
Nginx文件類型錯誤解析漏洞
在2010年的時候,國內(nèi)安全組織80Sec發(fā)現(xiàn)了一個Nginx文件類型解析漏洞,但實際上這個并非Nginx本身的漏洞,而是由于配置導(dǎo)致的安全問題。下面我們詳細分析一下這個漏洞。
漏洞分析:Nginx默認是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通過正則匹配設(shè)置SCRIPT_FILENAME。配置文件中會有類似如下內(nèi)容,如圖1所示。

圖1
location對請求進行選擇的時候會使用URI環(huán)境變量進行選擇,其中傳遞到后端Fastcgi的關(guān)鍵變量SCRIPT_FILENAME是由Nginx生成的$fastcgi_script_name來決定的。而通過分析可以看到$fastcgi_script_name是直接由URI環(huán)境變量控制的,這里就是產(chǎn)生問題的點。當(dāng)訪問http://192.168.1.103/phpinfo.jpg/1.php這個URL時,$fastcgi_script_name會被設(shè)置為“phpinfo.jpg/1.php”,然后構(gòu)造成SCRIPT_FILENAME傳遞給PHP CGI,但是PHP為什么會接受這樣的參數(shù),并將phpinfo.jpg作為PHP文件解析呢?
這就要說到fix_pathinfo這個選項了,如圖2所示。

圖2
如果開啟了這個選項,那么就會觸發(fā)在PHP中的如下邏輯,如圖3所示。

圖3
到這里,PHP會認為SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就會將phpinfo.jpg作為PHP文件來解析了。
漏洞危害:利用該漏洞,攻擊者可以將任意文件類型作為PHP文件解析,攻擊者通常利用該漏洞來獲取到一個WebShell。
漏洞利用:假設(shè)某一服務(wù)器存在該漏洞,攻擊者可以通過上傳一張包含PHP后門代碼的圖片來獲取WebShell,這是一種常見的攻擊方式,如圖4所示。

圖4
解決方案:這里介紹兩種解決方案:一、修改php.ini文件,將cgi.fix_pathinfo的值設(shè)置為0;二、在Nginx配置文件中添加以下代碼:
if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}
這行代碼的意思是當(dāng)匹配到類似test.jpg/a.php的URL時,將返回403錯誤代碼,如圖5所示。

圖5
Nginx配置錯誤而導(dǎo)致目錄遍歷漏洞
在Nginx的配置文件中如果開啟了autoindex選項,并采用類似下面的配置時會造成目錄遍歷漏洞,如圖6所示。

圖6
當(dāng)訪問http://192.168.1.103/test/這個URL時,正常情況應(yīng)該遍歷html/test/這個目錄,但是如果訪問http://192.168.1.103/test../這個URL時,則會遍歷上一級目錄(html/)了。
下面我們通過一個實例來演示下這個漏洞,先來看下正常訪問時返回的頁面,如圖7所示。

圖7
現(xiàn)在我們再來看下漏洞被觸發(fā)后返回的頁面,如圖8所示。

圖8
通過圖8所示的返回結(jié)果,我們可以看到利用該漏洞我們成功遍歷到了其上一級目錄。
下面提供兩種方法來解決這個問題,從中選擇一種即可,具體配置如下圖9所示。

圖9
現(xiàn)在我們再來驗證下當(dāng)采用上面的代碼加固Nginx以后,服務(wù)器是否還存在漏洞。

圖10
從圖10的返回結(jié)果可以看到漏洞沒有被觸發(fā),而是返回了404頁面,說明漏洞被修復(fù)。
Nginx安全加固
針對Nginx的安全加固,主要從以下兩個方面考慮:一、Nginx Web Server程序本身是否安全,如是否存在安全漏洞;二、Nginx Web Server是否提供了可使用的安全功能,這部分主要是檢查Nginx的配置是否得當(dāng),是否存在由于配置失誤導(dǎo)致的安全問題。
Nginx版本的選擇與安裝注意事項
在選擇Nginx版本時,需要關(guān)注是否存在安全漏洞和版本的穩(wěn)定性。一般選擇最新的穩(wěn)定版本,這樣可以在穩(wěn)定性和安全之間取得一個平衡。在升級Nginx版本前建議先在測試環(huán)境中測試通過后再正式升級,以避免由于兼容性帶來其他不可預(yù)知的問題。
關(guān)于Nginx的安全漏洞可以關(guān)注Nginx官方發(fā)布的安全公告(http://nginx.org/en/security_advisories.html)或到其他一些漏洞發(fā)布平臺上查找。
在安裝Nginx時建議使用自定義安裝路徑,如果采用默認安裝路徑,很容易被攻擊者和一些自動化攻擊工具猜測到,為其進行下一步的攻擊提供便利。
Nginx安全配置
1. 修改/隱藏Nginx Banner信息
攻擊者在對目標(biāo)服務(wù)器進行滲透攻擊前,通常會有一個目標(biāo)信息收集階段,這個階段的任務(wù)就是通過各種手段獲取到目標(biāo)服務(wù)器的信息,如獲取目標(biāo)服務(wù)器的系統(tǒng)版本、Web、數(shù)據(jù)庫的類型及相關(guān)信息,這個階段獲取到的信息將直接關(guān)系到攻擊者下一步采取的攻擊手段。因此,修改/隱藏Nginx的相關(guān)信息將在一定程度上可以增大攻擊者的攻擊難度,也可以騙過一些自動化攻擊工具。
在Linux平臺下以源碼方式安裝Nginx時,可以通過修改“src/core/nginx.h”中的信息來達到隱藏或自定義Banner信息的目的。
我們先來看下nginx.h這個文件中默認的內(nèi)容,類似圖11所示。

圖11
這時當(dāng)我們訪問Nginx服務(wù)器時,Server字段會返回真實的Banner信息,如圖12所示。

圖12
現(xiàn)在我們來自定義nginx.h中關(guān)于Banner信息的內(nèi)容,可參考圖13。

圖13
修改完成后,重新編譯Nginx,然后安裝即可。安裝完成后,我們再來訪問下該Nginx服務(wù)器,發(fā)現(xiàn)這時Server返回的內(nèi)容為自定義的Banner信息了,如圖14所示。

圖14
2. Nginx日志安全
不論在那種服務(wù)器上,日志都是一個非常重要的部分,我們需要對它嚴加保護。在Nginx上也是如此。Nginx的日志默認存放在安裝目錄的logs目錄下,首先要修改日志的默認保存路徑,然后設(shè)置只允許管理員有日志存放目錄的完全控制權(quán)限。
3. Nginx權(quán)限設(shè)置
Nginx權(quán)限設(shè)置分為Nginx運行權(quán)限設(shè)置和網(wǎng)站目錄權(quán)限設(shè)置兩部分。
Nginx運行權(quán)限是指Nginx以什么權(quán)限運行,以管理員權(quán)限運行是一個非常糟糕的決定。這樣的后果是攻擊者一旦攻擊成功,將直接獲取到一個高權(quán)限的WebShell。因此,我們需要設(shè)置Nginx以一個低權(quán)限的身份運行,可通過修改“Nginx.conf”這個配置文件來實現(xiàn)。
網(wǎng)站目錄權(quán)限設(shè)置則要遵循以下原則:
a) 如果目錄有寫入權(quán)限,一定不要分配執(zhí)行權(quán)限
b) 如果目錄有執(zhí)行權(quán)限,一定不要分配寫入權(quán)限
c) 網(wǎng)站上傳目錄和數(shù)據(jù)庫目錄一般需要分配“寫入”權(quán)限,但一定不要分配執(zhí)行權(quán)限
d) 其他目錄一般只分配“讀取”權(quán)限即可