Web Hacking 101 中文版 十一、SQL 注入

十一、SQL 注入

作者:Peter Yaworski

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

描述

SQL 注入,或者 SQLi 允許黑客將 SQL 語句注入到目標(biāo)中并訪問它們的數(shù)據(jù)庫。它的潛力是無窮的,通常使其成為高回報(bào)的漏洞,例如,攻擊者能夠執(zhí)行所有或一些 CURD 操作(創(chuàng)建、讀取、更新、刪除)來獲取數(shù)據(jù)庫信息。攻擊者甚至能夠完成遠(yuǎn)程命令執(zhí)行。

SQLi 攻擊通常是未轉(zhuǎn)義輸入的結(jié)果,輸入被傳給站點(diǎn),并用作數(shù)據(jù)庫查詢的一部分。它的一個(gè)例子是:

$name = $_GET['name']; 
$query = "SELECT * FROM users WHERE name = $name";

這里,來自用戶輸入的傳入值直接被插入到了數(shù)據(jù)庫查詢中。如果用戶輸入了test' or 1=1,查詢就會(huì)返回第一條記錄,其中name = test or 1=1,所以為第一行?,F(xiàn)在在其他情況下,你可能會(huì)得到:

$query = "SELECT * FROM users WHERE (name = $name AND password = 12345");

這里,如果你使用了相同的載荷,你的語句最后會(huì)變成:

$query = "SELECT * FROM users WHERE (name = 'test' OR 1=1 AND password = 12345");

所以這里,查詢會(huì)表現(xiàn)得有些不同(至少是 MySQL)。我們會(huì)獲取所有記錄,其中名稱是test,或者密碼是12345。很顯然我們沒有完成搜索數(shù)據(jù)庫第一條記錄的目標(biāo)。因此,我們需要忽略密碼參數(shù),并能夠使用注釋來實(shí)現(xiàn),test' or 1=1;--。這里,我們所做的事情,就是添加一個(gè)分號(hào)來合理結(jié)束 SQL 語句,并且立即添加兩個(gè)短橫線(和一個(gè)空格)來把后面的所有東西標(biāo)記為注釋。因此不會(huì)被求職。它的結(jié)果會(huì)和我們初始的例子一樣。

示例

1. Drupal SQL 注入

難度:中

URL:任意版本小于 7.32 的 Drupal 站點(diǎn)

報(bào)告鏈接;https://hackerone.com/reports/31756

報(bào)告日期:2014.10.17

獎(jiǎng)金:$3000

描述:

Drupal 是一個(gè)流行的內(nèi)容管理系統(tǒng),用于構(gòu)建網(wǎng)站,非常相思雨 WordPress 和 Joomla。它以 PHP 編寫,并且基于模塊,意思是新的功能可以通過安裝模塊來添加到 Drupal 站點(diǎn)中。Drupal 社區(qū)已經(jīng)編寫了上千個(gè),并且使他們可免費(fèi)獲取。其中的例子包括電子商務(wù),三方繼承,內(nèi)容產(chǎn)品,以及其他。但是,每個(gè) Drupal 的安裝都包含想用的核心模塊系列,用于運(yùn)行平臺(tái),并且需要數(shù)據(jù)庫的鏈接。這些通常都以 Drupal 核心來指代。

在 2014 年,Drupal 安全小組為 Drupal 核心發(fā)布了一個(gè)緊急安全更新,表明所有 Drupal 站點(diǎn)都存在 SQL 注入漏洞,它能夠由匿名用戶來完成。這一漏洞允許攻擊者控制任意沒有更新的 Drupal 站點(diǎn)。

對(duì)于漏洞來說, Stefan Horst 發(fā)現(xiàn)了 Drupal 開發(fā)者不當(dāng)實(shí)現(xiàn)了數(shù)據(jù)庫查詢的包裝功能,它能夠被攻擊者濫用。更具體來說,Drupal 使用 PHP 數(shù)據(jù)對(duì)象(PDO)作為結(jié)構(gòu)用于訪問數(shù)據(jù)庫。Drupal 核心的開發(fā)者編寫了代碼來調(diào)用這些 PDO 函數(shù),并且在其他開發(fā)者編寫代碼來和 Drupal 數(shù)據(jù)庫交互的任何時(shí)候,這些代碼都可以使用。這在軟件開發(fā)中是個(gè)最佳時(shí)間。它的原因是為了讓 Drupal 能夠用于不同類型的數(shù)據(jù)庫(MySQL、Postgres,一起其它),移除復(fù)雜性并提供標(biāo)準(zhǔn)化。

