[RoarCTF 2019]Easy Calc
0x00 php解析字符串特性解题
打开网页
看这里我们知道这是实现的一个网页计算器,所以不会存在SQL注入。
暂时能想到的没有其他方向了,所以我们去查找更多信息。
查看网站源代码,对代码进行观察
看到下面这一行
<!--I've set up WAF to ensure security.-->
我们知道存在过滤,继续观察到了下面这一行
url:"calc.php?num="+encodeURIComponent($("#content").val()),
这是一个ajax请求里面的参数,我们知道存在一个calc.php页面并且他的传入参数为num
我们打开calc.php界面看看
我们看到下面这一行
eval('echo '.$str.';');
可以知道也许存在命令注入漏洞,但是对$str变量进行的如下的过滤
[' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
那我们先试一下是否存在注入漏洞,因为phpinfo()这个命令中没有字符存在上面的列表中,构造如下的payload:
/calc.php?num=phpinfo()
结果返回如下
再试试如下payload:
/calc.php?num=1
结果返回如下
由此可知我们有权限访问calc.php,但是在上面进行命令注入的时候返回没有权限访问,所以这里还存在一个过滤WAF
这里我根据 ?num 猜测只可以传送数字
我们想办法Bypass,因为后台是php写的
所以首先就想到了php解析符串的特性:
- 删除空格
- 将特殊字符(包括空格)变成 _ (下划线)
根据这一特性我们可以创建如下的payload:
/calc.php? num=phpinfo()
##注意?后面是空格
根据返回结果,我们可以知道注入的命令被执行了,看来WAF是用php写的
那为什么这个payload,注入的命令会被执行?
重点就是?后面的空格
后台使用php写的,WAF会检测前端传入的
WAF应该制定的规则是num参数只可以传入数字
然而这里我们传入的是 num,而不是num所以不符合WAF的规则,从而绕过WAF
经过WAF后会到后端的calc.php
calc.php中的$GET对传入的参数进行解析,将 num变成num
所以最后phpinfo()传入到eval()函数进行执行
接下来我们寻找flag,可以构造如下payload:
/calc.php? num=var_dump(scandir("/"))
突然想起来前面过滤列表里面存在 /,这里我们通过ASCII绕过
/calc.php? num=var_dump(scandir(chr(47)))
我们可以看到返回的结果中存在f1agg,flag可能在里面
继续构造payload来获取/f1agg中的内容
/calc.php? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
## chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)是/f1agg的ASCII编码形式
得到结果
0x01 http走私
构造payload如下:
/calc.php?num=phpinfo()
并抓包得到如下
修改成如下
发送后可以返回界面
说明已经执行phpinfo()命令
这里为什么会执行?
首先这里用的是http走私的CL-CL
带有WAF的代理服务器接收到请求中存在两个CL,产生400错误使得WAF失效将数据包全部转给后端服务器
后端服务器可以解析成功导致了命令的执行
然后继续构造如下payload:
/calc.php?num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
利用上面的方法去请求,得到flag