作者:phith0n@長亭科技
之前在Sec-News中推薦了一個開源程序,作用是來檢測 Nginx 配置文件中存在的問題。正好 Pwnhub 上周的比賽也出現了一道題,包含由 Nginx 配置錯誤導致的漏洞。
所以我挑選我覺得比較有趣,而且很有可能犯錯誤的三個典型案例,來說說 Nginx 配置文件的安全。
另外,本文所涉及的三個案例,均已上線到Vulhub,閱讀本文的同時可以自己動手測試。
$uri導致的CRLF注入漏洞
下面兩種情景十分常見:
用戶訪問http://example.com/aabbcc, 自動跳轉到 https://example.com/aabbcc
用戶訪問http://example.com/aabbcc, 自動跳轉到 http://www.example.com/aabbcc
比如我的博客,訪問 http://www.leavesongs.com/other/tinger.html ,將會301跳轉到 https://www.leavesongs.com/other/tinger.html 。隨著現在 https 的普及,很多站點都強制使用 https 訪問,這樣的跳轉非常常見。
第二個場景主要是為了統一用戶訪問的域名,更加有益于 SEO 優化。
在跳轉的過程中,我們需要保證用戶訪問的頁面不變,所以需要從 Nginx 獲取用戶請求的文件路徑。查看 Nginx 文檔,可以發現有三個表示 uri 的變量:
$uri$document_uri$request_uri
解釋一下,1和2表示的是解碼以后的請求路徑,不帶參數;3表示的是完整的URI(沒有解碼)。那么,如果運維配置了下列的代碼:
location / {
return 302 https://$host$uri;
}
因為$uri是解碼以后的請求路徑,所以可能就會包含換行符,也就造成了一個CRLF注入漏洞。(關于CRLF注入漏洞,可以參考我的老文章.
這個 CRLF 注入漏洞可以導致會話固定漏洞、設置 Cookie 引發的 CSRF 漏洞或者 XSS 漏洞。其中,我們通過注入兩個 \r\n 即可控制 HTTP 體進行 XSS,但因為瀏覽器認為這是一個300跳轉,所以并不會顯示我們注入的內容。
這個情況下,我們可以利用一些技巧:比如使用 CSP 頭來 iframe 的地址,這樣瀏覽器就不會跳轉,進而執行我們插入的 HTML :

關于上述利用方法,可以參考我的另一篇文章《Bottle HTTP 頭注入漏洞探究》。
如何修復這個 CRLF 漏洞?正確的做法應該是如下:
location / {
return 302 https://$host$request_uri;
}
另外,由$uri導致的 CRLF 注入漏洞不僅可能出現在上述兩個場景中,理論上,只要是可以設置 HTTP 頭的場景都會出現這個問題。
目錄穿越漏洞
這個常見于 Nginx 做反向代理的情況,動態的部分被 proxy_pass 傳遞給后端端口,而靜態文件需要 Nginx 來處理。
假設靜態文件存儲在 /home/ 目錄下,而該目錄在 url 中名字為 files ,那么就需要用 alias 設置目錄的別名:
location /files {
alias /home/;
}
此時,訪問http://example.com/files/readme.txt, 就可以獲取/home/readme.txt文件。
但我們注意到,url上/files沒有加后綴/,而alias設置的/home/是有后綴/的,這個/就導致我們可以從/home/目錄穿越到他的上層目錄:

進而我們獲得了一個任意文件下載漏洞。
這個有趣的漏洞出現在了 Pwnhub 上一期比賽《尋找 SNH48》中,@Ricter師傅的題目。
如何解決這個漏洞?只需要保證location和alias的值都有后綴/或都沒有這個后綴。
Http Header被覆蓋的問題
眾所周知,Nginx 的配置文件分為 Server、Location、If 等一些配置塊,并且存在包含關系,和編程語言比較類似。如果在外層配置的一些選項,是可以被繼承到內層的。
但這里的繼承也有一些特性,比如 add_header,子塊中配置后將會覆蓋父塊中的 add_header 添加的所有 HTTP 頭,造成一些安全隱患。
如下列代碼,Server 塊添加了 CSP 頭:
server {
...
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;
location = /test1 {
rewrite ^(.*)$ /xss.html break;
}
location = /test2 {
add_header X-Content-Type-Options nosniff;
rewrite ^(.*)$ /xss.html break;
}
}
但 /test2 的 location 中又添加了 X-Content-Type-Options 頭,導致父塊中的 add_header 全部失效:

此時,test2 的 csp 就完全失效了,我們成功觸發 XSS :

總結
Nginx配置文件造成的漏洞絕不止這三種,比如之前特別火的解析漏洞,也和 Nginx 的配置有一定關系。
解決這類漏洞,最根本的方法是仔細閱讀官方文檔,文檔里說明了很多配置文件錯誤和正確的用法。最忌去百度網上的一些解決方法,很多錯誤就是一傳十十傳百,最后流傳開來的。
另外,本文開頭提到的工具 gixy ,我們也可以利用起來,網站上線前進行一下掃描,也許就能發現一些可能存在的問題。
參考文章:
- http://blog.volema.com/nginx-insecurities.html
- https://github.com/phith0n/vulhub/tree/master/nginx/insecure-configuration
- https://hackerone.com/reports/25275
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/335/
暫無評論