前言
目前我們一般通過報錯和時間盲注來對update和insert語句進行SQL注入,下面我們來講解一種新的獲取數(shù)據(jù)的方法。
首先我們來看一個簡單的例子,假設應用會將username字段的結果會返回給我們:
1
$query?=?"UPDATE?users?SET?username?=?'$username'?WHERE?id?=?'$id';";
HTTP應用中的參數(shù)是這樣的:
1
username=test&id=16
我最近研究的帶內,帶外攻擊技巧剛好適用于這個場景,要理解我的技巧,我們可以先看下Mysql 是如何處理字符串的。在Mysql 中一個字符串等于 ‘0’,我們來看一下:

假如我們把字符串和數(shù)字相加,結果和0 加這個數(shù)字一樣:

Mysql的這個屬性給了我一些靈感,我們來看看BIGINT的最大值加上一個字符串會怎樣?

結果是 ‘1.8446744073709552e19’,這表明字符串實際上作為八字節(jié)的DOUBEL類型來處理。

將一個DOUBLE類型和大數(shù)字相加會返回IEEE格式的值,為了解決這個問題我們可以使用OR。

現(xiàn)在我們得到了最大的64bit無符號的BIGINT值0xffffffffffffffff。我們需要注意通過OR獲取數(shù)據(jù)時,這個值必須小于BIGINT(不能超過64bit)。
轉換字符串為數(shù)字
為了獲取數(shù)據(jù)我們可以將應用輸出的字段轉換為數(shù)字,然后再解碼回來,如下步驟:
1
String?->?Hexadecimal?->?Decimal

通過SQL,Python和Ruby等語言我們可以將數(shù)字轉回字符串,如下:
1
Decimal?->?Hexadecimal?->?String

如上面提到的,Mysql中的最大值為BIGINT,我們不能超過它,也就是說每次提取的字符串不能超過8位。

4702111234474983745可以被解碼為AAAAAAAA,如果再加一個A,我們就不能正確解碼了,因為返回的結果會是無符號的BIGINT值0xffffffffffffffff。

如果需要獲取的數(shù)據(jù)超過8個字節(jié),我們需要使用substr()方法來將數(shù)據(jù)分片。
1
select?conv(hex(substr(user(),1?+?(n-1)?*?8,?8?*?n)),?16,?10);
n的取值為1、2、3…比如我們要獲取的username長度超過8個字符,我們首先獲取前八個字符,然后繼續(xù)獲取后面的8個直到得到NULL。

最后我們把user()函數(shù)獲得的數(shù)據(jù)解碼。

注入技巧
獲取表名
1
select?conv(hex(substr((select?table_name?from?information_schema.tables?where?table_schema=schema()?limit?0,1),1?+?(n-1)?*?8,?8*n)),?16,?10);
獲取列名
1
select?conv(hex(substr((select?column_name?from?information_schema.columns?where?table_name=’Name?of?your?table’?limit?0,1),1?+?(n-1)?*?8,?8*n)),?16,?10);
利用UPDATE語句
下面我們通過一個例子來說明如何利用更新語句。

實際的查詢語句可能是這樣的:


利用INSERT語句
原始SQL語句如下:
1
insert?into?users?values?(17,'james',?'bond');
我們可以像update語句中一樣獲取數(shù)據(jù):
1
insert?into?users?values?(17,'james',?'bond'|conv(hex(substr(user(),1?+?(n-1)?*?8,?8*?n)),16,?10);
MySQL 5.7中的限制
你可能注意到這種方法在MySQL 5.7.5之后的版本并不奏效。

通過研究MySQL
5.7發(fā)現(xiàn)Mysql服務器默認運行在‘Strict SQL Mode’下,在MySQL
5.7.5里,默認的模式包含‘STRICT_TRANS_TABLES’。在 ‘Strict SQL Mode’
下我們不能將integer轉換為string。

為了解決這個問題,我們需要在注入時一直使用一個integer類型,這樣就不會有任何問題了。

另外任何用戶都可以在他的會話里關閉‘Strict Mode’。

如果想設置影響所有客戶端的全局屬性需要SUPER權限。

開發(fā)者也可以使用‘IGNORE’關鍵字來忽略‘Strict Mode’,如‘INSERT IGNORE’或者‘UPDATE IGNORE’。

解碼Decoding
SQL
1
select?unhex(conv(value,?10,?16));
Python
1
dec?=?lambda?x:("%x"%x).decode('hex')
Ruby
1
2dec?=?lambda?{?|x|?puts?x.to_s(16).scan(/../).map?{?|x|?x.hex.chr?}.join?}或
dec?=?lambda?{?|x|?puts?x.to_s(16).scan(/\w+/).pack("H*")?}