文件上傳漏洞原理
在文件上傳的功能處,若服務端腳本語言未對上傳的文件進行嚴格驗證和過濾,導致惡意用戶上傳惡意的腳本文件時,就有可能獲取執行服務端命令的能力,這就是文件上傳漏洞。
文件上傳漏洞對Web應用來說是一種非常嚴重的漏洞。一般情況下,Web應用都會允許用戶上傳一些文件,如頭像、附件等信息,如果Web應用沒有對用戶上傳的文件進行有效的檢查過濾,那么惡意用戶就會上傳一句話木馬等Webshell,從而達到控制Web網站的目。
誘因:服務端腳本語言未對上傳的文件進行嚴格驗證和過濾
文件上傳漏洞原理圖解:
文件上傳漏洞高危觸發點
- 相冊、頭像上傳
- 視頻、照片分享
- 附件上傳(論壇發帖、郵箱)
- 文件管理器:編輯器
文件上傳漏洞分類
- 任意上傳
- JS驗證:能在可控制台能改
- MIME-type檢測
- 文件頭檢測
- 文件擴展名黑白名單檢測
- 文件加載檢測
文件上傳漏洞分類圖解
任意文件上傳:
沒有任何校驗
繞過JS上傳:
校驗發生在前端
繞過后端校驗上傳:
校驗發生在后端
繞過文件類型校驗
繞過擴展名校驗
繞過文件頭校驗
解析漏洞上傳:
中間件解析漏洞
其他類型
文件上傳漏洞成因
-
未過濾或Web前端過濾被繞過
-
文件檢測被繞過
-
中間件解析
-
不完善的黑名單擴展名
-
文件路徑截斷
-
HTTP不安全方法(PUT協議)
漏洞成因分析及案例
1、 未過濾或者web前端過濾被繞過
未過濾是沒有對文件上傳格式做限制,前端繞過是指當前頁面中js對上傳文件做限制,可通過HTTP抓包工具進行改包上傳。
這類相對好理解,前部分是可以任意上傳文件,后部分是因為只是前端限制,只用上傳可以上傳的文件,然后抓包對后綴進行修改就可以成功。
2、文件內容檢測被繞過
檢測CONTENT-TYPE內容(判斷是否為特定數據類型),檢測文件頭,檢測文件擴展功能相關內容。
(1) Content-Type繞過
這里看到讓我們上傳一個php文件,但是上傳后顯示[非圖片文件]
這里我使用burpsuite進行截包然后重放。
發現並沒用但是將Content-Type:改為 image/jpeg則成功上傳
可以看到這里只是對content-Type進行驗證,我們只需要修改成圖片的格式就上傳成功。
(2) 文件頭檢測繞過
//檢查是否圖片
if(function_exists('getimagesize')) {
$tmp_imagesize = @getimagesize($new_name);
list($tmp_width, $tmp_height, $tmp_type) = (array)$tmp_imagesize;
$tmp_size = $tmp_width * $tmp_height;
if($tmp_size > 16777216 || $tmp_size < 4 || empty($tmp_type) || strpos($tmp_imagesize['mime'], 'flash') > 0) {
@unlink($new_name);
return cplang('only_allows_upload_file_types');
}
}
這是php的一串檢查圖片代碼,使用getimagesize函數無法判斷其圖片是無效的
我們只需要再上傳的文件頭加入GIF89a 便可以欺騙服務器認為我們的文件是圖片。
這里舉幾個常見的文件頭對應關系:
(1) .JPEG;.JPE;.JPG,"JPGGraphic File"
(2) .gif,"GIF 89A"
(3) .zip,"Zip Compressed"
(4) .doc;.xls;.xlt;.ppt;.apr,"MS CompoundDocument v1 or Lotus Approach APRfile"
3、中間件解析
由於中間件本身的缺陷,再對上傳文件進行解析時會出現一些不可預料的錯誤從而導致被利用進行上傳繞過。
(1) IIS6.0解析漏洞
第一種,當建立*.asp、*.asa格式的文件夾時,其目錄下任意文件都會被iis當作asp文件來解析。
例如:創建xxx.asp目錄那么在xxx.asp目錄下如果存在1.txt文件會被當做1.asp文件來執行。
第二種,在IIS6.0下分號后的不被解析。
例如:xxx.asp;.jpg會被服務器看作為xxx.asp文件
(2) IIS7.0/7.5畸形解析漏洞
IIS7.0/7.5中:任意文件名/任意文件名.php就會被解析為php
(3) Apache解析漏洞
在Apache 1.x和Apache 2.x中存在解析漏洞。
Apache在解析文件時有一個原則,當碰到不認識的擴展名時,將會從后向前解析,直到碰到認識的擴展名為止,如果都不認識,則會暴露其源代碼。
如:1.php.rar.sa.xs就會被解析為php,可以據此來繞過文件名限制
(4) Nginx<8.03畸形解析漏洞
在默認Fast-CGI開啟的情況下上傳一個xxx.jpg,內容為<?php eval($POST[‘cmd’])?>的文件然后訪問xxx.jpg/.php在該目錄下就會生成一句話木馬文件xxx.php。
(5) PHP CGI解析漏洞
當php的配置文件中的選項cgi.fix_pathinfo= 1開啟時,當訪問http://www.example.com/xxx.txt/xxx.php時,若xxx.php不存在,則PHP會遞歸向前解析,將xxx.txt當作php腳本來解析
4、不完善的黑名單擴展名
因為程序員在開發文件上傳時加入了不允許上傳類型的黑名單,但是黑名單內容並不完善,這時候我們可以利用一些其他擴展名繞過黑名單限制,這里就不進行詳細的贅述了,這里列舉一些可用於繞過的文件名:
- PHP: php2、php3、php5、phtml、pht
- ASP: aspx、ascx、ashx、cer、asa
- JSP: jspx
5、文件路徑截斷
(1)php%00截斷
利用條件:php版本小於5.3.4,php的magic_quotes_gpc
為OFF狀態
詳情:CVE-2006-7243
(2)Nginx<8.03空字節代碼執行漏洞
影響版本:0.5,0.6,0.7<=0.7.65,0.8<=0.8.37
Nginx在圖片中嵌入PHP代碼然后訪問xxx.jpg%00.php來執行其中的代碼
(3)截斷后綴上傳
部分上傳功能在對后綴名進行驗證時存在缺陷,導致在文件寫入過程中產生錯誤,導致可通過十六進制截斷符(%00)對后綴進行截斷。
例如:
POST /Upload HTTP/1.1
Host: www.example.com
Proxy-Connection: keep-alive
Content-Length: 363
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5YpmA9D3wW207kB7
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
------WebKitFormBoundary5YpmA9D3wW207kB7
Content-Disposition: form-data; name="uploadfile"; filename="xxx.php%00.jpg"
Content-Type: image/jpg
<?php eval($POST[‘CMD’]);?>
------WebKitFormBoundary5YpmA9D3wW207kB7--
上傳處理時將對檢測到%00(這里需要對%00進行urldecode)並對.jpg字符串進行截斷刪除,最終文件名為xxx.php導致可成功上傳動態腳本到服務器上
6、HTTP不安全方法(PUT協議)
(1)WebDav漏洞
WebDav是一種基於HTTP1.1協議的通信協議,它擴展了HTTP協議。在開啟WebDav后若支持PUT、Move、Copy、Delete等方法,就會存在安全隱患。
測試流程:
首先提交options 請求看服務器是否支持此類方法
OPTIONS /HTTP/1.1
Host:www.example.com
通過PUT方法上傳腳本文件
PUT /xxx.txtHTTP/1.1
Host:www.example.com
Content-Length:30
1 <?php eval($POST[‘cmd’]); ?>
通過move或者copy方法移動文件
COPY /xxx.txtHTTP/1.1
Host:www.example.com
Destination:http://www.example.com/cmd.asp
(2)發布的tomcat漏洞
http://blog.csdn.net/u011499747/article/details/78108240
其他的上傳利用
1、結合文件包含
很多時候網站檢測的過於嚴格,我們只能上傳白名單的文件格式,這時我們可以嘗試去看看網站是否存在一些文件包含漏洞,結合我們上傳的文件進行聯合利用。
2、黑白名單共存
之前我遇到過這樣一個網站,就是黑白名單共存。該網站的架構是這樣的,在后台有個地方是可以設置上傳的白名單內容,在代碼層面又含有黑名單檢測。當時猜測他網站的判斷是這樣的:
if(正則匹配在白名單中==正則匹配不在黑名單中)
上傳成功
Else:
上傳失敗
於是我清空了白名單的內容,然后上傳了在黑名單中的文件格式於是,代碼false==false 上傳成功。
3、利用源代碼進行文件上傳
很多時候我們通過各種源碼泄露,例如:.svn、.git、網站備份、任意文件下載等等獲取到了網站的源碼,我們可以進行代碼審計尋找文件上傳的接口,我之前測試過的很多網站他們的代碼都有一個api接口用來處理上傳的文件,而黑白名單僅僅是進行了上傳檢測,我們可以在本地直接構造一個上傳頁面然后調用這個api接口直接上傳文件解析。
4、操作系統解析
由於windows會將文件的后綴中的空格以及點進行過濾,如果遇到是黑名單校驗的,如限制不允許上傳PHP文件,而系統又是windows系統,那么我們可以上傳xx.php ,或者xx.php.,通過這種方式就可以繞過黑名單檢驗的文件上傳!
5、htaccess文件解析
如果Apache中.htaccess可被執行並可被上傳,那么可以嘗試在.htaccess中寫入:
<FilesMatch"xxx.jpg"> SetHandler application/x-httpd-php </FilesMatch>
然后再上傳xxx.jpg的木馬,這樣xxx.jpg就可被解析為PHP文件了。
文件上傳的防御
- 客戶端檢測,使用 js 對上傳圖片檢測,包括文件大小、文件擴展名、文件類型等
- 服務端檢測,對文件大小、文件路徑、文件擴展名、文件類型、文件內容檢測、對文件重命名等
- 服務器端上傳目錄設置不可執行權限
- 檢查網站有沒有文件解析漏洞和文件包含漏洞
- 將文件上傳到單獨的文件服務器,並且單獨設置文件服務器的域名
總結
作為獲取shell最直接的方法,上傳地方檢測是最為嚴密的,我們需要想方設法的去嘗試各種思路才能繞過各種限制。隨着信息安全發展的不斷壯大,文件上傳也越來越難以被利用,但是在很多系統管理層后台是並沒有限制的,看上去越強壯的網站內部越脆弱不堪。我們需要細心挖掘每一個點並加以利用。比起基礎來說更多的是經驗,只有經驗不斷增加才會有更多的思路拓展。