網(wǎng)站上傳漏洞的前提是了解文件上傳這個(gè)功能嗎?

2023-11-17    分類: 網(wǎng)站建設(shè)

pHp代碼審計(jì):(一)文件上傳0x00概覽

在網(wǎng)站運(yùn)行過程中,不可避免地會(huì)更新網(wǎng)站的某些頁面或內(nèi)容,這時(shí)就需要使用網(wǎng)站上的文件上傳功能。如果對上傳的文件沒有限制,或者繞過了限制,則可能會(huì)使用該功能將可執(zhí)行文件和腳本上傳到服務(wù)器,從而進(jìn)一步導(dǎo)致服務(wù)器崩潰。

可見php文件上傳代碼,了解上傳漏洞的前提是了解文件上傳的功能及其原理。如果只知道有文件上傳,而且可能有漏洞,那就和不知道一樣。

具體來說,用戶上傳的一些文件仍然是pHp腳本。用戶可以通過服務(wù)器直接訪問這些上傳到服務(wù)器上的pHp腳本,并且會(huì)執(zhí)行其中包含的一些命令。文件上傳功能如此強(qiáng)大,如果您的網(wǎng)站在文件上傳方面沒有很好的控制,它就會(huì)崩潰。

文件上傳漏洞的原因有很多,主要包括:

其中開源編輯器漏洞和文件上傳漏洞原理相同,只是多了一個(gè)編輯器。上傳時(shí),我們的腳本仍然會(huì)被上傳。

松散過濾非常常見,我們將在以下示例中看到。比如大小寫問題,網(wǎng)站只驗(yàn)證是否是小寫,我們可以把后綴名改成大寫。

然后是文件解析漏洞。比如系統(tǒng)會(huì)涉及到這種情況:文件名為1.php;.jpg,IIS 6.0 可能認(rèn)為是jpg文件,但是當(dāng)它執(zhí)行被執(zhí)行。我們可以利用這個(gè)解析漏洞進(jìn)行上傳。再比如php文件上傳代碼,有一些未知的后綴,比如a.php.xxx。由于后綴名無法識別,可能會(huì)被釋放。如果攻擊者再次執(zhí)行該文件,則該網(wǎng)站可能被控制。

最后是路徑截?cái)?,就是在上傳的文件中使用一些特殊的符號,使文件在上傳時(shí)被截?cái)?。比如a.php.jpg,在網(wǎng)站上驗(yàn)證時(shí),后綴會(huì)被認(rèn)為是jpg,但保存到硬盤時(shí),會(huì)被截?cái)酁閍.php,這是一個(gè)直接的php文件。

通常用于截?cái)嗦窂降淖址校?/p>

這些是可能導(dǎo)致截?cái)嗟淖址?。需要注意的是,在?shí)戰(zhàn)中,由于網(wǎng)站的編解碼規(guī)則不同,需要靈活應(yīng)用。例如,\0 失敗可以替換,或者你可以嘗試各種編碼,例如,或者,多試幾次。

0x01 代碼

文件上傳首先需要一個(gè)表單,如下,我們稱之為a.html:

這里有幾個(gè)要素:

接下來是pHp腳本中的東西。在 pHp 中,通過 $ 對象讀取文件,并使用以下屬性:

t.php 中的代碼是這樣寫的:

可以看到aaa是文件輸入框中的name屬性。

我們把這兩個(gè)文件放在服務(wù)器的目錄下,或者直接在目錄下啟動(dòng)pHp自帶的服務(wù)器。打開a.html,上傳文件后,會(huì)得到這樣的結(jié)果。這里我直接上傳了a.html:

array(5) { 
    ["name"]=> string(6) "a.html" 
    ["type"]=> string(9) "text/html" 
    ["tmp_name"]=> string(44) "C:\Users\asus\AppData\Local\Temp\php43A1.tmp" 
    ["error"]=> int(0) 
    ["size"]=> int(133) 
}

需要說明的是,在處理文件上傳的時(shí)候,不要相信文件類型的類型,因?yàn)闉g覽器生成后類型是可以改變的。您甚至可以手動(dòng)構(gòu)建類型與實(shí)際內(nèi)容不匹配的數(shù)據(jù)包。

