1. 程式人生 > 其它 >upload-labs通關日記

upload-labs通關日記

Pass-01 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;

}

}

原始碼分析:

在這裡我們的原始碼可以看到,這個是個很簡單的前端JavaScript驗證原始碼,前端定義了一個函式先對檔案是否為空進行判斷,上傳檔案後對齊的檔案格式做了個白名單,然後在白名單裡面查詢,白名單不存在的不能上傳,很簡單,這裡沒有在後臺進行操作,僅僅只是前端進行了判斷,我們在這裡直接禁用此頁面的JavaScript,從而能夠繞過檢測。這裡推薦個chrome外掛,toggle JavaScript,能夠直接進行禁止該介面的JavaScript程式碼。

具體操作:



筆者這裡只會在這裡提及相關上傳操作,後面基本以文字進行敘述

Pass-02 MIME繞過

$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.'資料夾不存在,請手工建立!';

}

}

原始碼分析:

在這裡我們可以看到他對檔案型別進行了判斷,而判斷標準都是看這個檔案是不是jpg、jpeg、png、gif檔案,沒有進行黑白名單設定,僅僅只是使用php函式進行判斷,只要是這個判斷標準中的檔案型別都會上傳,而沒有做後續操作,這裡我們就可以想,我們是不是可以直接使用BP進行抓包,然後偽造檔案型別就行了?當然是可行的了。

開啟代理

上傳成功

Pass-03 黑名單驗證

$is_upload = false;

$msg = null;

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

if (file_exists(UPLOAD_PATH)) {

    $deny_ext = array('.asp','.aspx','.php','.jsp');

    $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.'/'.date("YmdHis").rand(1000,9999).$file_ext;            

        if (move_uploaded_file($temp_file,$img_path)) {

             $is_upload = true;

        } else {

            $msg = '上傳出錯!';

        }

    } else {

        $msg = '不允許上傳.asp,.aspx,.php,.jsp字尾檔案!';

    }

} else {

    $msg = UPLOAD_PATH . '資料夾不存在,請手工建立!';

}

}

原始碼分析:

這裡我們可以看到,原始碼中有個deny_ext拒絕的陣列,表示在這裡我們設定了一個黑名單,然後利用了trim、deldot、strtolow,str_ireplace,分別去掉了兩個空格,刪除字尾名的點,大小寫等等,這就意味著我們不能通過點繞,空格繞過等操作(這些方式我們後面會提及),從後面的 if(!in_array($file_ext,$deny_ext)){ ……… }這行程式碼中是說,檔名不在黑名單中,然後就能上傳,那麼我們就去構造一個不是黑名單中的檔名字尾比如php5,php3等方式

Pass-04 .htaccess繞過

$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.'/'.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 . '資料夾不存在,請手工建立!';

}

}

原始碼分析:

這裡的黑名單更為詳細,黑名單中包含了所有的可執行指令碼語言的字尾名,包括字尾名變異,這裡我們可以知道,想通過指令碼語言來執行webshell是很難的了,但是還是有繞過思路的,這個時候我們就按照他的規矩來,我們上傳一個圖片,但是在上傳圖片時,我們先上傳一個.htaccess檔案,這是php中的一個配置檔案,該檔案中寫入程式碼

<FilesMatch "123.jpg">

SetHandler application/x-httpd-php

這個程式碼的意思是,匹配到123.jpg這個檔案的話,這個檔案使用php的方式執行該檔案,然後使用notepad++在圖片後面寫入木馬,上傳123.jpg

Pass-05 大小寫繞過

$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 . '資料夾不存在,請手工建立!';

}

}

原始碼分析:

我們在這裡看到,黑名單多了.htaccess檔案,這就意味之,第四關的方法不可行了,怎麼辦?不好繞啊,但是有沒有發現,我們之前審計的程式碼都有哪些對檔案字尾的處理

1、 trim 刪除檔名兩側的空格

2、 deldot刪除檔名後面的點 ‘ . ’

3、 strtolower 檔名轉換為小寫

4、 strchr($file_name,’.’) 返回字尾名

5、 str_ireplace(‘::$DATA’,‘ ’,$file_ext)把檔案字尾中的::$DATA轉換成空字串

但是我們這裡仔細發現,他沒有strtolower這個函式,那我們在這裡就可以通過構造大小寫來進行繞過了

Pass-06 空格繞過

$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 = $_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

    

    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 刪除檔名兩側的空格

2、 deldot刪除檔名後面的點 ‘ . ’

3、 strtolower 檔名轉換為小寫

