[程式碼審計]php上傳漏洞總結

寒江雪語發表於2018-06-05

背景:
這兩天在網上瞎看,看到別人總結的一個上傳漏洞靶場,覺得很不錯,就是自己測試了下,
感覺對程式碼審計能力提高還是有幫助的,下面簡單介紹靶場的解題思路(當然,每一題可能存在多種上傳方式)。
靶場地址:https://github.com/c0ny1/upload-labs
一、環境搭建
建議使用靶場提供的測試環境。
二、解題思路
Pass-01:
檢查程式碼:

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;
    }
}

由程式碼可知程式僅用js在前端做了簡單的字尾名檢查,很容易繞過。

本地目錄放兩個檔案,一個phpinfo.png,一個phpinfo.php。 上傳phpinfo.png抓包,在這將png改成php即可。

Pass-02:
檢查程式碼:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
                $is_upload = true;

            }
        } else {
            $msg = '檔案型別不正確,請重新上傳!';
        }
    } else {
        $msg = $UPLOAD_ADDR.'資料夾不存在,請手工建立!';
    }
}

這裡僅對上傳type型別做了判斷。

這裡將Content-Type: application/octet-stream修改成Content-Type: image/png即可。

Pass-03:
檢查程式碼:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $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)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) {
                 $img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name'];
                 $is_upload = true;
            }
        } else {
            $msg = '不允許上傳.asp,.aspx,.php,.jsp字尾檔案!';
        }
    } else {
        $msg = $UPLOAD_ADDR . '資料夾不存在,請手工建立!';
    }
}

這裡只對基本型別做了簡單的判斷,可以上傳php3,php5等型別的檔案,由於我的環境配的不能解析php3等類似的檔案,所以這裡我們上傳.htaccess檔案,內容如下
AddType application/x-httpd-php .jpg
意思讓伺服器將.jpg檔案當做php解析。
然後在上傳phpinfo.jpg即可。

=======================================
*後面的請參考(歡迎訂閱我的專欄):
https://xiaozhuanlan.com/topic/7036829451*

相關文章