五個案例“熄滅”Nginx漏洞隱患

Nginx從2004年10月發佈至今,已經趨於成熟和完善。

在連接高併發的情況下,Nginx是Apache服務不錯的替代品,作為一款分佈式輕量級的中間件Nginx也是存在大量的漏洞的。

下面我們針對常見的漏洞來進行探討。

01

目錄遍歷漏洞

漏洞介紹

Nginx的目錄遍歷漏洞屬於配置不當導致的漏洞,錯誤的配置使得目錄被遍歷與源碼洩露‘。該漏洞的產生與nginx.conf文件中的autoindex(目錄瀏覽功能)參數設置有關,默認是關閉的狀態,即autoindex off。例如打開test文件夾,出現403,如下圖所示:

五個案例“熄滅”Nginx漏洞隱患


修改配置文件,該文件位置如下:

五個案例“熄滅”Nginx漏洞隱患


在如下圖所示的位置添加autoindex on,重啟Nginx:

五個案例“熄滅”Nginx漏洞隱患


再次訪問,即可訪問到目錄:

五個案例“熄滅”Nginx漏洞隱患


漏洞修復

將/etc/nginx/sites-avaliable/default裡的autoindex on改為autoindex off。


02

目錄穿越漏洞


漏洞介紹

Nginx經常被做為反向代理,動態的部分被proxy_pass傳遞給後端端口,而靜態文件需要nginx來處理。如果靜態文件存儲在/home/目錄下,而該目錄在url中名字為files,那麼就需要用設置目錄的別名,如下所示:


location /files {
alias /home/;
}

此時,訪問http:// xxx.xx.xx /files/readme.txt,就可以獲取/home/readme.txt文件。但我們注意到,url上/files沒有加後綴“/”,而alias設置的/home/是有後綴“/”的,這個/就導致我們可以從/home/目錄穿越到他的上層目錄,進而我們獲得了一個任意文件下載漏洞:


五個案例“熄滅”Nginx漏洞隱患


漏洞修復

location 和 alias 的值要不都加“/”, 要不都加,統一即可。


03

服務端請求偽造漏洞


漏洞介紹

一般情況下,服務端請求偽造的目標是從外網無法訪問的內部系統,服務端請求是利用存在缺陷的web應用作為代理的遠程和本地的服務器,常出現在反向代理的配置中,反向代理的語法如下:proxy_pass http ://IP。正是因為它是由服務端發起的,所以它能夠請求到與它相連而與外網隔離的內部系統。

這裡將nginx裡的相關配置展示一下:

五個案例“熄滅”Nginx漏洞隱患


如果利用者可以操控IP, 將其修改成內網IP地址即可造成服務端請求偽造漏洞。例如對外網、內網、本地進行端口掃描,某些情況下端口的Banner會顯出來(比如3306),我們可通過返回banner的差異值來猜測內網IP,從而拿到內網IP信息。

漏洞修復

過濾返回信息,驗證遠程服務器對請求的響應是比較容易的方法。如果web應用是去獲取某一種類型的文件。那麼在把返回結果展示給用戶之前先驗證返回的信息是否符合標準。

統一錯誤信息,避免用戶可以根據錯誤信息來判斷遠端服務器的端口狀態。

限制請求的端口為http常用的端口,比如,80,443,8080,8090。

黑名單內網ip。避免應用被用來獲取獲取內網數據,破壞內網。

禁用不需要的協議。僅僅允許http和https請求。可以防止類似於file:///, gopher://, ftp:// 等引起的問題。


04

版本洩露


漏洞介紹

對於nginx服務器,之前曾爆出過不同版本的解析漏洞,比如nginx 0.7.65以下(0.5., 0.6., 0.7. )全版本系列和0.8.37(0.8.)以下8系列受影響。

