2023-11-17 分類: 網(wǎng)站建設(shè)
pHp代碼審計(jì):(一)文件上傳0x00概覽
在網(wǎng)站運(yùn)行過程中,不可避免地會更新網(wǎng)站的某些頁面或內(nèi)容,這時(shí)就需要使用網(wǎng)站上的文件上傳功能。如果對上傳的文件沒有限制,或者繞過了限制,則可能會使用該功能將可執(zhí)行文件和腳本上傳到服務(wù)器,從而進(jìn)一步導(dǎo)致服務(wù)器崩潰。
可見php文件上傳代碼,了解上傳漏洞的前提是了解文件上傳的功能及其原理。如果只知道有文件上傳,而且可能有漏洞,那就和不知道一樣。
具體來說,用戶上傳的一些文件仍然是pHp腳本。用戶可以通過服務(wù)器直接訪問這些上傳到服務(wù)器上的pHp腳本,并且會執(zhí)行其中包含的一些命令。文件上傳功能如此強(qiáng)大,如果您的網(wǎng)站在文件上傳方面沒有很好的控制,它就會崩潰。
文件上傳漏洞的原因有很多,主要包括:
其中開源編輯器漏洞和文件上傳漏洞原理相同,只是多了一個(gè)編輯器。上傳時(shí),我們的腳本仍然會被上傳。
松散過濾非常常見,我們將在以下示例中看到。比如大小寫問題,網(wǎng)站只驗(yàn)證是否是小寫,我們可以把后綴名改成大寫。
然后是文件解析漏洞。比如系統(tǒng)會涉及到這種情況:文件名為1.php;.jpg,IIS 6.0 可能認(rèn)為是jpg文件,但是當(dāng)它執(zhí)行被執(zhí)行。我們可以利用這個(gè)解析漏洞進(jìn)行上傳。再比如php文件上傳代碼,有一些未知的后綴,比如a.php.xxx。由于后綴名無法識別,可能會被釋放。如果攻擊者再次執(zhí)行該文件,則該網(wǎng)站可能被控制。
最后是路徑截?cái)?,就是在上傳的文件中使用一些特殊的符號,使文件在上傳時(shí)被截?cái)?。比如a.php.jpg,在網(wǎng)站上驗(yàn)證時(shí),后綴會被認(rèn)為是jpg,但保存到硬盤時(shí),會被截?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,上傳文件后,會得到這樣的結(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ù)需要丟棄并重新生成,或過濾并重新使用。
過度相信這些東西會產(chǎn)生一些隱患,我們將在下面看到。
0x02 實(shí)戰(zhàn)
實(shí)戰(zhàn)部分,我會用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)容。打開抓包,我們會在請求體中看到類似這樣的內(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í)會被截?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”,會自動(dòng)插入一個(gè)\0。然后點(diǎn)擊“開始”,你就完成了。
注意這里插入的話,會上傳成功,但是訪問的時(shí)候會直接當(dāng)作圖片處理,里面的內(nèi)容不會被執(zhí)行。
0x03 解決方案
同目錄下還有一個(gè).php,里面有正確的做法。大家可以看看。里面的代碼使用了$=md5(().$).'.'。$; 生成獨(dú)立的文件名,使其不受原文件名中各種截?cái)嘧址母蓴_。
0x04 注意
新聞標(biāo)題:網(wǎng)站上傳漏洞的前提是了解文件上傳這個(gè)功能嗎?
網(wǎng)頁路徑:http://www.rwnh.cn/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)請盡快告知,我們將會在第一時(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)
猜你還喜歡下面的內(nèi)容