代码审计-php代码执行

作者:小刚
一位苦于信息安全的萌新小白帽,记得关注给个赞,谢谢
本实验仅用于信息防御教学,切勿用于其它用途

前言

近期在学习php的代码审计,推一下这本书啊代码审计 企业级Web代码安全架构_尹毅著
在学习代码执行和命令执行中遇到很多的小问题,再本文章中记一下。
先说几个php小要点

1.当代码赋值时用的双引号,双引号中的变量会进行解析
2.@符号,当表达式附加@符号时,将忽略该表达式可能生成的错误消息
3.php中${}一起用并且内部是一个函数的话,内部函数会被执行,php解释器会自动略过无效的${}
4.eval属于php语法构造的一部分,是语言结构并不是一个函数,所以不能通过调用函数形式来调用。
echo,print,unsert(),issert()empty(),incli=ude(),require()都不行。

什么是代码执行,命令执行

在漏洞银行的萌新课中有位大佬给我点通了。
代码执行、命令执行说白了就是倒过来,执行代码、执行命令
代码是php,java,python等写的代码,命令是win,Linux的系统命令。
本篇重点写写代码执行的小问题。

1.eval assert导致的代码执行

在代码审计中主要观察这俩所获得的参数可不可控,有没有进行过滤。
php一句话木马通常使用eval。

2.preg_replace的e修饰符

preg_replace 是执行一个正则表达式的搜索和替换的函数

使用e 修饰符时, 会将替换的字符串当做代码执行

preg_replace("/\[(.*)\]/e",'\\1',$_GET['str']);

\\n 或$n是引用第n个匹配的字符,当传参?str=[phpinfo()]时,就会执行phpinfo()代码

注意:
php5.5.0的/e 修饰符已经被弃用了。使用会提示被弃用。改为用 preg_replace_callback() 代替
php7.0.0不再支持 /e修饰符。 使用会报错,改为用 preg_replace_callback() 代替。

3.调用函数导致的代码执行

在php中很多函数可以调用php函数来使用,call_user_func()、array_map()等等
call_user_func(1,2)用来调用函数,第一参数为函数的名,第二参数为调用函数的参数

$b = "phpinfo()";
cell_user_func($_GET['a'],'$b');

当传参?a=assert即可导致PHPinfo()代码执行。

4.动态函数执行

php中有个函数写法叫动态函数,或者变量函数
写法"函数(变量)"

$_GET['a']($_GET['b']);

当传参?a=assert&b=phpinfo()即可导致代码执行
但是eval等不能调用
在上传木马时,可以通过字符串拼接绕过许多waf的检测

$e='sys'.'t','em';
$e('ipconfig');

ThinkPHP历史漏洞

简化的漏洞代码

preg_replace('/(\w+)\|(.*)/ie','$\\1="\\2";',$_GET['a']);

当传参?a=z|${@phpinfo()}

'$\\1="\\2";'
变成
'$z="${@phpinfo()}"'

结合上面说的几个小要点,最终导致命令执行。

修复措施

过滤方式采用白名单机制,结合正则表达式进行白名单限制
还有就是对双引号的严格监控。

2020/7/25修改

php5中assert是一个函数,可以动态函数调用
php7中assert不再是函数,类似eval,不能动态执行了。

猜你喜欢

转载自blog.csdn.net/weixin_43221560/article/details/107375721