4、 strchr($file_name,’.’) 返回字尾名

5、 str_ireplace(‘::$DATA’,‘ ’,$file_ext)把檔案字尾中的::$DATA轉換成空字串

這裡沒有對檔名後面去掉空格,那麼我們可以通過構造空格來繞過

Pass-07 點繞過

$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_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 . '資料夾不存在,請手工建立!';

}

}

原始碼分析:

和第五關一樣我們之前審計的程式碼都有哪些對檔案字尾的處理

1、 trim 刪除檔名兩側的空格

2、 deldot刪除檔名後面的點 ‘ . ’

3、 strtolower 檔名轉換為小寫

4、 strchr($file_name,’.’) 返回字尾名

5、 str_ireplace(‘::$DATA’,‘ ’,$file_ext)把檔案字尾中的::$DATA轉換成空字串

這裡我們進行程式碼審計時,沒有對點號 . 進行過濾,要知道我們的檔案在儲存計算機上時,你在檔案後面新增一個點號,計算機會把點號自動給你刪除的,這樣我們可以利用這樣的機制來上傳木馬

Pass-08 ::$DATA繞過

$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 = strtolower($file_ext); //轉換為小寫

    $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 刪除檔名兩側的空格

2、 deldot刪除檔名後面的點 ‘ . ’

3、 strtolower 檔名轉換為小寫

4、 strchr($file_name,’.’) 返回字尾名

5、 str_ireplace(‘::$DATA’,‘ ’,$file_ext)把檔案字尾中的::$DATA轉換成空字串

我們這裡發現,這裡沒有對 ::$DATA進行過濾,那麼我們可以使用這個來進行繞過

Pass-09 . .繞過(點+空格+點)

$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 = 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 . '資料夾不存在,請手工建立!';

}

}

原始碼分析:

首先需要了解deldot函式,當deldot函式檢測到末尾的第一個點時將繼續從後向前檢測,當檢測到空格時就停下來,因此當字尾是php.[空格].時,經過deldot函式過濾後,字尾變成php.[空格],最終繞過黑名單,且上傳上去的檔名為php.,在windows下會自動去除點。

Pass-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 . '資料夾不存在,請手工建立!';

}

}

原始碼分析:

首先我們審計原始碼,這裡少了很多我們之前遇到的對檔名過濾的措施,這裡我們可以使用之前5-9關的方法來繞過,但是,有沒有發現,這裡出現了一個很粗暴的處理方式,就是匹配到黑名單裡面的字串,就把他替換成空字串,那我們這裡還能採取雙寫的方式來繞過,就比如,他會把php替換為空字串,那麼我這麼構造字尾pphphp,那麼被替換成空字串後,仍然還是php的字尾

Pass-11 %00白名單截斷

$is_upload = false;

$msg = null;

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

$ext_arr = array('jpg','png','gif');

$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);

if(in_array($file_ext,$ext_arr)){

    $temp_file = $_FILES['upload_file']['tmp_name'];

    $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;



    if(move_uploaded_file($temp_file,$img_path)){

        $is_upload = true;

    } else {

        $msg = '上傳出錯!';

    }

} else{

    $msg = "只允許上傳.jpg|.png|.gif型別檔案!";

}

}

原始碼分析:

$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);

這句程式碼含義還是表示返回檔案型別,substr(str,num),返回str字串中第num之後的字串,strrops,返回一個數值,此處表示 . 出現的位置

原始碼中,這裡採用了白名單的方式,那麼我們只能採取%00截斷的方式才能進行繞過,在url中%00表示的ASCII碼錶示為0,而在url中0,作為特殊字元保留,表示字串結束,所以在url中出現%00時就會被認為讀取已經結束了

但是這個只存在於php5.3.4以下的版本,筆者這裡的環境高於該環節,所以不好演示,具體方法為在post url後面新增%00

Pass-12 %00截斷 POST型

同樣是%00截斷,但是這次不同的是save_path在post包裡面,GET是可以把url自動轉碼的,但是POST方式不會自動將%00編碼為空字元。因此,我們需要在burp中選中%00右擊->url->urldecode go即可。

Pass13 – Pass16 圖片馬

具體原始碼分析就不展示了,其源碼錶示的就是匹配我們上傳的檔案是不是圖片格式

使用二進位制編譯器notepad++在圖片檔案後面寫上木馬然後上傳就行,具體怎麼執行該木馬,就需要使用檔案包含的知識了,具體使用方法,比如我上傳的是123.jpg,那麼使用該木馬則為 url + 123.jpg/111.php就能進行利用了

