前言
上周五参加福建省百越杯比赛,第二名。这篇小记一下线下赛的web题目,就当时找的漏洞做个简要的说明。由于一些配置不太清楚,所以现在复现起来可能不太准确,望见谅。原环境是linux下的,这里暂时win复现。
反序列化漏洞
先看一下web源码的目录大概如下
在common文件下,有一个home.php,其源码如下:
首先有一个home类,然后通过post接受参数a,并对其进行反序列化。仔细观察home类,里面有几个方法。
__construct
析构方法进行初始化操作,指定$method和$args。
__destruct
析构方法在对象销毁时调用,其中使用了call_user_func_array(),如果method中有ping,则会调用ping方法,其参数即为$args。
ping
方法执行sysyem命令:system("ping -c 2 $host");
,注意到$host参数,由前即home类实例的$args。
waf
方法,将传入的字符串中的空格去掉。
__wakeup
方法,在反序列化时会自动调用,其中实现的功能是将参数$args先经过mysql_escape_string(),然后去除两边空格(trim),调用waf方法去掉字符串中的空格。
看到这里,思路就很明确啦。构造反序列化字符串,先经过__wakeup
的过滤,在执行结束后利用__destruct
调用ping方法,利用其中的system执行任意命令。
exp如下:
直接复制打印出来的反序列化串去post参数给home.php,并不成功。原因是有一些不可见字符。对以上的exp进行小改动,将反序列话结果输出到文件中,再用十六进制编辑器打开。
可以上发现有一些零字节需要补上,最后payload如下:
接下来进一步利用,在比赛时,我们需要读取到放在根目录下的flag(/flag)。而waf方法过滤了空格,这额可以用linux下的特殊变量\$\{IFS\}
来代替。所以如果要读取flag,修改exp.php,注意需要转义$
:
关于linux环境下的命令执行绕过waf的方法,不妨看看这个: WAF-Bypass
:命令注入
最后的payload即为:
防御方法,直接将@unserialize($a);
注释掉就行啦。
关于PHP反序列化漏洞,可以看看另一篇文章:chybeta: 浅谈php反序列化漏洞
最后
比赛攻击是用的就是这个洞,应该还有其他漏洞,后面再进一步补上吧。