上傳驗證繞過全解析


目錄

0x01  客戶端驗證繞過(javascript 擴展名檢測)
0x02  服務端驗證繞過(http request 包檢測)

  • - Content-type (Mime type)  檢測

0x03  服務端驗證繞過(擴展名檢測)

  • - 黑名單檢測
  • - 白名單檢測
  • - .htaccess 文件攻擊

0x04  服務端驗證繞過(文件完整性檢測)

  • - 文件頭檢測
  • - 圖像大小及相關信息檢測
  • - 文件加載檢測

0x05  各種情況下的檢測繞過分析
0x06  關於圖像代碼注入后的解析簡答

前言
在現在越來越安全的體系下,SQL Injection 這類漏洞已經很難在安全性很高地站點出現,比 如一些不錯的.NET 或 JAVA 的框架基本上都是參數化傳遞用戶輸入,直接封死注入攻擊。 而在非 php 的 web 安全中最有威力的攻擊主要有兩種,第一種是 SQL Injection,第二種便 是上傳繞過漏洞。(php 的還有遠程文件包含或代碼注入漏洞)

一般只要能注冊普通用戶,時常都能找到上傳頭像或附件之類的地方,這些地方就是好的突 破點,只要有辦法繞過上傳驗證,並找到一句話木馬的 web 路徑基本上就能搞下這個站點。

這篇 paper 並不完善,但在分類框架上還是比較全面,因為個人經驗有限,所以所能覆蓋的 情況並不全面,也有很多地方還沒機會實踐並貼圖出來,希望大家有類似經驗的提出來,以 便我能完善這篇 paper,也讓大家的交流產生更大的價值。

0x01  客戶端驗證繞過(javascript 擴展名檢測)

打開 http 反向代理工具 burp
先隨便點擊上傳一個 2012.asa



然后還沒點 Upload
burp 里也還沒出現任何內容 便彈出了一個警告框 一看就知道是個客戶端驗證 javascript
只需要把它禁掉或者通過 burp 進行代理修改


這里我用 burp 進行代理修改 先將文件擴展名改成 jpg

然后 Upload
現在的文件名是 2012.jpg

在 burp 里將 jpg 改成 asp

 
然后繼續上傳
最后可以看到 asp 成功上傳

 
0x02  服務端驗證繞過(http request 包檢測)

Content-type (Mime-type)檢測

假如服務端上的 upload.php 代碼如下

 1 <?php
 2 if($_FILES['userfile']['type'] != "image/gif") { //檢測Content-type
 3 echo "Sorry, we only allow uploading GIF images";
 4 exit;
 5 }
 6 $uploaddir = 'uploads/';
 7 $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
 8 if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
 9 echo "File is valid, and was successfully uploaded.\n";
10 } else {
11 echo "File uploading failed.\n";
12 }
13 ?>

然后我們可以將 request 包的 Content-Type 修改 POST /upload.php HTTP/1.1

TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY Content-Length: 155
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="shell.php" Content-Type: image/gif (原為 Content-Type: text/plain)

  
  
  
          
--xYzZY--
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 14:02:11 GMT Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 59
Connection: close
Content-Type: text/html
File is valid, and was successfully uploaded.

像這種服務端檢測 HTTP 包的 Content-Type 都可以用這種類似的方法來繞過檢測

0x03  服務端驗證繞過(擴展名檢測)
黑名單檢測

黑名單的安全性其實還沒白名單的安全性高,至少攻擊它的方式比白名單多多了
一般有個專門的 blacklist 文件,里面會包含常見的危險腳本文件 例如 fckeditor 2.4.3 或之前版本的黑名單

 

1. 找黑名單擴展名的漏網之魚 - 比如上面就漏掉了asa和cer之類

2. 可能存在大小寫繞過漏洞 - 比如 aSp 和 pHp 之類

3. 特別文件名構造 -  比如發送的http包里把文件名改成 help.asp. 或 help.asp_(下划線為空格),這種命名方式在 windows 系統里是不被允許的,所以需要在 burp 之類里進行修改,然 后繞過驗證后,會被 windows 系統自動去掉后面的點和空格。

4. IIS 或 nginx 文件名解析漏洞 -  比如 help.asp;.jpg 或http://www.xx.com/help.jpg/2.php
這里注意網上所謂的 nginx 文件名解析漏洞實際上是 php-fpm 文件名解析漏洞 詳見 http://www.cnbeta.com/articles/111752.htm

5. 0x00 截斷繞過 -  這個是基於一個組合邏輯漏洞造成的
給個簡單的偽代碼
name = getname(http request) //假如這時候獲取到的文件名是 help.asp .jpg(asp 后面為 0x00)
type = gettype(name) //而在 gettype()函數里處理方式是從后往前掃描擴展名,所以判斷為 jpg if (type == jpg)
SaveFileToPath(UploadPath.name, name) //但在這里卻是以 0x00 作為文件名截斷
//最后以 help.asp 存入路徑里

