MySQL利用ODBC跳脫({})注入手法分析

2020-09-19 16:00:58

前言

最近由於工作需要在看libinjection的原始碼,查到一位師傅發了一篇繞過libinjection的文章,

https://www.o2oxy.cn/2772.html

由於URL編碼和HEX編碼的問題,感覺這位師傅寫的不是很對,就發評論跟他討論,當然他整個libinjection的流程分析還是很不錯的。

討論了半天,這位師傅又丟擲了一個payload,說libinjection也檢測不出來

1={date(if(mid((updatexml(1,concat(0x7e,(select user()),0x7e),1)),1,1)='1',2,1))}

嘗試了一下的確如此:
在這裡插入圖片描述

翻看MySQL語法分析的產生式

很久之前看到過這種注入的手法,當時沒有深究,這次打算好好研究一下。

mysql的SQL解析語法檔案:

https://github.com/mysql/mysql-server/blob/8.0/sql/sql_yacc.yy

(這個是yacc的產生式檔案,有興趣的師傅可以去找找lex&yacc的資料,順便看看編譯原理更佳~)

PS:開頭註釋表明5.7之後語法分析就沒有變過

看這個檔案懵逼了很久,最後直接搜尋’{’(三個字元)找到了關鍵點:

在這裡插入圖片描述

'{' 標誌符 表示式 '}'是simple_expr(簡單表示式)的一種,走PTI_odbc_date這個類的解析方法

https://github.com/mysql/mysql-server/blob/8.0/sql/parse_tree_items.cc

通過註釋可以看出,該功能是為了解析ODBC的跳脫形式語法而寫的,並且最後如果標誌符部分不是dtts,就會直接返回表示式的內容。

在這裡插入圖片描述

實際上效果上來說,標誌符部分可以任意寫,表示式部分都可以正常執行

在這裡插入圖片描述

所以可以嘗試通過這種形式進行SQL隱碼攻擊防禦的繞過。

MySQL手冊相關

https://dev.mysql.com/doc/refman/8.0/en/expressions.html

https://downloads.mysql.com/docs/refman-4.1-en.a4.pdf

這塊感謝同事donky16師傅,實際上手冊中有寫這種用法,之前搜關鍵詞bracescurly brackets,就是沒搜curly braces。。。。:

在這裡插入圖片描述

上面那波分析,多少有點走彎路了。

從手冊中可以看出,從3.23開始就已經存在了ODBC跳脫語法。

回到Payload

1={date(if(mid((updatexml(1,concat(0x7e,(select user()),0x7e),1)),1,1)='1',2,1))}

payload中,date並不代表一個函數,而是一個識別符號, 後面整個括號包裹的if部分是表示式,並且可以不適用括號分割而,轉而使用空格之類的進行分割:

在這裡插入圖片描述
在這裡插入圖片描述

可以看到兩個效果是一樣的,都可以正常觸發報錯,說明updatexml函數已經被執行了。

但是後一種寫法是可以被libinjection檢測出來的:

在這裡插入圖片描述

而libinjection中實際上已經考慮了ODBC跳脫的情況:

在這裡插入圖片描述

原因分析

libinjection中有種token型別為bareword

bareword可能被認為:label 、 控制程式碼 、函數 、 普通字串

libinjection特定位置上只有非關鍵字列表(方法名、變數名、select union之類的關鍵字)才會被認為是bareword。

在libjection的token摺疊函數中,’{’+BAREWORD的組合會進行摺疊,而像’{date’這種形式會被解析成’{’+FUNCTION的Token串,不會被摺疊導致了繞過。

{foo expr}

而在ODBC跳脫語法的語境中,上述foo位置都會被認為是識別符號或者說bareword

所以此處解決辦法有兩個:

  1. 加特徵,將’{’+FUNCTION的情況包進去
  2. 優化摺疊程式碼,考慮’{’+FUNCTION的情況

最後選用了第二種方法進行完善,可以正常的檢測出來該SQL隱碼攻擊:

在這裡插入圖片描述

參照內容

libinjection原始碼(語意分析SQL隱碼攻擊檢測):

https://github.com/client9/libinjection

感謝這位師傅,漲知識了~:

https://www.o2oxy.cn/2772.html

MySQL原始碼:

https://github.com/mysql/mysql-server/

MySQL手冊:

https://dev.mysql.com/doc/refman/8.0/en/expressions.html