前言
终于也跌跌撞撞踏入了php代码审计之路,前段时间学习了li9hu师傅的php代码审计介绍,学到了不少姿势,所以写个blog做个记录
审计思路
php的审计思路大概为两个
1、通读全文代码,了解项目的运行思路,然后进行漏洞挖掘。好处就是,通读代码可以把握全局,能够进行细致的挖掘。但是耗费时间精力很多,不适合入门的同学们。
2、使用半自动代码审计工具,如seay,rips,phpstorm等工具进行危险函数定位,并回溯可控变量。
url路由解析
index.php里,发现使用get方法,使用page参数传递值。然后过滤后传入view类的echoContent函数中解析。那我们继续深入分析。
我们进入view类中进行分析。主要是将我们的参数传递到echoCentent中进行处理,首先调用了loadFile函数,然后使用本类中调用的parseHeadAndFoot、parseVal、parseIf等函数。
我们进入loadFile文件中分析。位于comment.php中。该函数判断读取的文件是否存在,不存在将错误信息写入日志。然后存在的话,使用fopen,fread函数读取。然后再将内容继续向下处理。这里我们url路由分析就到这,大概先了解即可。
代码审计
这里我们使用Seay工具先进行自动审计。发现可能存在文件包含、命令执行、文件写入、文件读取、文件包含等漏洞。这个项目里没有使用数据库,所以不存在sql注入。
文件包含
此处有一个文件包含,其中page参数是通过post请求传递page参数,然后进过filter函数过滤。我们进入filter函数看到,将.号进行空白替换。我们这里可以使用绝对路径进行文件包含。
变量覆盖
变量覆盖,主要是使用$$,和extract()函数,我们看到入口里有三个页面存在$$符号,分别是md5、phpcom、normaliz三个页面。
发现,normaliz页面还存在一个preg_match_all()函数。该函数在php5版本的时候,可以使用/e模式,来进行代码执行。所以我们这里需要通过变量覆盖,来使得代码执行。通过参数构造成
preg_match_all(/xxx/e,phpinfo(),xxx)即可。
但是三个参数通过post_data参数进行传递,我们全局搜索下,发现是在action页面中定义的,所以推测,是先在action.php中进行文件包含,再通过post_data参数传递到normaliz.php。于是构造请求如下。
文件写入
在library/common.php中存在一个file_put_content()函数,其中input参数是有外层函数write_log传入,并且没有什么过滤。
我们进行全局搜索该函数,发现是在loadfile函数里的,当访问的文件不存在时,会将访问的文件名写入cfg_logfile文件里。这里就直接构成任意文件内容写入。loadfile只在echoCentent函数中利用。所以我们访问index.php,然后page函数中使用一个恶意代码。将其写入cfg_logfile文件后,我们进行文件包含执行。
写入到里logs/logfile.php。
使用文件包含。
命令执行
从Seay看到,主要是library/view.php中的eval函数。在phpstorm中定位到该位置,发现$strIf变量存在可控,于是我们进行变量回溯。$strIf,是通过里$iar的[1][m]然后通过parsestrIf函数进行处理。而$iar是通过content获取的。在echoContent函数中,content又先在parseVal中处理,在parseVal中,content参数的值通过$this-data里获取的,echoCentent函数中,$this-data参数又是通过data获取的,data则在action中使用了post请求得到的。其他页面正好存在变量覆盖,在action里包含其他页面,然后进行变量覆盖,这里只有res和page两个传递参数位。所以猜测是在res中。于是构造payload," or system(ipconfig) or "。执行成功。
参考
https://rj45mp.github.io/php-chinaz/
资料
chinaz:
链接:https://pan.baidu.com/s/1bWrIkVBa8ZgJABOSTYXHRQ 密码:b8lr