6. 雙擴展名解析繞過攻擊(1) -  基於 web 服務的解析邏輯 比如在 Apache manual 中有這樣一段描述
“Files can have more than one extension, and the order of the extensions is normally irrelevant. For  example, if the file welcome.html.fr maps onto content type text/html and language French then the  file  welcome.fr.html  will  map  onto exactly  the  same  information.  If more  than one extension is given which maps onto the same type of meta-information, then the one to the right will  be  used,  except for languages  and content  encodings.  For example, if  .gif  maps to the MIME-type image/gif and .html maps to the MIME-type text/html, then the file welcome.gif.html will be associated with the MIME-type text/html.”

如果上傳一個文件名為 help.asp.123
首先擴展名123並沒有在擴展名 blacklist 里,然后擴展名 123 也沒在 Apache 可解析擴展名
list 里,這個時候它會向前搜尋下一個可解析擴展名,或搜尋到.php,最后會以 php 執行
7. 雙擴展名解析繞過攻擊(2) -  基於web服務的解析方式 如果在Apache的 conf 里有這樣一行配置
AddHandler php5-script .php
這時只要文件名里包含.php
即使文件名是 test2.php.jpg 也會以 php 來執行

8. 危險解析繞過攻擊 - 基於 web 服務的解析方式 如果在Apache的conf里有這樣一行配置
AddType application/x-httpd-php .jpg
即使擴展名是 jpg,一樣能以 php 方式執行


白名單檢測

白名單相對來說比黑名單安全一些,但也不見得就絕對安全了

1. 特別文件名構造 (同黑名單攻擊第 3 條)
2. IIS或nginx文件名解析漏洞 (同黑名單攻擊第 4 條)
3. 0x00 截斷繞過 (同黑名單攻擊第 5 條)

.htaccess 文件攻擊

無論是黑名單還是白名單 再直接點就是直接攻擊.htaccess 文件 在 PHP manual 中提到了下面一段話
move_uploaded_file section, there is a warning which states
‘If the destination file already exists, it will be overwritten.’ 如果 PHP 安全沒配置好
就可以通過 move_uploaded_file 函數把自己寫的.htaccess 文件覆蓋掉服務上的
這樣就能任意定義解析名單了
0x04  服務端驗證繞過(文件完整性檢測)

文件頭檢測

主要是在文件內容開始設置好圖片文件的幻數

要繞過 jpg 文件檢測就要在文件開頭寫上下圖的值

 

要繞過 gif 文件檢測就要在文件開頭寫上下圖的值

要繞過 png 文件檢測就要在文件開頭寫上下面的值

然后在文件頭后面加上自己的一句話木馬就行了

圖像大小及相關信息檢測

常用的就是 getimagesize()函數
只需要把文件頭部分偽造好就 ok 了,就是在幻數的基礎上還加了一些文件信息
有點像下面的結構
GIF89a(...some binary data...)<?php phpinfo(); ?>(... skipping the rest of binary data ...)
文件加載檢測

這個是最變態的檢測了,一般是調用的 API 或函數去進行文件加載測試常見的是圖像渲染測試,再變態點的甚至是進行二次渲染(后面會提到) 對它的攻擊一般就兩種方式,一個是渲染測試繞過,另一個是攻擊文件加載器自身

渲染測試繞過
先用 GIMP 對一張圖片進行代碼注入
用 winhex 看數據可以分析出這類工具的原理是 在不破壞文件本身的渲染情況下找一個空白區進行填充代碼 一般是圖片的注釋區
對於渲染測試基本上都能繞過

 
但如果碰到變態的二次渲染 基本上就沒法繞過了,估計就只能對文件加載器進行攻擊了
比如上傳文件前,文件的數據如下

然后上傳這個 jpg 但把它重新下載回本地發現了奇怪的地方

 

上傳后圖片被二次渲染過
新的 JPG 圖片內容里含有這個
CREATOR: gd-jpeg v1.0 (using IJG JPEG v62)
貌似是調用的 GD php 的 gd 庫
測試了 gif 文件也一樣
原文件內容是(雖然文件名是 2.jpg,實際文件格式是 gif 哈)

上傳后下載回來對比 可以發現文件被重新渲染過 一句話代碼也不見了

 
然后是進行報錯觸發 看下是被用什么 API 或函數進行的二次渲染

上傳文件數據不完整的 gif 文件 觸發報錯后,知道后台用的是 imagecreatefromgif()這個函數


上傳文件數據不完整的 png 文件 觸發報錯后,知道后台用的是 imagecreatefrompng()這個函數


一般進行過二次渲染 再想繞過個人經驗是幾乎不可能了 它相當於是把原本屬於圖像數據的部分抓了出來,再用自己的 API 或函數進行重新渲染 在這個過程中非圖像數據的部分直接就隔離開了

