【i春秋】 Web —— 爆破-1
0x00 前言
此题出自「百度杯」CTF 比赛 2017 二月场,是第一道 「爆破」系列的 Web 题,考察大家对 PHP 语言特性的熟练度,难度低,需要的基础知识有:PHP、正则表达式。
题目链接在「i春秋」的 CTF 大本营,解题链接通过创建在线靶场后得到:
0x01 爆破六位变量?
打开链接,直接看到一段 PHP 源码,是 PHP 代码审计出题的常规手法,只需提交正确的 payload,绕过代码中设置的限制即可:
1 |
|
由提示可知,flag 是藏在某六位变量中,有的同学一上来就跳进出题人挖的坑里,直接生成字典去爆破变量名。
不要着急,先看看代码第 4 行的变量名匹配规则,是通过正则表达式 /^\w*$/
完成的,其中:
^n
:匹配任何开头为n
的字符串。n$
:匹配任何结尾为n
的字符串。n*
:匹配任何包含零个或多个 n 的字符串。\w
:查找单词字符,包括大写字母A-Z
、小写字母a-z
、数字0-9
、下划线_
。
理解了匹配规则后,可推出以下两条线索:
- 在没有给任何提示的情况下,PHP 中满足正则表达式的六位变量共有 $53 \times 63^{5} = 52,599,136,779$ 种(变量首位不能为数字),每个变量占六字节,至少需要 $52,599,136,779 \times 6 = 315,594,820,674 \ B \approx 294 \ GB$ 的存储空间,用如此大的字典去爆破,普通计算机是无法承受的。
- 匹配字符串无限定长度,说明不一定非要提交六位变量。
入坑的朋友们,赶紧从坑里爬出来,转换一下思路吧!
0x02 超级全局变量 $GLOBALS
由第 3 行可知,通过 GET 请求或 POST 请求提交的 hello
参数,将其赋值给 PHP 变量 $a
,再到第 7 行的代码执行函数 eval()
中,由 var_dump()
函数变量的类型、值、结构等信息打印出来。
小贴士:
eval()
函数的执行顺序,是先将变量$a
解析得到字符串(设为xxx
),再与$
拼接,最后执行var_dump($xxx);
。详情可参考:玩转 PHP eval() 中的单双引号。
既然 flag 存放在某个变量中,这时我们应该想到超级全局变量 $GLOBALS
,它是一个包含了全局作用域中全部变量的关联数组,变量名即为数组的键值,注意变量名必须全部大写。
因此,只需构造 payload hello=GLOBALS
提交 GET 请求,即可获得 flag,同时也看到了传说中的某六位变量 $d3f0f8
。