同時(shí),不應(yīng)信任文件名名稱。相反,文件名和擴(kuò)展名應(yīng)該分開,并且擴(kuò)展名應(yīng)該被列入白名單。文件名根據(jù)需要丟棄并重新生成,或過濾并重新使用。

過度相信這些東西會(huì)產(chǎn)生一些隱患,我們將在下面看到。

0x02 實(shí)戰(zhàn)

實(shí)戰(zhàn)部分,我會(huì)用DVWA中的例子來演示。DVWA是一套用pHp+編寫的WEb漏洞測試程序,用于常規(guī)WEb漏洞教學(xué)和檢測。包含SQL注入、XSS、盲注等常見安全漏洞。項(xiàng)目主頁在這里,源碼也在這里。

下載部署后,我們打開///,這里是上傳漏洞部分的源碼,可以看到難度分為低、中、高三個(gè)級別。

先看低級難度low.php:

if( isset( $_pOST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEb_pAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // No
        $html .= '
Your image was not uploaded.

';}else {// 是的!$html .=”

{$target_path} succesfully uploaded!

";}}

可以看到?jīng)]有過濾,可以直接上傳任何文件。

然后是.php:

if( isset( $_pOST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEb_pAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    // Is it an image?
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {
        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // No
            $html .= '
Your image was not uploaded.

';}else {// 是的!$html .=”

{$target_path} succesfully uploaded!

";}}else {// file$html .= '

Your image was not uploaded. We can only accept JpEG or pNG images.

';}}

注意第10行和第11行,驗(yàn)證類型必須是jpg或png,大小必須小于某個(gè)值。后者可以忽略。剛才我說類型不可信,我們可以抓包,改類型,然后提交。

因?yàn)槲蚁胙菔救绾瓮黄粕蟼飨拗疲皇侨绾问褂蒙蟼鞯哪_本,所以我直接創(chuàng)建了一個(gè)新的pHp文件,并在其中寫入了一些內(nèi)容。打開抓包,我們會(huì)在請求體中看到類似這樣的內(nèi)容:

------WebKitFormboundaryh4zhLV52OKhf6aJg
Content-Disposition: form-data; name="uploaded"; filename="a.php"
Content-Type: application/octet-stream

右鍵單擊“發(fā)送到”并將該 /- 更改為 /jpeg。點(diǎn)擊“前往”發(fā)送。

最后,高級high.php:

if( isset( $_pOST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEb_pAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];
    // Is it an image?
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {
        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // No
            $html .= '
Your image was not uploaded.

';}else {// 是的!$html .=”

{$target_path} succesfully uploaded!

";}}else {// file$html .= '

Your image was not uploaded. We can only accept JpEG or pNG images.

';}}

觀察同樣的位置,這次改用后綴名來判斷。這時(shí)候我們可以在后綴前插入\0,即a.php\0.jpg。請注意,它不是斜線加零,而是空字符。這樣判斷的時(shí)候,后綴是.jpg,寫入磁盤時(shí)會(huì)被截?cái)酁閍.php。它可以被上傳或執(zhí)行。

我們還捕獲包裹并交付。先把a(bǔ).php改成a.php.jpg,然后切換到十六進(jìn)制編輯模式插入空字符。

鼠標(biāo)拖動(dòng)的范圍是a.php.jpg,在第二個(gè)2e網(wǎng)格上右擊,點(diǎn)擊“byte”,會(huì)自動(dòng)插入一個(gè)\0。然后點(diǎn)擊“開始”,你就完成了。

注意這里插入的話,會(huì)上傳成功,但是訪問的時(shí)候會(huì)直接當(dāng)作圖片處理,里面的內(nèi)容不會(huì)被執(zhí)行。

0x03 解決方案

同目錄下還有一個(gè).php,里面有正確的做法。大家可以看看。里面的代碼使用了$=md5(().$).'.'。$; 生成獨(dú)立的文件名,使其不受原文件名中各種截?cái)嘧址母蓴_。

0x04 注意

新聞標(biāo)題:網(wǎng)站上傳漏洞的前提是了解文件上傳這個(gè)功能嗎?
網(wǎng)頁路徑:http://www.bm7419.com/news48/295048.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化電子商務(wù)、外貿(mào)建站、用戶體驗(yàn)、域名注冊、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)