風炫安全web安全學習第三十七節課 15種上傳漏洞講解(二)php
仍是使用黑名單,禁止上傳全部web容器能解析的腳本文件的後綴html
$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 . '文件夾不存在,請手工建立!'; } }
繞過方式web
上傳.htaccess
靜態規則讓web容器把任意文件解析成PHP腳本文件shell
<FilesMatch "fx"> SetHandler application/x-httpd-php </FilesMatch>
演示地址:Pass-04/index.phpwindows
仍是黑名單,可是此次把.htaccess
也限制了安全
$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 . '文件夾不存在,請手工建立!'; } }
繞過方式app
在burp裏改包,把文件名改爲.phP
利用大小寫繞過檢測jsp
演示地址:Pass-05/index.phpide
仍是黑名單,此時已經把全部後綴名改成小寫,進行驗證。web安全
$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 . '文件夾不存在,請手工建立!'; } }
繞過方式
在burp裏改包,把文件名改爲.php
在後綴名處加空格(%00) 繞過
此種繞過方式受系統環境和Web容器影響
演示地址:Pass-06/index.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 . '文件夾不存在,請手工建立!'; } }
繞過方式
在burp裏改包,把文件名改爲.php.
在後綴名處加空格.繞過
可是沒有對後綴名進行去」.」處理,利用windows特性,會自動去掉後綴名中最後的」.」,可在後綴名中加」.」繞過:
演示地址:Pass-07/index.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 = 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 . '文件夾不存在,請手工建立!'; } }
繞過方式
在burp裏改包,把文件名改爲.php::$DATA
在後綴名處加::$DATA繞過
這道題利用的是Windows下NTFS文件系統的一個特性,即NTFS文件系統的存儲數據流的一個屬性 DATA 時,就是請求 a.asp 自己的數據,若是a.asp 還包含了其餘的數據流,好比 a.asp:lake2.asp,請求 a.asp:lake2.asp::$DATA,則是請求a.asp中的流數據lake2.asp的流數據內容。
演示地址:Pass-08/index.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","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);// preg_match_all $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 . '文件夾不存在,請手工建立!'; } }
繞過方式
在burp裏改包,把文件名改爲雙寫,好比.php 改爲 .phphpp
把其中一個php替換掉以後組成一個新的php文件
演示地址:Pass-10/index.php
能夠看到是白名單,只能'jpg','png','gif'
格式的文件訪問,保存的路徑是get傳遞的
$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類型文件!"; } }
繞過方式
在burp裏改包,使用在url參數上%00截斷繞過
演示地址:Pass-11/index.php
白名單,只能'jpg','png','gif'
格式的文件訪問,不過保存的路徑是post傳遞的
$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類型文件!"; } }
繞過方式
在burp裏改包,在post包裏用00截斷繞過,這裏只能改包的hex值,手動改%00字符串無效
演示地址:Pass-12/index.php
這裏是讀取了文件的內容,以文件的內容來判斷是不是圖片。
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 = "上傳出錯!"; } } }
繞過方式
製做圖片一句話木立刻傳 copy a.jpg/b + a.txt = a1.jpg
演示地址:Pass-13/index.php
這裏是現把上傳文件移動到目標文件夾,後對文件名進行判斷。不符合條件的都刪除掉。
$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 = '上傳出錯!'; } }
繞過方式
只要利用競爭上傳,上傳的php文件內容爲寫入shell文件,而後不斷的訪問該文件,只要訪問成功,即可以寫入shell,直接利用burp的intruder模塊上傳文件,同時不停的訪問這個文件。
參考:
http://blog.evalshell.com/2020/12/20/風炫安全web安全學習第三十七節課-15種上傳漏洞講解/