現(xiàn)在結(jié)果是,Stefan 發(fā)現(xiàn)了 Drupal 包裝器代碼對(duì)傳給 SQL 查詢的數(shù)組數(shù)據(jù)做了一個(gè)錯(cuò)誤的假設(shè)。這里是原始代碼:

foreach ($data as $i => $value) { 
    [...] 
    $new_keys[$key . '_' . $i] = $value; 
}

你能夠之處錯(cuò)誤(我都不能)嘛?開發(fā)者的假設(shè)為,數(shù)組數(shù)據(jù)始終含有數(shù)字鍵,例如0, 1, 2以及其他($i的值)。并且所以它們將$key變量連接到$i,并且使其等于value。這里是來自 Drupal 的db_query函數(shù),通常的查詢的樣子。

db_query("SELECT * FROM {users} WHERE name IN (:name)", array(':name'=>array('user1','user2')));

這里,db_query函數(shù)接受數(shù)據(jù)庫查詢SELECT * FROM {users} WHERE name IN (:name),以及值的數(shù)組來替換查詢中的占位符。在 PHP 中,當(dāng)你將數(shù)組聲明為array('value','value2',value3'),它實(shí)際上創(chuàng)建了[0 =>'value',1=>'value2',2=>'value3'],其中每個(gè)值都可以通過數(shù)字鍵來訪問。所以這里,:name變量被數(shù)組中的值替換。你從中獲取到的東西是:

SELECT * FROM users WHERE name IN (:name_0, :name_1)

到目前為止很好。當(dāng)你獲取不含有數(shù)字鍵的數(shù)組時(shí),問題就來了,像這樣:

db_query("SELECT * FROM {users} where name IN (:name)", 
array(':name'=>array('test) -- ' => 'user1','test' => 'user2')));

這里,:name是個(gè)數(shù)組,它的鍵是'test) –', 'test'。你可以看到為什么嘛?當(dāng) Drupal 收到它并且處理數(shù)組來創(chuàng)建查詢時(shí),我們會(huì)得到:

SELECT * FROM users WHERE name IN (:name_test) -- , :name_test)

看出這是為什么可能需要一些技巧,所以讓我們過一遍它?;谏厦婷枋龅?code>foreach,Drupal 會(huì)遍歷數(shù)組中的每個(gè)元素。所以,對(duì)于第一個(gè)迭代$i = test) –以及$value = user1。現(xiàn)在,$key是查詢中的(:name),并且和$i組合之后,我們得到了name_test) –。對(duì)于第二個(gè)迭代,$i = test并且$value = user2,所以組合$key$i之后,我們得到了name_test,結(jié)果是個(gè):name_test的占位符,它等于user2。

現(xiàn)在,知道這些之后,Drupal 包裝 PHP PDO 對(duì)象的事實(shí)就登場了,因?yàn)?PDO 允許多重查詢。所以,攻擊者能夠傳遞惡意輸入,例如實(shí)際的 SQL 查詢來為任何的數(shù)組鍵創(chuàng)建管理員用戶,它作為多重查詢解釋和執(zhí)行。

重要結(jié)論

SQLi 似乎更難于發(fā)現(xiàn),至少基于為了這本書搜索的報(bào)告。這個(gè)例子很有意思,因?yàn)樗⒉皇翘峤粏我?hào)和截?cái)嗖樵?。反之,它全部關(guān)于 Drupal 的代碼如何處理傳給內(nèi)部函數(shù)的數(shù)組。這并不易于通過黑盒測試發(fā)現(xiàn)(其中你并不接觸任何代碼)。這里的重要結(jié)論是,尋找機(jī)會(huì)來修改傳給站點(diǎn)的輸入格式,所以在 URL 接受?name作為參數(shù)的地方,嘗試傳入類似?name[]的數(shù)組,來觀察站點(diǎn)如何處理。它也可能不會(huì)造成 SQLi,但是可能會(huì)導(dǎo)致其他有趣的行為。

總結(jié)

SQLi 對(duì)站點(diǎn)來說十分重要和危險(xiǎn)。尋找這一類型的漏洞可能導(dǎo)致站點(diǎn)的完整的 CURD 權(quán)限。在其他情況下,它可能擴(kuò)展為遠(yuǎn)程代碼執(zhí)行。Drupal 的例子實(shí)際上是這些例子之一,它們證明了攻擊者可以通過漏洞來執(zhí)行代碼。在尋找它們的時(shí)候,不要僅僅留意向查詢傳遞未轉(zhuǎn)義單引號(hào)和雙引號(hào)的可能性,也要注意以非預(yù)期方式提供數(shù)據(jù)的可能性,例如在 POST 數(shù)據(jù)中提交數(shù)組參數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容