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

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

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

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

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

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

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

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

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

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

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

通常用于截斷路徑的字符有:

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

0x01 代碼

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

這里有幾個要素:

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

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

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

我們把這兩個文件放在服務(wù)器的目錄下,或者直接在目錄下啟動pHp自帶的服務(wù)器。打開a.html,上傳文件后,會得到這樣的結(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) 
}

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

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

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

0x02 實戰(zhàn)

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

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

先看低級難度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行,驗證類型必須是jpg或png,大小必須小于某個值。后者可以忽略。剛才我說類型不可信,我們可以抓包,改類型,然后提交。

因為我想演示如何突破上傳限制,而不是如何使用上傳的腳本,所以我直接創(chuàng)建了一個新的pHp文件,并在其中寫入了一些內(nèi)容。打開抓包,我們會在請求體中看到類似這樣的內(nèi)容:

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

右鍵單擊“發(fā)送到”并將該 /- 更改為 /jpeg。點擊“前往”發(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.

';}}

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

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

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

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

0x03 解決方案

同目錄下還有一個.php,里面有正確的做法。大家可以看看。里面的代碼使用了$=md5(().$).'.'。$; 生成獨立的文件名,使其不受原文件名中各種截斷字符的干擾。

0x04 注意

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

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

廣告

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