現在的位置: 首頁 > 資料庫 > 正文

MongoDB怎麼樣默認安全設置?MongoDB中JavaScript怎麼執行與保護

2020年07月02日 資料庫 ⁄ 共 1549字 ⁄ 字型大小 評論關閉

在默認情況下,mongod是監聽在0.0.0.0之上的。而任何客戶端都可以直接連接27017,且沒有認證。好處是,開發人員或dba可以即時上手,不用擔心被一堆配置弄的心煩意亂。壞處是,顯而易見,如果你直接在公網伺服器上如此搭建MongoDB,那麼所有人都可以直接訪問並修改你的資料庫數據了。下面學步園小編來講解下MongoDB怎麼樣默認安全設置?MongoDB中JavaScript怎麼執行與保護?

MongoDB怎麼樣默認安全設置

在默認情況下,mongod是監聽在0.0.0.0之上的。而任何客戶端都可以直接連接27017,且沒有認證。好處是,開發人員或dba可以即時上手,不用擔心被一堆配置弄的心煩意亂。壞處是,顯而易見,如果你直接在公網伺服器上如此搭建MongoDB,那麼所有人都可以直接訪問並修改你的資料庫數據了。

默認情況下,mongod也是沒有管理員賬戶的。因此除非你在admin資料庫中使用db.addUser()命令添加了管理員帳號,且使用–auth參數啟動mongod,否則在資料庫中任何人都可以無需認證執行所有命令。包括delete和shutdown。

此外,mongod還會默認監聽28017埠,同樣是綁定所有ip。這是一個mongod自帶的web監控界面。從中可以獲取到資料庫當前連接、log、狀態、運行系統等信息。如果你開啟了–rest參數,甚至可以直接通過web界面查詢數據,執行mongod命令。

我試著花了一個晚上掃描了國內一個B段,國外一個B段。結果是國外開了78個MongoDB,而國內有60台。其中我隨意挑選了10台嘗試連接,而只有一台機器加了管理員賬戶做了認證,其他則全都是不設防的城市。可見其問題還是比較嚴重的。

其實MongoDB本身有非常詳細的安全配置準則,顯然他也是想到了,然而他是將安全的任務推給用戶去解決,這本身的策略就是偏向易用性的,對於安全性,則得靠邊站了。

用戶信息保存及認證過程

類似MySQL將系統用戶信息保存在mysql.user表。MongoDB也將系統用戶的username、pwd保存在admin.system.users集合中。其中pwd=md5(username+「:mongo:」+real_password)。這本身並沒有什麼問題。username和:mongo:相當於對原密碼加了一個salt值,即使攻擊者獲取了資料庫中保存的md5hash,也沒法簡單的從彩虹表中查出原始密碼。

我們再來看看MongoDB對客戶端的認證交互是如何實現的。mongoclient和server交互都是基於明文的,因此很容易被網路嗅探等方式抓取。這裡我們使用資料庫自帶的mongosniff,可以直接dump出客戶端和服務端的所有交互數據包:

[root@localhostbin]#./mongosniff--sourceNETlo

sniffing27017

...//省略開頭的數據包,直接看看認證流程。以下就是當用戶輸入db.auth(username,real_passwd)後發生的交互。

127.0.0.1:34142-->>127.0.0.1:27017admin.62bytesid:88

query:{getnonce:1.0}ntoreturn:-1ntoskip:0

127.0.0.1:27017<<--127.0.0.1:3414281bytesid:77-8 replyn:1cursorId:0 {nonce:"df97182fb47bd6d0",ok:1.0} 127.0.0.1:34142-->>127.0.0.1:27017admin.152bytesid:99

query:{authenticate:1.0,user:"admin",nonce:"df97182fb47bd6d0",key:"3d839522b547931057284b6e1cd3a567"}ntoreturn:-1ntoskip:0

127.0.0.1:27017<<--127.0.0.1:3414253bytesid:88-9 replyn:1cursorId:0 {ok:1.0} 第一步,client向server發送一個命令getnonce,向server申請一個隨機值nonce,server返回一個16位的nonce。這裡每次返回的值都不相同。 第二步,client將用戶輸入的明文密碼通過演算法生成一個key,即key=md5(nonce+username+md5(username+「:mongo:」+real_passwd)),並將之連同用戶名、nonce一起返回給server,server收到數據,首先比對nonce是否為上次生成的nonce,然後比對key==md5(nonce+username+pwd)。如果相同,則驗證通過。 由於至始至終沒有密碼hash在網路上傳輸,而是使用了類似挑戰的機制,且每一次nonce的值都不同,因此即使攻擊者截取到key的值,也沒用辦法通過重放攻擊通過認證。 然而當攻擊者獲取了資料庫中保存的pwdhash,則認證機制就不會起到作用了。即使攻擊者沒有破解出pwdhash對應的密碼原文。但是仍然可以通過發送md5(nonce+username+pwd)的方式直接通過server認證。這裡實際上server是將用戶的pwdhash當作了真正的密碼去驗證,並沒有基於原文密碼驗證。在這點上和我之前分析的mysql的認證機制其實沒什麼本質區別。當然或許這個也不算是認證機制的弱點,但是畢竟要獲取MongoDB的username和pwd的可能性會更大一些。 然而在Web的監控界面的認證中則有一些不同。當client來源不是localhost,這裡的用戶認證過程是基於HTTP401的。其過程與mongo認證大同小異。但是一個主要區別是:這裡的nonce並沒有隨機化,而是每次都是默認為」abc」。 利用這個特點,如果攻擊者抓取了管理員一次成功的登錄,那麼他就可以重放這個數據包,直接進入Web監控頁面。 同樣,攻擊者還可以通過此介面直接暴力破解mongo的用戶名密碼。實際上27017和28017都沒有對密碼猜解做限制,但Web由於無需每次獲取nonce,因此將會更為簡便。 MongoDB中JavaScript怎麼執行與保護 MongoDB本身最大的特點之一,就是他是使用JavaScript語言作為命令驅動的。黑客會比較關注這一點,因為其命令的支持程度,就是獲取MongoDB許可權之後是否能進一步滲透的關鍵。 JavaScript本身的標準庫其實相當弱。無論是spidermonkey或者是v8引擎,其實都沒有系統操作、文件操作相關的支持。對此,MongoDB做了一定的擴展。可以看到,ls/cat/cd/hostname甚至runProgram都已經在JavaScript的上下文中有實現。看到這裡是不是已經迫不及待了?mongoshell中試一下輸入ls(「./」),看看返回。 等等?結果怎麼這麼熟悉?哈哈,沒錯,其實這些api都是在client的上下文中實現的。一個小小玩笑。 那麼在server端是否可以執行js呢?答案是肯定的。利用db.eval(code)——實際上底層執行的是db.$cmd.findOne({$eval:code})——可以在server端執行我們的js代碼。 當然在server端也有js的上下文擴展。顯然mongod考慮到了安全問題(也可能是其他原因),因此在這裡並沒有提供client中這麼強大的功能。當然MongoDB還在不斷更新,長期關注這個list,說不定以後就有類似load_file/exec之類的實現。 一勞永逸解決服務端js執行帶來的問題可以使用noscripting參數。直接禁止server-side的js代碼執行功能。 以上就是關於「MongoDB怎麼樣默認安全設置?MongoDB中JavaScript怎麼執行與保護」的內容,希望對大家有用。更多資訊請關注學步園。學步園,您學習IT技術的優質平台!

抱歉!評論已關閉.