upload-labs
less-1(前端js繞過)
建立一個一句話木馬 上傳
在前端有checkfile()函式,就是檢測上傳的檔案是否是jpg png gif格式,在前端刪掉即可上傳成功
原始碼:
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; } } 沒有進行任何過濾
Less-2(檔案型別繞過)
第二關上傳後沒有通過前端js驗證,所以上一關的方法行不通。
進行抓包發現只有在Content-Type處改變資料,所以修改Content-Type的引數即可上傳成功
。
less-3(其他字尾可解析繞過)
第三關Content-Type修改行不通了,試了下php3上傳成功
原始碼:
$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 . '資料夾不存在,請手工建立!'; } }
1.原始碼中有黑名單過濾了.asp,.aspx,.php,.jsp
2.在window的時候如果檔名+"::$DATA"會把::$DATA之後的資料當成檔案流處理,不會檢測字尾名,且保持::$DATA之前的檔名,他的目的就是不檢查字尾名.
例如:"phpinfo.php::$DATA"Windows會自動去掉末尾的::$DATA變成"phpinfo.php"
Less-4(.htacess檔案繞過)
直接看原始碼
$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 . '資料夾不存在,請手工建立!'; } }
這個黑名單過濾的有點多,把常見的過濾方法都過濾了,::$DATA也不行
可以用.htaccess檔案上傳 (.htaccess可以用來留後門和針對黑名單繞過)
.htaccess檔案
原理大概就是:通過.htaccess檔案呼叫php解析器解析一個檔案,只要包含"cimer"這個字串的任意檔案。如果"cimer"的內容是一句話木馬,就可以通過菜刀等連線
例如:
shell.htaccess檔案中
shell.jpg是一個圖片馬,上傳後會當成php解析
上傳成功後檢視影象複製路徑菜刀連線成功
Less-5(大小寫繞過)
原始碼:
$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所以不能有上一關方法
但是這關的原始碼中沒有 strtolower函式,說明可以採用大小寫繞過
Less-6(空格繞過)
原始碼:
$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 . '資料夾不存在,請手工建立!';
}
}
這關原始碼裡面加上了strlower函式,但是沒有 $file_ext = trim($file_ext);去空處理,所以可以利用空格繞過。 在上傳儲存到windows系統後文件名最後一個空格會被抹掉,意味著在後綴那裡加上空格後可以繞過黑名單,最後儲存的時候還是原始檔名字尾。
Less-7(點繞過)
原始碼:
$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 . '資料夾不存在,請手工建立!';
}
}
這關沒有 $file_name = deldot($file_name);這個函式,意味著在檔案末尾加上點就可以繞過
less-8(::$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 . '資料夾不存在,請手工建立!';
}
}
原始碼中沒有了$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字串::$DATA
所以可以用::$DATA繞過 。windows中特性檔案流繞過,在後綴後加上::$DATA,上傳成功後儲存的還是原檔案
Less-9(點+空格+點繞過)
原始碼:
• 程式碼
$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 . '資料夾不存在,請手工建立!';
}
}
原始碼中刪除檔名末尾的點,刪除首尾的空格,再通過strrchr虛招檔案中的點確定檔案的字尾名,但是在最後儲存檔案的時候沒有重新賦值命名,而是直接使用file_name原始檔名導致可以利用點+空格+點繞過
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($deny_ext,"", $file_name);將deny_ext中替換成空字元,可以嘗試雙寫繞過
經過測試,使用黑名單中的任何一個雙寫都可以繞過
Less-11(GET型%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型別檔案!";
}
}
十一關沒有了黑名單變成了白名單,只能有jpg,png,gif。直接拼接的img_path可以%00截斷.截斷條件:
1、php版本小於5.3.4 2、php.ini的magic_quotes_gpc為OFF狀態
知識點:這裡利用的是00截斷。move_uploaded_file函式的底層實現類似於C語言,遇到0x00會截斷。
Less-12(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型別檔案!";
}
}
這關和十一關不同的是這次的save_path是通過post傳進來的,還是利用00截斷,但這次需要在二進位制中進行修改,因為post不會像get對%00進行自動解碼
Less-13(圖片馬)
copy 1.jpg /b + 1.php /a test.jpg
Less-14(圖片馬繞過 - getimagesize)
這裡用getimagesize獲取檔案型別,還是直接就可以利用圖片馬就可進行繞過
getimagesize() 函式用於獲取影象大小及相關資訊,成功返回一個數組,失敗則返回 FALSE 併產生一條 E_WARNING 級的錯誤資訊
less-15(圖片馬繞過exif_imagetype)
exif_imagetype()檢查是否為圖片檔案
less-16()
詳細分析(https://xz.aliyun.com/t/2657#toc-0)