CVE-2013-4547 Nginx解析漏洞深入利用及分析

Nginx歷史上曾出現過多次解析漏洞,比如80sec發現的解析漏洞,以及后綴名后直接添加%00截斷導致代碼執行的解析漏洞。

但是在2013年底,nginx再次爆出漏洞(CVE-2013-4547),此漏洞可導致目錄跨越及代碼執行,其影響版本為:nginx 0.8.41 1.5.6,范圍較廣。

為了更深入的了解漏洞產生的原因,筆者根據官方補丁(http://nginx.org/download/patch.2013.space.txt),對此漏洞進行了進一步的分析,

一、漏洞朔源

1.從官方補丁可以看出nginxngx_http_parse_request_line函數處做了代碼patch,下載nginx源代碼,定位其補丁文件為ngx_http_parse.c,函數ngx_http_parse_request_line中,分別位于代碼段:

由此可定位本次漏洞需要分析的點,啟用gdb調試,將break點設置為ngx_http_parse_request_line

并且watch變量statep,因為此函數為狀態機,state為狀態值,p為指針所指地址,這將是漏洞觸發的關鍵點。

調試過程中需要跟蹤nginxworker子進程,所以需要設置setfollow-fork-mode child,并且在相應的地方設置斷點,

-1 跟進子進程

2.分別發送正常和攻擊語句進行測試:

正常語句:http://127.0.0.1/a.jpg

攻擊語句:http://127.0.0.1/a.jpg(非編碼空格)\0.php

使用正常語句一直sn跟蹤,會發現在對url的解析過程中,當路徑中存在’.’url存在’\0’會有如下處理:

但是在檢查uri中有空格則會進入到sw_check_uri_http_09的邏輯中,那么當我們發送攻擊代碼的時候,執行流程將如下:

-2 \0未觸發異常

再回到sw_check_uri狀態,此時后面的字符串為.php,而“.”將被為是uri的擴展名的分隔符

-3 取后綴名錯誤

最終導致nginx認為此次請求的后綴名為php,通過配置,會傳給fastcgi進行處理,而fastcgi在查找文件的時候被\0截斷,最終取到”a.jpg(非編碼空格)”文件(注:Linuxphp-fpm默認限制的后綴名為php,如未取消限制,訪問將出現access denied。測試想要查看執行結果,需修改php-fpm.conf中的security.limit_extensions為空,即允許任意后綴名文件作為php解析。)

跨越location /protected / {deny all;}的規則的原理與此類似,均為狀態機中判斷出現混亂,從導致而可以跨越到protected目錄中,訪問默認不可訪問到的文件。

由此可知,常規利用中如果想觸發代碼執行,條件為可上傳帶空格的文件到服務器,并且服務器存儲的時候也需要保留空格,而大多數情況下,web應用在處理上傳文件時,都會將文件重命名,通過應用自身添加后綴,或者對后綴名去掉特殊字符后,做類型判斷。

???????? 以上因素都導致此漏洞被認為是雞肋漏洞,難以利用,而被人們所忽略。

二、windows下的RCE

????此問題在windows的攻擊場景中,則從小汽車變身為變形金剛。

????首先,我們了解一下windows讀取文件時的特點,即文件系統api創建文件名或查找文件名時,默認會去掉文件名后的空格,再執行操作,參見示例代碼,目錄下放置a.txt不帶空格:

通過此代碼可知道,即使我們傳入參數是”a.txt ”帶空格,最后訪問到卻確是”a.txt”不帶空格

此時的攻擊過程為:

1.上傳任意文件(不需要帶空格文件),

2.http://127.0.0.1/a.jpg(非編碼空格)\0.php

-4文件a.jpg

-5漏洞利用

成功將a.jpg文件當作php代碼執行,達到了攻擊成功的目的。

通過windows的此特性,使CVE-2013-4547windows+nginx的環境中的危害無限擴大,即在windows下,只要普通用戶能上傳文件,則可利用本次漏洞,導致代碼執行,并進一步入侵服務器。

并且在普通站長中使用windows做為操作系統的數量甚廣,CVE-2013-4547windows的場景下將進行華麗的變身。

[via@百度安全中心]