Pass17 條件競爭

$is_upload = false;

$msg = null;

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

$ext_arr = array('jpg','png','gif');

$file_name = $_FILES['upload_file']['name'];

$temp_file = $_FILES['upload_file']['tmp_name'];

$file_ext = substr($file_name,strrpos($file_name,".")+1);

$upload_file = UPLOAD_PATH . '/' . $file_name;



if(move_uploaded_file($temp_file, $upload_file)){

    if(in_array($file_ext,$ext_arr)){

         $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;

         rename($upload_file, $img_path);

         $is_upload = true;

    }else{

        $msg = "只允許上傳.jpg|.png|.gif型別檔案!";

        unlink($upload_file);

    }

}else{

    $msg = '上傳出錯!';

}

}

原始碼分析:

我們之前接觸的程式碼的邏輯基本上是,先在後臺中判斷,然後再上傳移動檔案位置,但是我們這裡發現個問題,此處的程式碼邏輯是先上傳到伺服器,上傳完成之後,再去判斷這個檔案的字尾名是否合法,如果不合法就使用unlink函式來刪除這個檔案,所以說這個檔案是能存在很短一段時間的,這裡我們使用BP,只要利用競爭上傳,上傳的php檔案內容為寫入shell檔案,然後不斷的訪問該檔案,只要訪問成功,便可以寫入shell,直接利用burp的intruder模組上傳檔案,同時不停的訪問這個檔案。

Pass-18 條件競爭

//index.php

$is_upload = false;

$msg = null;

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

{

require_once("./myupload.php");

$imgFileName =time();

$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);

$status_code = $u->upload(UPLOAD_PATH);

switch ($status_code) {

    case 1:

        $is_upload = true;

        $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;

        break;

    case 2:

        $msg = '檔案已經被上傳,但沒有重新命名。';

        break; 

    case -1:

        $msg = '這個檔案不能上傳到伺服器的臨時檔案儲存目錄。';

        break; 

    case -2:

        $msg = '上傳失敗,上傳目錄不可寫。';

        break; 

    case -3:

        $msg = '上傳失敗,無法上傳該型別檔案。';

        break; 

    case -4:

        $msg = '上傳失敗,上傳的檔案過大。';

        break; 

    case -5:

        $msg = '上傳失敗,伺服器已經存在相同名稱檔案。';

        break; 

    case -6:

        $msg = '檔案無法上傳,檔案不能複製到目標目錄。';

        break;      

    default:

        $msg = '未知錯誤!';

        break;

}

}

//myupload.php

class MyUpload{

......

......

......

var $cls_arr_ext_accepted = array(

  ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",

  ".html", ".xml", ".tiff", ".jpeg", ".png" );

......

......

......

/** upload()

**

** Method to upload the file.

** This is the only method to call outside the class.

** @para String name of directory we upload to

** @returns void

**/

function upload( $dir ){

$ret = $this->isUploadedFile();



if( $ret != 1 ){

  return $this->resultUpload( $ret );

}



$ret = $this->setDir( $dir );

if( $ret != 1 ){

  return $this->resultUpload( $ret );

}



$ret = $this->checkExtension();

if( $ret != 1 ){

  return $this->resultUpload( $ret );

}



$ret = $this->checkSize();

if( $ret != 1 ){

  return $this->resultUpload( $ret );    

}



// if flag to check if the file exists is set to 1



if( $this->cls_file_exists == 1 ){

  

  $ret = $this->checkFileExists();

  if( $ret != 1 ){

    return $this->resultUpload( $ret );    

  }

}



// if we are here, we are ready to move the file to destination



$ret = $this->move();

if( $ret != 1 ){

  return $this->resultUpload( $ret );    

}



// check if we need to rename the file



if( $this->cls_rename_file == 1 ){

  $ret = $this->renameFile();

  if( $ret != 1 ){

    return $this->resultUpload( $ret );    

  }

}



// if we are here, everything worked as planned :)



return $this->resultUpload( "SUCCESS" );

}

......

......

......

};

程式呼叫了一個MyUpload類,來判斷即檔案的狀態,和上題一樣,但是程式會首先呼叫isUploadedFile來判斷是否屬於白名單,然後會一步一步檢查檔案大小、檔案是否存在等等,將檔案上傳後,對檔案重新命名,同樣存在條件競爭的漏洞。可以不斷利用burp傳送上傳圖片馬的資料包,由於條件競爭,程式會出現來不及rename的問題,從而上傳成功。