文章目錄
- 前言
- 一、題目
- 二、WriteUp
- [1]. 原始碼審計
- [2]. MIME繞過
前言
php即Hypertext Preprocessor超文本前處理器,多用于web后端- 在進行代碼審計的時候可以使用
Seay進行全域搜索
目前正在學習代碼審計的內容,所以會介紹得更細一些,以便學習了解,MIME全稱為Multipurpose Internet Mail Extensions是一種標準,用來表示檔案、檔案或位元組流的性質或格式,
瀏覽器通常使用MIME型別來確定如何處理URL,MIME的組成結構為型別/子型別
檔案上傳繞過思路集合
upload-labs靶場下載
upload-labs在線靶場-BUUCTF
蟻劍AntSword
菜刀Cknife
Seay
PHP: PHP 手冊 - Manual
MIME型別 - HTTP | MDN
一、題目


php后端代碼
$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.'檔案夾不存在,請手工創建!';
}
}
二、WriteUp
隨便上傳一個檔案,并抓包了解一下其中都含有那些上傳的變數引數

[1]. 原始碼審計
- 對
php代碼進行審計,if陳述句比較多最好從外往內分析- 第一條
if陳述句只是判斷了一下提交的post請求中submit引數是否被設定且非空
PHP:isset - Manual

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {//第一條if
//代碼
}
- 第二條陳述句判斷了一下檔案上傳的路徑存不存在,存在的話就執行里面的代碼,不存在就給
$msg設定回顯資訊- 通過
Seay審計的全域搜索功能可以找到UPLOAD_PATH是在config.php中被定義的
Pass-02\index.php的代碼中包含了上一級目錄下的config.php
然后這個變數就可以在Pass-02\index.php中直接使用../表示訪問上一級的目錄,所以upload-labs-master\Pass-02\index.php包含的是upload-labs-master\config.php- 當
UPLOAD_PATH變數在upload-labs-master\Pass-02\index.php中被呼叫時,就會設定上傳的父檔案夾為upload-labs-master\upload





$is_upload = false;
$msg = null;
if (xxx) {//第一條if陳述句
if (file_exists(UPLOAD_PATH)) {//第二條if陳述句
//代碼
}else {//第二條if為假時
$msg = UPLOAD_PATH.'檔案夾不存在,請手工創建!';
}
}
- 第三條if陳述句判斷的條件稍微多了點,主要是判斷了檔案的
Content-Type引數是否為image/jpeg、image/png、image/gif三者中的一個- 如果符合就通過此if陳述句,否則就設定
$msg的值用于回顯錯誤提示資訊

$is_upload = false;
$msg = null;
if (xxx) {//第一條if陳述句
if (xxx) {//第二條if陳述句
if (($_FILES['upload_file']['type'] == 'image/jpeg')
|| ($_FILES['upload_file']['type'] == 'image/png')
|| ($_FILES['upload_file']['type'] == 'image/gif')) {//第三條if陳述句
//代碼
} else {//第三條if為假時
$msg = '檔案型別不正確,請重新上傳!';
}
} else {//第二條if為假時
//代碼
}
}
- 在上傳檔案的時候,檔案都會被存盤在一個臨時的檔案夾下
我們不需要知道具體路徑,只需要通過tmp_name引數獲取路徑即可- 下方兩條陳述句是先將獲取的臨時路徑存盤到
$temp_file變數內,然后設定上傳的路徑- 假設上傳的檔案名為
test2.txt,則$img_path值為../upload/test2.txt
$is_upload = false;
$msg = null;
if (xxx) {//第一條if陳述句
if (xxx) {//第二條if陳述句
if (xxx) {//第三條if陳述句
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
//代碼
} else {//第三條if為假時
//代碼
}
} else {//第二條if為假時
//代碼
}
}
- 第四條if陳述句會執行
move_uploaded_file函式,將存在臨時檔案夾內的檔案移動到指定的upload檔案夾下,并以原先的檔案名存盤,- 如果移動失敗就設定回顯陳述句,成功就設定
$is_upload為真
$is_upload = false;
$msg = null;
if (xxx) {//第一條if陳述句
if (xxx) {//第二條if陳述句
if (xxx) {//第三條if陳述句
//代碼
if (move_uploaded_file($temp_file, $img_path)) {//第四條if陳述句
$is_upload = true;
} else {//第四條if為假時
$msg = '上傳出錯!';
}
} else {//第三條if為假時
//代碼
}
} else {//第二條if為假時
//代碼
}
}
[2]. MIME繞過
- 知道了原始碼的上傳思路后,就比較好繞過了
其中比較重要的是第三條if陳述句,其他的陳述句沒有對檔案進行過濾- 所以只要
Content-Type的值為image/jpeg、image/png、image/gif其中一個,就可以繞過
存在于服務器的檔案后綴必須為php,不然沒有辦法決議里面的代碼- 下方的表格來自MIME型別 - HTTP | MDN
| 型別 | 描述 | 示例 |
|---|---|---|
| text | 表明檔案是普通文本,理論上是人類可讀 | text/plain, text/html, text/css, text/javascript |
| image | 表明是某種影像,不包括視頻,但是動態圖也使用image型別 | image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon |
| audio | 表明是某種音頻檔案 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav |
| video | 表明是某種視頻檔案 | video/webm, video/ogg |
| application | 表明是某種二進制資料 | application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf |

上傳成功后,右鍵查看圖片的url并訪問
沒有報錯,就說明成功決議了這個php檔案


使用蟻劍進行連接


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289482.html
標籤:其他
下一篇:Lampp安全[小白]
