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($this) as $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(1, 10000)); } public function getFlag() { $this->token_flag = md5(rand(1, 10000)); if ($this->token === $this->token_flag) { if (isset($this->file)) { echo @highlight_file($this->file, true); } } } a ?>
|
hint.php
这道题的重点不是其中的反序列化,而是其中parse_url与md5的绕过方法
分析hint源码发现,我们需要将Handle类中的handle属性赋值为Flag类以调用getFlag()函数,
但单单这样构造序列化之后,传入的payload中肯定含有“flag”这一字符串,会因index.php源码中的遍历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);
|
最后更新时间: