说明
打强网杯的时候一直在写论文, 做林逸师傅的培训题目。 现在得空,还是看了一部分的题目和wp。
源码
源码一共三部分, 这里只写下我知识盲区的一部分,作为自己的记录。
<?php
highlight_file(__FILE__);
$flag=file_get_contents('ssrf.php');
class Pass
{
function read()
{
ob_start();
global $result;
print $result;
}
}
class User
{
public $age,$sex,$num;
function __destruct()
{
$student=$this->age;
$body=$this->sex;
$a=$this->num;
$student->$body();
if(!(is_string($a)) || !(is_string($body)) || !(is_object($student)) )
{
ob_end_clean();
exit();
}
globa $$a;
$result=$GLOOBALS[‘flag’];
ob_end_clean();
}
}
if(isset($_GET['x']))
{
unserialize($_GET['x'])->get_it();
}
解析
上面的源码只会运行最后4行,而最后四行会调用上面的类。所以容易产生反序列化漏洞。
1、需要想办法输出$result.
因为以前无论做PHP开发还是审计的时候,都很少碰缓存相关的东西。这里直接把我难住了, 因为。ob_start()之后的所有数据都会进入缓存,不再打印。
虽然下面也有print $result。但是实际上是存在服务器缓存中,无法打印出来的。
盲区1:启用缓存之后,当代码抛出异常之后缓存内容显示运行结果。
方法:使用传入序列化的时候让Num的值等于result覆盖掉原来的result值。再设置$this->um='this'即可。
第二部分。在摧毁序列化内容的时候,出现变量覆盖漏洞$$a,这个由a的值this可以直接控制报错,原来的$$a变成了$this。即上面的num->this的传值
那么就很明确第一部分,和第二部的作用了。
第一部分,设置$$a
第二部分,反序列化。
那么考点就是,php启用缓存之后PHP报错原理以及利用方式。
payload
算了, 没有。自己去网上找, 一大把。