Uploads-labs上傳繞過(上)
- 2020 年 3 月 8 日
- 筆記
·使用phpstudy搭建Uploads-labs
鏈接:https://pan.baidu.com/s/1lMRBVdQyFuKOgNlWPUoSSQ
提取碼:8mmv
下載後,解壓修改名字:upload-labs,然後移動到phpstudy網站目錄:phpstudywww(根據自己的網站目錄決定),若網站根目錄下存在多個目錄,記得打開允許目錄列表,打開方法:其他選項菜單—phpStudy設置—允許目錄列表。在upload-labs目錄下創建一個upload文件夾
在瀏覽器輸入:http://localhost/upload-labs/ 或者:http://127.0.0.1/upload-labs/
第一關:JS繞過
源程式碼如下

從源程式碼來看,這裡是用前端程式碼來判斷的允許上傳文件的名單(白名單)驗證。我們需要做的只是添加上.php文件即可

上傳的時候打開burp抓包發送到repeater模組點擊go

能夠看見a.php已經上傳成功
打開菜刀鏈接即可



第二關:文件類型繞過
先看給的源程式碼

從源碼來看,這裡只是對文件類型進行了判斷 Content-Type
我們上傳時,用burp抓包修改Content-Type為:image/jpg 即可繞過

接下來就算和第一題一樣,用菜刀鏈接即可
第三題:php3繞過
做題之前,先說說白名單和黑名單
- 白名單限制:通俗一點來說就是允許上傳的名單,白名單限制的特點就是只允許上傳指定的文件,這總時候繞過的招式就很少了,常見的是%00截斷上傳,但是它上傳上去並不能解析為php,這時候需要找到解析漏洞或者包含漏洞才能觸發小馬
- 黑名單限制:不允許上傳的名單,黑名單限制就是除了規定的文件不能上傳外,其它文件都可以上傳,這總時候,繞過的方式就很多了,常見的有大小寫繞過,雙寫繞過,如果是php還能php3 php4 php5 phtml 等方式
源碼:
$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,.aspx,.php,.jsp文件
$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); //收尾去空
程式碼說明:上傳文件的時候判斷類型,然後去除文件末尾的點,然後將文件名全變為小寫再去掉文件名後面的空格
這裡我們就不能用大小寫繞過的方式去繞過
在這裡我們只需要避開上傳就好,這裡方式很多-> php3、php4等

在這裡如果復現不成功,打開phpstudy->其它選項菜單->打開配置文件夾->httpd-conf
ctrl+F查找 application/x-httpd-php
再後面添加.php3 php4 php5 phtml即可
如果沒有找到,把下面一行程式碼加入httpd-conf即可
AddType application/x-httpd-php .php .html .phtml

第四關:.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",".ini"); $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 . '文件夾不存在,請手工創建!'; } }
源程式碼看似把幾乎所有的文件都限制了,仔細看它漏掉了.htaccess
關於.htaccess 大家第一次看見,在這給大家詳細講解一下
1.創建htaccess文件,編輯內容為:
SetHandler application/x-httpd-php
然後再上傳shell.jpg的木馬, 這樣shell.jpg就可解析為php文件。
2.編輯內容為:
<FilesMatch "jpg">
SetHandler application/x-httpd-php
</FilesMatch>
指定文件名的文件,才能被當做PHP解析.
原文鏈接:https://blog.csdn.net/qq_36512966/article/details/72716079

先上傳.htaccess

.htaccess上傳成功後上傳圖片馬

菜刀鏈接就OK

第五關:邏輯繞過
$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 . '文件夾不存在,請手工創建!'; } }
參考第十題解題辦法。
第六關:大寫繞過
$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",".ini"); $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 . '文件夾不存在,請手工創建!'; } }
對比之前的程式碼,發現沒有了轉換小寫的操作,這裡我們直接大寫繞過就好

後面就是菜刀的使用了,參考前面就好
第七關:空格繞過
$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",".ini"); $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 . '文件夾不存在,請手工創建!'; } }
對比前面的程式碼,發現少了 去掉末尾空格的操作,所有我們空格繞過就好

第八關:點空格點繞過
$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",".ini"); $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 . '文件夾不存在,請手工創建!'; } }
對比前面程式碼,這裡沒有對文件尾 點 的處理,所有我們上傳a.php.即可

第九關:::$DATA繞過(windows)
$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",".ini"); $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
在php+windows的情況下:如果文件名+"::$DATA"會把::$DATA之後的數據當成文件流處理,不會檢測後綴名.且保持"::$DATA"之前的文件名。
如果這是我們在windows下搭建的環境的話,我們在文件末尾加入::$DATA即可繞過上傳

上傳成功後,我們在本地upload文件夾中看見的是這樣,所有和我們預期是一樣的

在這裡我們用菜刀連接:
http://127.0.0.1/upload-labs/upload/202001080558469464.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",".ini"); $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 . '文件夾不存在,請手工創建!'; } }
這一關看起來無從下手,但是他有個邏輯漏洞
程式先是去除文件名前後的空格,再去除文件名最後所有的.,再通過strrchar來尋找.來確認文件名的後綴,但是最後保存文件的時候沒有重命名而使用的原始的文件名,導致可以利用類似a.php. .(兩個點號之間有一個空格)繞過

後11題參考下一期內容