1. 程式人生 > 其它 >upload-labs pass-5-利用系統特性繞過

upload-labs pass-5-利用系統特性繞過

Windows利用系統本身的命名規則繞過:

先看一下利用Windows特性繞過

  1. 大小寫繞過:針對對大小寫不敏感的系統如 windows 例如test.PhP

  2. 以下為不符合規則的Windows檔案

shell.php. 檔名後加 '.' 適用於上傳的檔名沒有被修改
shell.php空格 檔名後加空格
shell.php.空格. 檔名+'.'+空格+'.' 適用於上傳的檔名沒有被修改
shell.php:1.jpg 檔名後加冒號 適用於上傳的檔名沒有被修改
shell.php::$DATA 檔名加NTFS ADS特性::$DATA
shell.php::$DATA...... 檔名::$DATA.....

均會被windows系統自動去掉不符合規則符號後面的內容

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

上傳的檔名 伺服器表面現象 生成的檔案內容
test.php:a.jpg 生成test.php
test.php::$DATA 生成test.php
test.php::$INDEX_ALLOCATION 生成test.php資料夾
test.php::$DATA.jpg 生成0.jpg
test.php::$DATA\aaa.jpg 生成aaa.jpg

在php環境下可以上傳test.php::$DATA

參考:NTFS ADS的前世今生

Linux也可利用系統本身的命名規則繞過

linux命名規則

1、檔名最大長度為255

2、全路徑長度最大為4096(16級最大檔案長度)

3、區分大小寫

4、除“/”之外所有字元都可以使用

5、linux不以副檔名區分檔案型別,對linux來說一切皆檔案。

原始碼分析

$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",".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 = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除檔名末尾的點
        $file_ext = strrchr($file_name, '.');
        $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.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯!';
            }
        } else {
            $msg = '此檔案型別不允許上傳!';
        }
    } else {
        $msg = UPLOAD_PATH . '資料夾不存在,請手工建立!';
    }
}
  1. 首先 trim( )函式 移除字串兩側的空白字元

    • 假設上傳test.php+空格,這時伺服器獲取到的字尾是.php+空格,該檔案不再黑名單中,因此上傳功。
    • 由於windows檔案系統的特性,會去除後面的空格,導致test.php+空格=test.php
  2. deldot( ) 刪除檔名末尾的點

    • 假設上傳test.php.這時伺服器獲取到的字尾是,不在黑名單中,因此檔案上傳成功
    • 但是由於windows檔案系統的特性導致test.php.=test.php
  3. strchr( $file_name,' . ')函式 是搜尋.在檔名中的位置,並返回從該位置(包括此位置)到字串結尾的所有字元

    • 從頭開始,找到第一個滿足的就開始擷取

  4. strrchr( $file_name,' . ')函式 函式和3中的strchr不同,看看下面的圖體會一下,原始碼用的此函式

  5. str_ireplace('::$DATA', '', $file_ext)將::$DATA去掉

  6. 使用 trim($file_ext) 移除字串兩側的空白字元

  7. 禁止上傳如下字尾檔案

  1. 檔案重新命名文年月日星期+1000~9000+字尾名
  2. 上傳成功

上傳

分析上面的原始碼後,思路逐漸清晰,前兩步尾部去點,去空格,第五步去::$DATA,對於windows來說算致命打擊,但是轉換沒轉換大小寫,可以用test.PHp繞過windows系統

利用linux的特性,建立一個類似檔案如test.\php可以繞過linux系統

上傳一個test.\php,看到上傳的字尾名沒了,所以上傳的不是linux系統,而是windows系統

因此利用windows不區分大小寫特性來繞過

上傳1.PHp

連線成功