假設在存在漏洞的站點上有一張圖片url地址為:http://x.x.x.x/logo.jpg , 當正常訪問圖片時,nginx會把這個當作非腳本語言直接讀取傳送會客戶端(也就是瀏覽器),但是存在解析漏洞的nginx會把如下連接解析並且當作php文件執行,也就是前面介紹過的文件解析漏洞:


http://x.x.x.x/logo.jpg/x.php
http://x.x.x.x/logo.jpg%00x.php

因此隱藏 Nginx 的版本號,可以在一定程度上提高安全性。

漏洞修復

在配置文件nginx.conf裡面,設置如下:server_tokens off。


05

整數溢出漏洞

漏洞介紹

在Nginx的range filter中存在整數溢出漏洞,可以通過帶有特殊構造的range的HTTP頭的惡意請求引發這個整數溢出漏洞,並導致信息洩露。

HTTP的Range允許客戶端分批次請求資源的一部分,如果服務端資源較大,可以通過Range來併發下載;如果訪問資源時網絡中斷,可以斷點續傳。Range設置在HTTP請求頭中,它是多個byte-range-spec(或suffix-byte-range-spec)的集合,如下所示:

五個案例“熄滅”Nginx漏洞隱患


其中,first-bytes-pos指定了訪問的第一個字節,last-byte-pos指定了最後一個字節,suffix-length則表示要訪問資源的最後suffix-length個字節的內容。例如:

Range:bytes=0-1024 表示訪問第0到第1024字節;

Range:bytes=500-600,601-999,-300 表示分三塊訪問,分別是500到600字節,601到600字節,最後的300字節。

在Response頭中設置:Accept-Ranges:bytes 表示接受部分資源的請求;

Content-Range: bytes START-END/SIZE 表示返回的資源位置;其中SIZE等於Content-Length;如:Content-Range: bytes 500-600/1000


如果一次請求有多個range,返回的數據需要multipart來組織;格式如下:

五個案例“熄滅”Nginx漏洞隱患


Nginx對Range的支持包括header處理和body處理,分別用來解析客戶端發送過來的Range header和裁剪返回給客戶端的請求數據Body。其實現分別由ngx_http_range_header_filter_module和ngx_http_range_body_filter_module兩個過濾模塊完成。

在ngx_http_range_header_filter_module中調用了ngx_http_range_header_filter函數,而該函數進一步調用了ngx_http_range_parse函數來解析header中的Range字段;分別調用ngx_http_range_singlepart_header和ngx_http_range_multipart_header來生成single range和multi ranges的Response Header;

本次復現利用使用Nginx-1.12.0作為緩存服務器,緩存配置同上文,訪問的目標文件仍然是http://www.baidu.com/img/bd_logo1.png 。

首先,不指定range,得到該圖片文件的長度為7877,如下所示:

五個案例“熄滅”Nginx漏洞隱患


設置第一段range為-8500,此時的start為7877-8500=-623,即圖片在Cache文件偏移之前的623 bytes也會被返回,而這623 bytes中就包含了Cache文件頭部。

下一步,按照上文所說,第二段range的長度需要將總長度溢出。我們的目標總和size為0×8000000000000000,第一段range長度為8500,故第二段range長度為0×8000000000000000-8500=9223372036854767308。

於是,使用curl命令,配合-r參數指定bytes range:

五個案例“熄滅”Nginx漏洞隱患


可以看到返回內容中,第一段即為-8500的range,而這一段中我們就看到了Cache文件頭部,例如cache key以及後端服務器返回的HTTP頭。

漏洞修復

綜合來看,這個漏洞就是整數溢出漏洞的利用,能夠從Cache文件中獲取Cache頭的信息。在某些配置的情況下Cache頭中會存在IP地址信息,造成信息洩露。就Nginx模塊以及常用的第三方模塊本身來說,無法通過這個整數溢出來對內存進行操作或者遠程執行。

建議升級到1.13.3和1.12.1版本;如果不能升級,可以在Nginx配置文件中添加max_ranges 1,從而禁用multipart range。


分享到:


相關文章: