这里我用的是buuctf里面的[极客大挑战 2019]PHP 1。
这里我们看到题目,然后发现提示,他说有网站备份,我们知道备份文件一般是bak格式的,这里我用xshell连接kali,然后用kali去扫描网站目录。
这里dirsearch在kali不是自带的,要自己去下一条命令就可以下载好,然后自己学一下如何扫描,很简单。
进入目录之后输入网址
这里发现有非常多的目录
但是发现这个颜色不一样,事出反常必有妖,所以访问看看。
这里发现需要下载文件,然后我们把文件下载一下,看一下。
这里我们解压一下发现这里应该就是网站备份源码了。
首先我们分析一下,这里包含了一个类的文件,还有一个一个get传参,传过来的值进行反序列化。
这里解释一下反序列化,这里的反序列化就是把对象转换成字符串的形式,就是为了节省资源。
把上面的代码转换成为
O:4:“Test”:2:{s:10:“Testname”;s:3:“cat”;s:3:“age”;i:6;}
这里我们分成三段看
第一段
O:4:“Test”:2:
O表示:类型是对象,长度是4,后面Test是对象名。
第二段
s:10:“Testname”;s:3:“cat”;
s:10:“Testname”:s表示的是字符串,这里的Testname,因为对象名字是private的,表示私有变量,所以用类的名字后面跟着属性的名字,这里为什么s字符串长度是10呢,因为私有变量反序列化的时候是这样表示字符串的
%00类名%00属性名,这里就是%00Test%00name,这里%00表示的是0的意思,但是这里转换成字符串的时候省略了。s:3:"cat"这个就表示字符串长度为三,属性值是cat。
第三段
s:3:“age”;i:6;
这里表示字符串长度为3,属性名是age这里,因为是public所以字符长度就是三,这里的i表示数字的意思属性值是6。
这里通过传参数输出反序列化,这里我们用刚刚输出的反序列化语句为例
但是这里加了%00,加%00的意思就是因为是private,上面介绍过了,这里就不多说了。
O:4:“Test”:2:{s:10:"%00Test%00name";s:3:“cat”;s:3:“age”;i:6;}
这里看到我们已经把序列化输出来了。
这里我们看一下第二个例子,这里想测试的话可以把,return撤回掉,然后再试一下。
class Test{
public $name = "small z";
public $age =18;
public function __construct() //对象创建的时候调用此方法
{
echo "__construct run";
}
public function __destruct(){ //销毁对象是创建的方法
echo "__destruct run";
}
public function __sleep(){ //序列化对象的时候,调用此方法
echo "__sleep run";
return array("1","2"); //这里必须要一个返回值,才能在反序列化的时候调用。
}
public function __wakeup()//反序列化字符串的时候调用此方法.
{
echo "__wakeup run";
}
}
$obj =new Test();
$str = serialize($obj);
$obj1 = unserialize($str);
?>
这里执行一下代码
这里怎么执行的我就不多坐解释了。
想看解释去看视频,解释的详细点链接
接下来解释完就可以继续做题了,这里我们想看框里的代码
第一句是包含了class.php
第二句是提交一个post参数
第三句是一个反序列化的函数,把传过来的值反序列化一下。
接下来我们进入到class.php文件看一下,这里发现一个wakeup函数,因为我们前面进行了反序列化,所以这边就会调用wakeup函数,然后我们看下面的destruct函数,发现只要满足destruct函数就可以了。满足destrct就要让
username=admin
password=100
这里要构造一个反序列化,我们先在自己本地构建一个,因为太多符号,构造起来有一点麻烦。
这里先用这一句试一下,记得加上%00
O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
这里发现没有反应,然后通过修改name值来绕过,把2改成3,这里原理我也不清楚,但先这样用,这里我参照的大佬的wp链接
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}