王哥带我学反序列化漏洞[1]
  • 2020-06-18


0X01

遇到个题目代码如下

移植主题导致代码丢失OVO

首先 这种题一看就知道是反序列化的题型,我们来逐一分析代码,毕竟北哥我是写php后端出生的,看懂这些还是可以的

0x02

这里定义了一个flag类并且有一个属性$cmd还有一个php反序列化后会自动执行的__destruct方法

关键点在于

eval('$a="'.$this->cmd.'";');

这里就是命令执行的关键了,假定我们自己序列化了一个对象,$cmd里写入命令fuckyou 会被拼接成$a="fuckyou";

而eval后运行没什么卵用 仅仅是$a被赋值成了我们的$cmd属性值

参考eval函数,当内容里用分号分割时可以多条命令同时执行

所以我们传入的属性值需要闭合$a="这里的命令  也就是输入";我们要写的命令

后面同理 闭合之后的";可以写成";我们要写入的命令;$b="

这样 eval函数里的参数会变成eval($a="";我们要写入的命令;$b="");

这样当eval函数执行的时候就会同时运行  $a=""     我们写入的命令   $b=""了!

0x03

所以本题的解题思路是  传递一个flag对象的序列化内容 cmd属性值写入上面那个payload然后让__destruct函数执行即可

然后看主体部分 

if (!isset($_GET['fl']) || !isset($_GET['ag'])) {
  die(@highlight_file('index.php',true));
}
else {
if (!(preg_match('/[A-Za-z0-9]+(/i', $_GET['fl']))) {
   die('hack!!!');
}
else{
     echo unserialize($_GET['ag']);
 }
}

这里如果没有赋值fl和ag的get参数就会代码高亮显示

如果赋值了进入else   正则匹配fl参数  如果fl参数内容不包括A-za-z0-9这些数字字母和(左括号,程序停止

如果匹配了就反序列化ag参数的内容

所以我们需要给定一个fl参数的内容为A(即可

也就是 ?fl=A(&ag=序列化后的对象

0x04

序列化的对象怎么构造,这里又需要看到一处 

if (preg_match('/w+((?R)?)/', $this->cmd))

这里会递归匹配$cmd属性内()中的内容,需要让$cmd属性值内无参数

这是构造序列化对象的步骤,这里需要加一个array(),原因是题目中是直接echo出来内容的

但是phpecho对象会直接500错误 放到数组里就可以

5eeb0820997f9.png

5eeb0851a53d8.png

成功执行了phpinfo

0x05

但是执行了phpinfo有什么用呢,最终目的是获取flag.php中的内容

但是又必须要使得我们输入命令的那一块无参数

phpinfo中可以发现 是apache2.0的服务器web引擎

参考:

http://docs.php.net/manual/tw/function.getallheaders.php

5eeb093db18a5.png


所以可以新建一个序列化对象 

带有getallheaders()函数 ,获取所有headers头部放入数组,然后通过end函数获取数组的最后一个值,在通过system函数执行即可


5eeb0a52014bf.png

这里end获取头部的数组最后一个键值对后,拿到了ls这个值并system执行,成功列出目录,然后cat flag就能拿到flag了

5eeb0a828376e.png