太菜了,只能等到 writeup 出了再来复现
1、Easy Calc
打开网页,显示让我们输入表达式
查看源代码,发现有个 calc.php 文件,访问 calc.php 看看
显示出了 calc.php 的源码
<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>
分析这个代码,它接受一个参数 num 传进来的值,并且有一个 blacklist ,传入的参数不能包括 ' ', '\t', '\r', '\n',''', '"', '`', '[', ']','$','\','^' ,单是这样的话,绕过这几个限制其实并不难,但是这个网站还有 waf,当我们尝试执行命令的时候,服务器会返回 403。(除了下面说的 http 走私漏洞,还可以对 payload 进行 url 编码,一样可以绕过waf)
经过观看大佬的 writeup ,我知道了这里存在 http 走私漏洞,有关 http 走私漏洞可以查看这里;然后通过这个漏洞来绕过 waf ,修改请求方式为 POST,加上两个 Content-Length .
可以看到服务器返回的是 400 ,这说明我们已经绕过 waf 了,至于 flag 暂时先别管,那个命令是需要后面构造出来的。
这时可以考虑怎么去获取 flag 了,要想得到 flag ,肯要先知道它在哪里,所以需要先扫面目录,需要使用到 scandir这个函数,因为并没有过滤字母,所以上图用 base_convert 其实是多余的。
一般来说都是直接看根目录,所以要构造一个 '/' 出来,dechex() 函数可以把 10 进制转换为 16 进制,47 对应的十六进制是 0x2f ,而 hex2bin() 可以把 16 进制转换为 ASCII 码,对应的符号就是 '/',因此构造出的 payload 如下
num=var_dump(scandir(hex2bin(dechex(47))))
找到了 flag 文件,文件名是 f1agg,然后读文件
num=var_dump(readfile(hex2bin(2f).base_convert(25254448,10,36)))