[HFCTF2021 Quals]Unsetme
我们来进行代码审阅
1 | <?php |
看题目我们真的用了f3框架,而f3框架3.7.1版本存在rce漏洞 CVE-2020-5203
但我们不能直接复原原漏洞,因为在/lib/CHANGELOG.md中发现他用的是3.7.2的版本
在原来rce的地方加上了正则匹配
关键代码在lib/base.php下
1 | function compile($str, $evaluate=TRUE) { |
compile是修改后加了函数的地方
1 | function __unset($key) { |
这里是执行RCE的地方,和3.7.1比没有修改
我们已知使用unset()销毁并不能销毁的变量时会调用__unset()方法,这里会把我们传入的参数赋值到$key,经过过滤后执行eval,可以发现eval处只是简单的字符串拼接,用分号闭合后就可以在后面构造代码进行RCE了
compile处最后返回的$str是@hive.xxxxx的形式主要看一下第二个正则
/\.([^.\[\]]+)|\[((?:[^\[\]\'"]*|(?R))*)\]/
这里匹配的是以
.
开始后面是字符串加[]
的形式或[]
包裹字符串的形式
我们尝试闭合unset
1 | ?a=a%0a);phpinfo( |
成功执行
那我们进行rce
1 | ?a=a[b]%0a);system("cat%20../../../flag" |
得到flag
补充
在外面构造payload时,我们发现?a=a);phpinfo(不可以,但?a=a%0a);phpinfo(可以
因为我们需要用%0a进行换行处理
1 | unset($f3->a);phpinfo(); |
如果不换行,就会导致php解释器将整行的字符当作unset的参数处理,导致语法错误