檔案上傳漏洞全面滲透姿勢總結

wolfshadow發表於2021-03-18

檔案上傳漏洞全面滲透姿勢總結

0x00 檔案上傳場景

(本文件只做技術交流,切勿進行違法犯罪操作,請做一個好人,不給別人添麻煩)

檔案上傳的場景真的隨處可見,不加防範小心,容易造成漏洞,造成資訊洩露,甚至更為嚴重的災難。

比如某部落格網站評論編輯模組,右上角就有支援上傳圖片的功能,提交帶有惡意字串的圖片後,就直接可以顯示在評論中了,如圖:

 

再次宣告:大家在自己的搭建的環境裡面測試,不要給別人造成麻煩哈。

檔案上傳漏洞是進行滲透是比較常見好利用的漏洞,利用它能夠直接上傳webshell,進行連線,是比較常見的攻擊方式。針對檔案上傳場景檢測和繞過進行了全面姿勢總結。

0x01 滲透姿勢全面分析

針對一個檔案上傳場景,首先判斷是客戶端JS校驗還是伺服器校驗,判斷依據:上傳非法檔案,返回結果是否很快?

1.客戶端JavaScript檢測

如果上傳非法檔案,返回結果很快,或者F12開啟開發者模式,上傳非法檔案,發現沒有網路請求,但是被攔截了,很有可能就是客戶端進行了JS校驗檢測。這種前端採用JS限制上傳型別和大小的方式:

<script type="text/javascript">
    function checkFile() {
        var file = document.getElementsByName('upload_file')[0].value;
        if (file == null || file == "") {
            alert("請選擇要上傳的檔案!");
            return false;
        }
        //定義允許上傳的檔案型別
        var allow_ext = ".jpg|.png|.gif";
        //提取上傳檔案的型別
        var ext_name = file.substring(file.lastIndexOf("."));
        //判斷上傳檔案型別是否允許上傳
        if (allow_ext.indexOf(ext_name) == -1) {
            var errMsg = "該檔案不允許上傳,請上傳" + allow_ext + "型別的檔案,當前檔案型別為:" + ext_name;
            alert(errMsg);
            return false;
        }
    }
</script>

很是雞肋,繞過思路:1.直接本地禁用JS,不讓其做檢測  2.抓包,修改檔案字尾名型別,繞過檢測限制

2.伺服器後端檢測

伺服器後端檢測有較多方式,普遍分為檔案型別檢測,檔案頭型別,副檔名名單檢測,檔案內容檢測,接下來進行簡要分析。

a.檔案型別檢測

此類檢測防護主要是從content-type進行檢測,檢驗請求中content-type是否符合可接受的上傳型別(如"image/gif","image/png","image/jpeg") 

if (isset($_POST['submit'])) {

if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];          
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;     

繞過思路:抓包將content-type改為可接受圖片形式,即可繞過

b.檔案頭型別檢測 

上個檔案型別是檢測content-type,比較好偽造,這個則是使用getimagesize()函式來獲取檔案的MIME型別,通過檔案頭進行判斷檔案型別

 if(file_exists($filename)){
        $info = getimagesize($filename);

檔案頭就是檔案特定的標誌,如二進位制PE檔案的4D5A,bmp檔案的424D,zip檔案的504B0304,各種常見檔案的檔案頭型別大家可以查詢了解一下,常見圖片檔案頭如下:

gif: GIF89a

jpg,jpeg: FF D8 FF

png: 89 50 4E 47 0D 0A

繞過思路:針對這種,上傳木馬惡意檔案時,先使用編輯工具在資料最前面新增圖片的檔案頭進行偽造,即可繞過

c.副檔名檢測

這種型別有基於黑名單檢測和白名單檢測。通常基於黑名單是很不安全的,黑名單機制:只攔截名單中出現的擴充套件字尾名,其餘預設放行。這就取決於名單中的擴充套件字尾名覆蓋能力範圍了,很難把所有的考慮全面,就很容易造成漏洞。

黑名單繞過思路:可以從伺服器的解析特性進行分析,如特殊可解析字尾php3,php7,phtml,jspx等 如特殊的解析方式陌生字尾名,帶換行字尾名,雙字尾名等解析差異造成的漏洞。 還可以從混淆方面出發,字尾名大小寫,點繞過,空格繞過,以及上傳.htaccess配置控制檔案許可權和::$DATA資料流的使用

基於白名單相對於黑名單就安全很多了,要求只能是特定副檔名的檔案才能夠上傳。

白名單繞過思路:MIME繞過,修改檔案型別為白名單可接受的型別,以及%00,0x00截斷繞過,這種場景針對save_path可控。

00截斷原理其實很巧妙,利用場景是檔案儲存路徑可控,這樣一來我們上傳的檔案符合白名單就行,真正動手的地方在檔案儲存路徑出,可以放上自己的webshell檔案,然後在webshell檔案後面新增%00,或0x00,再加一些字元,這樣一來,系統在解析碰到00就會截斷,後面字元就不起作用,只剩下前面的webshell檔名,就可以在url中進行訪問了。%00和0x00的使用區別在於提交get請求時,是%00,會進行url自動解碼動作,然後進入驗證函式。0x00則是post請求直接進入驗證函式。

d.檔案內容檢測

比較厲害的防護檢測,就是針對內容做檢測,這種防護能力比較強,但也不是不能繞過。自始至終,攻防都是在對抗中螺旋演進的。

這種檢測防護基本都是從webshell具有的代表性敏感字元?或者危險敏感函式。

繞過思路:從特殊敏感字元開始進行Fuzz測試,探測webshell中有多少必要的字元存在被替換,如果構成webshell執行的字元

被替換得較多,剩下未過濾的字元的難以支撐webshell執行,可以換個角度利用系統,呼叫指令碼語言,如<script language='php'>system('ls');<script>。

還有一種更強的基於內容檢測機制,對上傳的圖片進行二次渲染,參考程式碼如下

//判斷檔案字尾與型別,合法才進行上傳操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "該檔案不是jpg格式的圖片!";
                @unlink($target_path);
            }else{
                //給新圖片指定檔名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //顯示二次渲染後的圖片(使用使用者上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上傳出錯!";
        }

主要就是後端呼叫了php的GD庫,利用imagecreatefromjpeg()函式提取了檔案中的圖片資料,然後再重新渲染,這樣圖片中插入的惡意程式碼就會被過濾掉了,經過測試發現,不管是直接修改檔案頭製作圖片馬,還是利用copy命令製作的圖片馬,都無法避免其中的一句話被過濾掉。

繞過思路:借鑑二進位制中鉤子的思想,其實就是想在上傳圖片中找一塊"地方",儲存webshell,這塊"地方"要求在後端處理後沒有被過濾掉。那就上傳一個正常的檔案,然後下載下來,diff一下,檢視哪些位置沒有被改動過,然後新增webshell進行嘗試。

0x02 安全小思考

以上防護和繞過姿勢基本上都是從業務實戰和CTF比賽中總結而來的,更多的時候需要各種資訊進行綜合利用,安全中攻擊和防範永遠是在對抗中相互成就的。敬畏前輩先驗知識,展露後輩探索精神。

相關文章