在我們開始之前,先給大家介紹一下libinjection。libinjection是一個非常流行的開源項目【傳送門】,該項目由Signal Sciences公司的Nick Galbreath負責開發和維護。
在此之前,市場上絕大多數的WAF都是基于正則匹配(Regex)的,但是現在不一樣了,很多的WAF(防火墻)以及NGWAF(下一代防火墻)出于性能方面的考慮,都會選擇使用這個庫來代替常規的正則表達式。例如mod_security從2.7.4版本開始就支持libinjection(dectectSQLi-v2.7.4、detectXSS-v2.8.0)。
從技術角度來看,libinjection是一個基于C語言的SQLi詞法解析分析器,它可以通過對不同語句進行詞法分析和語法分析來實現對SQL語句以及HTML語句的解析。
但需要注意的是,某些情況下libinjection的效果可能并沒有正則表達式好。接下來我會告訴大家我為什么會這樣認為。
libinjection解析器的未知令牌(token)
函數令牌,這是找出未知令牌的一種最簡單的方法了。我們曾嘗試列出所有可能的SQL函數,但這不太可能實現,因為還有很多自定義函數存在。這是其中一個原因,而另一個原因是各種不同的SQL引擎(例如MariaDB、MySQL、SQLite和PostgreSQL等等)都有很多不同的內置SQL函數。
下面是一個簡單的例子:
?id=‘-sqlite_version() UNION SELECT password FROM users- -
libinjection解析器的未知語境(context)
括號語境
如果攻擊者想要進行拒絕服務(DoS)攻擊,并嘗試通過SQL注入來拿下你的數據庫,那么他可能會使用下面這種查詢語句:
?id=sleep(9999)
但是,這種嘗試是會被檢測到的,而安全防護產品也能夠有效地阻止這種攻擊。但是,下面這種情況卻是無法檢測到的:
?id=)-sleep(9999
因為libinjection并不能理解這種括號語境。
同樣的,在MySQL的文件寫入中我們也可以利用類似的技術。比如說下面這個語句,它在一般情況下都會被檢測到:
?id=1337 INTO OUTFILE ‘xxx’--
但是如果攻擊者換成下面這種形式或語境的話,就無法被檢測到了:
?id=1337) INTO OUTFILE ‘xxx’--
除了上面給出的這種情況之外,我們同樣可以在批量查詢語句或多層查詢語句中使用同樣的技巧。比如說下面這條語句,它是會被檢測到并且被阻止的:
?id=123;DROP TABLE users--
但是下面這條語句卻不會被發現,這樣一來,你的用戶表(users)就被攻擊者拿到手了:
?id=123);DROP TABLE users--
簡單的數據提取Payload樣例如下所示:
?id=) OR (SELECT password FROM users ...
注釋語境
在SQL語句的注釋中執行注入
*/UNION SELECT password FROM users--
總結
實際上,我們經常可以在SQL語句的注釋區域中發現可行的注入點。libinjection無法檢測注釋區域中的內容,因為它的SQL解析器根本就不支持這種語境。
正如大家在本文中看到的那樣,想要保護Web應用不受網絡攻擊其實是一件非常困難的事情,即便是我們對SQL注入攻擊已經有著足夠的了解了,但我們仍然不能保證SQLi不會發生在我們自己的服務器身上。無論你所使用的庫有多么的流行,無論這個庫有多么的高級,攻擊者永遠都會有新的方法來繞過它們。
|