Web應用程序通常會提供一些上傳功能,比如上傳頭像,圖片資源等,只要與資源傳輸有關的地方就可能存在上傳漏洞,上傳漏洞歸根結底是程序員在對用戶文件上傳時控制不足或者是處理的缺陷導致的,文件上傳漏洞在滲透測試中用的比較多,因為它是獲取服務器WebShell最快最直接的攻擊手法,其實文件上傳本身並沒有問題,有問題的是文件上傳時程序員是如何對其進行合法化過濾的,如果程序員的處理邏輯做的不夠安全,則會導致嚴重的后果。
接下來你可以自行下載一個專門用於練習文件上傳的Web靶場應用並自己部署到你的服務器上,下載地址是:https://github.com/c0ny1/upload-labs 該靶場使用PHP語言編寫,專門收集滲透測試和CTF中遇到的各種上傳漏洞的靶場,目前共20關每一關都包含着不同上傳方式。
pass1 第一關
本關的突破非常的容易,因為程序中僅僅使用了JavaScript來拒絕非法文件的,但這種前端驗證的方式能夠防止普通用戶,但無法防止專業人員的突破,我們可以使用Brup工具來突破這一限制。
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; } }
首先准備好一句話后門 lyshark.php 然后將其修改成 lyshark.jpg ,使用Brup抓上傳的數據包,並將jpg后綴改成php直接提交。
上方我們開啟【Intercept is on】攔截,然后點擊上傳按鈕,將其中的【lyshark.jpg】修改為【lyshark.php】,點擊【Forward】按鈕放行,即可上傳成功。
pass2 第二關
本關的突破也非常簡單,如下代碼我們可以看出其使用了MIME類型來驗證上傳文件的合法性,下方允許上傳的格式有 image/jpeg,image/png,image/gif 這三種類型的文件。
$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.'文件夾不存在,請手工創建!'; } }
代碼中驗證了上傳的MIME
類型,繞過方式使用Brup抓包,將上傳的一句話小馬lyshark.php
中的 Content-Type: application/php修改成
Content-Type: image/jpeg
然后上傳。
pass3 第三關
第三關采用了黑名單的驗證方式,黑名單過濾也是一種不安全的方式,黑名單中定義了一系列的不安全的擴展名,服務器在接收到文件后,與黑名單做對比,從而決定是否要過濾上傳的文件。
$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 . '文件夾不存在,請手工創建!'; } }
如上方的代碼,其過濾掉了 .asp .php .jsp 等危險的腳本文件,看起來是把危險文件拒之門外了,但實際上其效果並不是太好,攻擊者可以通過黑名單中找到Web開發人員忽略的擴展名,從而完成上傳。
首先Brup攔截數據包,然后點擊上傳按鈕,在Brup的空白位置右鍵,選擇【Send To Repeater】發送到Repeater模塊中。
接着我們將 lyshark.php 修改為 lyshark.jpg 然后點擊 send 按鈕,在右側Response 會看到返回了數據./upload/201908080737005617.jpg ,這里也可以將其做成圖片木馬上傳,從而也可以繞過這個限制。
pass4 第四關
本關代碼如下,相比於前一關的內容,這里的過濾條件變得更為苛刻,其幾乎過濾掉了所有的腳本文件后綴,但是並沒有過濾.jpg等格式,如果使用jpg格式在php 5.5以前可以正常拿Shell ,但在PHP 7版本中顯然是不可取的,本關我們可以利用一個Apache解析漏洞完成我們的上傳任務。
$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 . '文件夾不存在,請手工創建!'; } }
解析漏洞,在Apache 2.x中存在一個解析漏洞,如果我們將 lyshark.php 修改為 lyshark.php.rar 這樣的格式,正常情況下會彈出文件下載提示框,但是由於Apache 2.x存在解析漏洞所以,會默認將其當作PHP腳本文件進行展開並執行。
Apache在解析文件時有一個原則,當碰到不認識的擴展名時,會從后向前解析,直到碰到認識的擴展名為止,如果不認識則會爆露其源代碼,此時我們如果上傳 lyshark.php.rar 的話,很明顯.rar 他不認識,則會先前遞增,會看到.php 默認就會使用.php 解析啦。
1.首先Brup攔截數據,然后選擇 lyshark.php 小馬,點擊上傳按鈕,回到Brup將lyshark.php 手動修改為 lyshark.php.rar 然后放行數據包,即可完成上傳。
上傳成功后,蟻劍直接拿shell。
pass5 第五關
第五關源代碼如下,該代碼中並沒有對文件名的大小寫進行強制轉換,所以繞過就變得容易了起來。
$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 . '文件夾不存在,請手工創建!'; } }
直接使用Brup抓包,然后攔截數據包,並發送到Repeater模塊將 lyshark.php 修改成 lyshark.PhP 然后Send發送數據包,成功的繞過了上傳檢測代碼。
pass6 第六關
代碼中並沒有首位去空格的函數,本關我們可以通過在 l'y'shark.php 的后面或前面添加一個或多個空格,繞過過濾規則完成上傳。
$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 . '文件夾不存在,請手工創建!'; } }
Brup抓包,然后將文件 lyshark.php 中添加空格,直接放行數據包。
pass7 第七關
本關中並沒有對末尾文件的點進行過濾,所以我們可以在 lyshark.php 的后面添加一個點,完成繞過。
$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 . '文件夾不存在,請手工創建!'; } }
pass8 第八關
本關中去掉了字符串::$DATA的代碼,所以我們可以使用 lyshark.php :: $DATA 完成繞過,但經過測試這種方式上傳的文件PHP解釋器已經無法識別了,也就無法拿到Shell。
$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 . '文件夾不存在,請手工創建!'; } }
pass9 第九關
本關中我們可以使用 lyshark.php. . (點+空格+點),的方式完成繞過。
$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 . '文件夾不存在,請手工創建!'; } }
pass10 第十關
本關 str_ireplace($deny_ext,"", $file_name); 函數,將黑名單中的后綴名替換為空,因此可雙寫繞過:
$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 . '文件夾不存在,請手工創建!'; } }
pass11 第十一關
通過GET方式傳入數據,然后通過GET
傳入save_path
值,使得上傳文件路徑可控,嘗試使用%00
截斷,這里PHP版本必須小於5.3否則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類型文件!"; } }
pass12 第十二關
本關與上一關不同,本關中通過POST
方式傳遞save_path變量的值
,同樣的可以使用%00
截斷,但需要考慮URL
編碼的問題,默認GET
方式傳輸會自動解碼成空字符,而POST
方式則不會自動解碼,所以要對POST
中的%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 = $_POST['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類型文件!"; } }
1.首先上傳文件,然后攔截請求,並在lyshark.jpg后面添加%00
2.接着選中%00 ,然后對URL進行編碼。
pass13 第十三關
本關采用了白名單的上傳驗證方式,其主要是允許jpg/png/gif這三種文件的傳輸,且代碼中檢測了文件頭的2
字節內容,也就是說我們只需要將文件的頭兩個字節修改為圖片的格式就可以繞過,通常 JPEG/JPG: FF D8 , PNG:89 50,GIF:47 49
function getReailFileType($filename){ $file = fopen($filename, "rb"); $bin = fread($file, 2); //只讀2字節 fclose($file); $strInfo = @unpack("C2chars", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = ''; switch($typeCode){ case 255216: $fileType = 'jpg'; break; case 13780: $fileType = 'png'; break; case 7173: $fileType = 'gif'; break; default: $fileType = 'unknown'; } return $fileType; } $is_upload = false; $msg = null; if(isset($_POST['submit'])){ $temp_file = $_FILES['upload_file']['tmp_name']; $file_type = getReailFileType($temp_file); if($file_type == 'unknown'){ $msg = "文件未知,上傳失敗!"; }else{ $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = "上傳出錯!"; } } }
以JPEG為例,我們在一句話木馬的開頭添加兩個11也就是二進制的2121,然后將 lyshark.php 修改為 lyshark.jpg,使用Brup抓包,然后發送到Repeater模塊
。
將HEX
編碼 3131 改為 FFD8 點Go
后成功上傳JPG
。
pass14 第十四關
這一關很簡單,首先程序中通過使用,getimagesize()
函數對文件信息的檢測識別,繞過的話就是制作一個圖片木馬,但是在PHP 7 版本中不能保證其能夠正常的拿Shell。
function isImage($filename){ $types = '.jpeg|.png|.gif'; if(file_exists($filename)){ $info = getimagesize($filename); $ext = image_type_to_extension($info[2]); if(stripos($types,$ext)>=0){ return $ext; }else{ return false; } }else{ return false; } } $is_upload = false; $msg = null; if(isset($_POST['submit'])){ $temp_file = $_FILES['upload_file']['tmp_name']; $res = isImage($temp_file); if(!$res){ $msg = "文件未知,上傳失敗!"; }else{ $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = "上傳出錯!"; } } }
Pass-16-二次渲染繞過
判斷后綴名、content-type,利用imagecreatefromgif判斷是否為gif圖片,最后做渲染。
$is_upload = false; $msg = null; if (isset($_POST['submit'])){ // 獲得上傳文件的基本信息,文件名,類型,大小,臨時文件路徑 $filename = $_FILES['upload_file']['name']; $filetype = $_FILES['upload_file']['type']; $tmpname = $_FILES['upload_file']['tmp_name']; $target_path=UPLOAD_PATH.'/'.basename($filename); // 獲得上傳文件的擴展名 $fileext= substr(strrchr($filename,"."),1); //判斷文件后綴與類型,合法才進行上傳操作 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 = "上傳出錯!"; } }else if(($fileext == "png") && ($filetype=="image/png")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上傳的圖片生成新的圖片 $im = imagecreatefrompng($target_path); if($im == false){ $msg = "該文件不是png格式的圖片!"; @unlink($target_path); }else{ //給新圖片指定文件名 srand(time()); $newfilename = strval(rand()).".png"; //顯示二次渲染后的圖片(使用用戶上傳圖片生成的新圖片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagepng($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上傳出錯!"; } }else if(($fileext == "gif") && ($filetype=="image/gif")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上傳的圖片生成新的圖片 $im = imagecreatefromgif($target_path); if($im == false){ $msg = "該文件不是gif格式的圖片!"; @unlink($target_path); }else{ //給新圖片指定文件名 srand(time()); $newfilename = strval(rand()).".gif"; //顯示二次渲染后的圖片(使用用戶上傳圖片生成的新圖片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagegif($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上傳出錯!"; } }else{ $msg = "只允許上傳后綴為.jpg|.png|.gif的圖片文件!"; } }
Pass-17-條件競爭
先將文件上傳到服務器,然后判斷是否合法合法則保留,可以利用burp的intruder模塊不斷上傳,然后我們不斷訪問該網址,總有一個會上傳成功。
$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 = '上傳出錯!'; } }