如果要對文件加載器進行攻擊,常見的就是溢出攻擊, 上傳自己的惡意文件后,服務上的文件加載器進行加載測試時,被觸發攻擊執行 shellcode 比如 access/mdb 溢出
大家可以參考下 http://lcx.cc/?FoxNews=1542.html
0x05  各種情況下的檢測繞過分析

A 客戶端端驗證繞過(javascript 擴展名檢測)
用反向代理工具(burp 之類)或禁用 js 便可以繞過客戶端端驗證

B 服務端驗證繞過(http request 包檢測)
- Content-type (Mime type)  檢測 用反向代理工具(burp 之類)進行 Content-type 偽造

C 服務端驗證繞過(擴展名檢測)
- 黑名單檢測

  • 找黑名單擴展名的漏網之魚 - 比如上面就漏掉了 asa 和 cer 之類 可能存在大小寫繞過漏洞 -  比如 aSp 和 pHp 之類
  • 特別文件名構造 - 比如發送的 http 包里把文件名改成 help.asp. 或 help.asp_(下划線為空格)
  • IIS或nginx文件名解析漏洞 - 比如 help.asp;.jpg 或 http://www.xx.com/help.jpg/2.php
  • 0x00 截斷繞過 - 這個是基於一個組合邏輯漏洞造成的 雙擴展名解析繞過攻擊(1) - 基於 web 服務的解析邏輯
  • 雙擴展名解析繞過攻擊(2) - 基於 web 服務的解析方式 危險解析繞過攻擊 - 基於 web 服務的解析方式

- 白名單檢測

  • 特別文件名構造 (同黑名單攻擊第 3 條)
  • IIS 或 nginx 文件名解析漏洞 (同黑名單攻擊第 4 條)
  • 0x00 截斷繞過 (同黑名單攻擊第 5 條)

- .htaccess 文件攻擊
在 PHP 安全沒配置好的情況下,用自己的.htaccess 覆蓋服務上原文件

D 服務端驗證繞過(文件完整性檢測)

  • - 文件頭檢測 在文件開始偽裝文件的幻數
  • - 圖像分辨率檢測
  • 在文件開始偽裝圖像大小數據
  • - 文件加載檢測 用工具對文件空白數據區或注釋區進行代碼注入繞過 (圖像僅能繞過渲染測試,而不能繞過二次渲染) 用惡意文件去攻擊加載器本身

E 相互關系與組合情況

首先客戶端端驗證和服務端驗證是相互獨立的,所以分開繞過就行了 主要難點是在服務端驗證的組合上 文件完整性檢測已經包含文件頭檢測和圖像大小及相關信息檢測,但不包含文件擴展名檢測 它是以加載來作為檢測的方式,比如用圖像渲染函數去渲染一張圖片 文件擴展名檢測和文件頭檢測都是同級的,相互獨立 所以如果是文件擴展名+文件頭檢測可以同時分開繞過
0x06  關於圖像代碼注入后的解析簡答

我在自己本機搭環境測試過 環境為 Apache+PHP 發現其無法解析圖像中的一句話

可能很多人都遇到過這類情況 並不真正清楚把代碼注入圖片之類后,怎么訪問才能連接上一句話 這里就來解釋下原理
其實就算對圖片進行代碼注入后,還需要調用對應的解析器來解析才能讓代碼得以解析執行 好比你把一個 exe 擴展改成 jpg,在桌面上打開,圖像查看器會報錯,說無法打開該文件
而你在 cmdshell 下,無論這個 exe 擴展名是什么,哪怕是 jpg,也能執行 因為只要調用到了正確的文件加載器或解析器,它是以文件頭幻數來判斷文件格式的,而不 是文件擴展名,所以我們如果只是簡單把圖片代碼注入后,上傳訪問,這個時候,還並不能
解析里面的一句話代碼
大家可以參考下:http://www.2cto.com/Article/201106/93084.html

常見的是結合 LocalFileInclude 漏洞來解析我們的圖片
(RemoteFileInclude 和 RemoteCodeExecution 在這里就有點大才小用了哈)

比如某個站有這樣一個 URL
www.2cto.com /view.php?page=contact.php

我們替換 contact.php 為../
www.2cto.com /view.php?page=../

得到一個報錯
Warning:  include(../)  [function.include]:  failed  to  open  stream:  No  such  file  or  directory  in
/home/sirgod/public_html/2cto.com /view.php on line 1337

就說明存在 LFI 漏洞,這個時候找到我們的圖片文件路徑
用一句話 client 去連接 www.2cto.com /view.php?page=../upload/help.jpg
就可以成功的得到 shell 了
還有像 nginx(php-fpm)解析漏洞,也可以直接解析圖片里的代碼 所以大家要了解哪些環境下才能對圖片里的代碼進行解析
這樣才能結合上傳繞過最后得到 webshell :)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM