HFCTF2021Quals-Unsetme


HFCTF2021Quals-Unsetme

知识点概要:命令执行

首页

源码逻辑分析:

  1. 引入base.php启动框架,并将框架实例赋值给$f3。
  2. 设置框架的DEBUG模式为启用。
  3. 检查PCRE(Perl兼容正则表达式)的版本是否低于8.0,如果低于则抛出错误。
  4. 使用highlight_file()函数高亮显示当前文件内容。
  5. 获取GET参数a的值,赋值给$a
  6. 使用unset()删除框架实例$f3上的属性$a
  7. 运行框架。

下面还有三处报错,涉及两个文件:index.php和base.php,应该是一条控制流

FatFree框架:https://github.com/bcosca/fatfree

本地调试

1.下载官方源码(笔者调试版本是fatfree-3.7.3)

2.在源码根目录(即index.php同级目录),新建一个test.php,把题目源码复制进去

3.开启调试环境,浏览器访问test.php

因为可控参数为GET参数a,所以调试的时候重点关注此参数的流向

(1)什么参数都不传递的情况下

控制流会从test.php的12行unset()函数进入base.php的__unset()魔术方法

然后进入offsetunset()方法

进入clear()后,会一路执行到530行

执行eval('unset('.$val.');');时,跳转到2337行,执行完2338行,web端返回如题目首页的错误

(2)GET传参?a=1时,前面的控制流路线和无参时是一样的,只不过执行eval('unset('.$val.');');时,会跳转到如下位置

从上述分析可见,eval()函数是危险函数,又因为变量$val@hive拼接$key经过compile()方法处理得到,$key是从GET参数a一路传递过来的,可控,所以就有了执行命令的机会。关键在于compile()做了什么处理,跟踪关键代码如下

这段代码功能相当于把@hive string $a替换成$hive['string'],又由于$val变量赋值的最外层正则会将$hive替换为$this->hive,所以相当于传进GET参数a=string,得到$var=$this->hive['string']

可以在eval()之前添加echo调试一下:

echo '<br>'.$val.'<br>';
echo 'unset('.$val.');';

传参?a=test,结果如下

传参?a=test%0a);phpinfo(,结果如下

所以,读flag可用如下payload

?a=test%0a);echo file_get_contents(%27/flag%27
?a=test%0a);readfile(%27/flag%27
?a=test%0a);system(%27cat%20/flag%27

参考

https://www.plasf.cn/articles/hfctfunsetme.html

https://blog.csdn.net/Little_jcak/article/details/123516439


文章作者: wa0er
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 wa0er !
评论
  目录