1. 程式人生 > >【SQL注入技巧拓展】————12、MongoDB安全 – PHP注入檢測

【SQL注入技巧拓展】————12、MongoDB安全 – PHP注入檢測

什麼是MongoDB

MongoDB 是一個基於分散式檔案儲存的資料庫。MongoDB是個開源的NoSql資料庫,其通過類似於JSON格式的資料儲存,這使得它的結構就變得非常自由。通過MongoDB的查詢語句就可以查詢具體內容。

為什麼使用MongoDB

其實大部分原因只是因為MongoDB可以快速查找出結果,它大概可以達到10億/秒。當然MongoDB很流行的另外一個原因是在很多應用場景下,關係型資料庫是不適合的。例如,使用到非結構化,半自動化和多種狀態的資料的應用,或者對資料可擴充套件性要求高的。

我們正在為開源專案提供免費測試,如果你想測試下你的開源程式,請點選

這裡

案例分析

第一個例子,我們有一個PHP頁面。主要實現通過變數id獲取到該id的username和password:

從程式碼可以知道,資料庫名是security,集合名是users。u_id 是通過GET請求傳到後臺,然後傳入一個數組變數中。然後進入MongoDB的查詢。我們試試通過陣列傳入運算子號。

返回了資料庫中的所有內容。看看我們傳入的資料:

http://localhost/mongo/show.php?u_id[$ne]=2

傳入後的MongoDB查詢語句如下:

$qry= array(“id” => array(“$ne” => 2))

這樣MongoDB就返回了除了id=2的其他所有資料。

讓我們看看另一種情況,通過指令碼實現同樣的功能。不同的是,我們在後臺用MongoDB中的findOne來查詢結果。

我們先來快速看下MongoDB中的findOne方法:

db.collection.findOne(query, projection)

返回了所有滿足查詢條件的文件中的第一個文件。當我們想要查詢id=2的文件,輸入以下語句:

我們看下程式碼:

這裡的關鍵就是破壞原有的查詢語句,再重新執行一個查詢語句。

能想象以下請求會在MongoDB中執行怎樣的操作嗎?

http://localhost/mongo/inject.php?u_name=dummy’});return{something:1,something:2}}//&u_pass=dummy

我們將原有的查詢閉合,然後返回了一個想要的引數:

注意報錯資訊中的username和password這兩個欄位,那麼我們就把剛剛的注入語句改上username和password 引數。如下

在MongoDB中,db.getName()方法可以查到資料庫的名字,我們可以構造如下引數:

mangodb中通過db.getCollectionNames()就能知道資料庫中用的使用者:

目前為止我們得到了資料庫名和集合名。現在需要做的就是獲取到users集合中的資料,可以構造如下語句:

我們可以用過改變引數來遍歷整個資料庫,例如改成 db.users.find()[2]:

防禦

第一個例子中的遍歷是傳遞給一個數組的(array)。防禦這種注入的話,我們總得先防止陣列中的運算操作。因此,其中一種防禦方法就是implode()方法:

implode()函式返回由陣列元素組合成的字串。這樣的話,我們就只能得到一個對應的結果。

第二個例子可以使用addslashes()函式,這樣的話攻擊者就不能破壞查詢語句了。同時,用正則表示式把一些特殊符號替換掉也是一個不錯的選擇。你可以使用如下正則:

$ u_name =的preg_replace('/ [^ A-Z0-9] / I','\',$ _GET ['u_name']);

再嘗試就沒有報錯資訊了:

參考

 

轉自:http://www.mottoin.com/article/web/94341.html