MongoDB未授权访问漏洞记录(端口:27017,37017)
一、漏洞危害
對外開放的MongoDB服務,未配置訪問認證授權,無需認證連接數據庫后對數據庫進行任意操作(增、刪、改、查高危動作),存在嚴重的數據泄露風險。
二、漏洞成因
MongoDB服務安裝后,默認未開啟權限驗證。如果服務監聽在0.0.0.0,則可遠程無需授權訪問數據庫。
3.0之前版本的MongoDB,默認監聽在0.0.0.0,3.0及之后版本默認監聽在127.0.0.1。
3.0之前版本,如未添加用戶管理員賬號及數據庫賬號,使用--auth參數啟動時,在本地通過127.0.0.1仍可無需賬號密碼登陸訪問數據庫,遠程訪問則提示需認證;
3.0及之后版本,使用--auth參數啟動后,無賬號則本地和遠程均無任何數據庫訪問權限。
三、漏洞驗證
MongoDB存在未授權訪問漏洞時,使用MongoDB的高版本shell工具mongo(高版本兼容低版本)直接連接成功,執行show dbs命令,無報錯信息,列表存在默認庫local庫,則判斷存在未授權訪問(local庫即便刪除,重啟MongoDB后仍會生成)。
C:\ "C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe" 127.0.0.1> show dbs admin 0.000GB config 0.000GB local 0.000GB test 0.000GB部分版本默認不存在admin庫,但如果創建了用戶管理員賬號,這個庫一定存在,如果存在admin庫,可以進入該庫查看是否有用戶,有用戶則表示添加了用戶管理員賬號,但未使用--auth參數啟動。
> use admin switched to db admin > show users {"_id" : "admin.admin","user" : "admin","db" : "admin","roles" : [{"role" : "userAdminAnyDatabase","db" : "admin"}],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"] }也可以使用圖形化界面管理工具連接服務進行測試。
Robo 3T下載地址:https://robomongo.org/download,建議使用1.2.1版本,使用1.3及之后版本的話,服務端如果使用較低版本MongoDB,存在未授權訪問時仍無法連接。
四、整改建議
4.1. 方案1:本地監聽
如MongoDB只需在本地使用,建議只在本地開啟監聽服務,使用--bind_ip 127.0.0.1綁定監聽地址。
$ mongod --bind_ip 127.0.0.1 --dbpath /tmp/test或:在配置文件中指定監聽IP,Linux下默認配置文件為/etc/mongod.conf。
# network interfaces net:port: 27017bindIp: 127.0.0.1指定配置文件啟動
mongod --config /etc/mongod.conf3.0及之后版本的MongoDB,監聽服務默認在127.0.0.1開啟。
4.2. 方案2:限制訪問源
如果僅對內網服務器提供服務,建議禁止將MongoDB服務發布到互聯網上,并在主機上通過防火墻限制訪問源IP。
Linux主機,使用iptables進行限制:
iptables -A INPUT -s <ip-address> -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -d <ip-address> -p tcp --source-port 27017 -m state --state ESTABLISHED -j ACCEPT<ip-address>替換成需訪問MongoDB服務的IP;第一條規則允許外部應用訪問MongoDB默認服務端口27017,第二條規則允許MongoDB外出流量到達外部應用。Windows主機,可以通過圖形管理界面添加防火墻策略或使用netsh命令添加,參考文檔:https://docs.mongodb.com/manual/tutorial/configure-windows-netsh-firewall/
4.3. 方案3:啟動基于角色的登錄認證功能
MongoDB支持SCRAM、x.509證書認證等多種認證機制,SCRAM(Salted Challenge Response Authentication Mechanism)是3.x版本的默認認證機制,該機制通過用戶名、密碼驗證,基于用戶角色進行訪問控制。下面是添加賬號認證的方法:
MongoDB 3.0及以上版本啟動時添加--auth參數開啟認證訪問,此時若數據庫中無賬號,本地登錄則無權限進行任何操作,因此需要先以無認證的方式啟動服務并創建系統用戶管理員賬號。
1)以無訪問認證的方式啟動MongoDB
$ mongod --dbpath /data/db2)未開啟認證的環境下,登錄到數據庫
$ mongo --host 127.0.0.1 --port 27017 MongoDB shell version v4.0.8 connecting to: mongodb://127.0.0.1:27017/test?gssapiServiceName=mongodb3)創建系統用戶管理員創建一個用戶名為myUserAdmin,密碼為Passw0rd的系統用戶管理員賬號。
#切換到admin庫: > use admin switched to db admin#創建用戶 > db.createUser({user: "myUserAdmin",pwd: "Passw0rd",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]} )#創建成功后提示信息: Successfully added user: {"user" : "myUserAdmin","roles" : [{"role" : "userAdminAnyDatabase","db" : "admin"}] }說明:3.0之前版本使用db.addUser方法創建用戶。
4)重啟MongoDB服務,開啟訪問認證啟動時添加--auth參數
$ mongod --auth --port 27017 --dbpath /tmp/test或:在配置文件中添加以下內容,指定配置文件啟動服務:
#security: security:authorization: enabled指定配置文件啟動MongoDB
$ mongod --config /etc/mongod.conf5)使用系統用戶管理員賬號登錄
$ mongo --port 27017 -u "myUserAdmin" -p "Passw0rd" --authenticationDatabase "admin"也可以在連接MongoDB是不指定認證信息,連接成功后通過db.auth()方法進行認證:
> use admin switched to db admin > db.auth("myUserAdmin","Passw0rd") 1 #返回1,表示認證成功6)創建數據庫用戶創建完系統用戶管理員賬號并通過系統用戶管理員登陸后,對每個庫創建指定的用戶。下面以對products庫創建一個具有讀寫權限的用戶accountUser為例:
> use products > db.createUser({user: "accountUser",pwd: "password",roles: [ "readWrite", "dbAdmin" ]} )#用戶創建成功 Successfully added user: { "user" : "accountUser", "roles" : [ "readWrite", "dbAdmin" ] }7)使用數據庫用戶訪問指定庫
$ mongo --port 27017 -u "accountUser" -p "password" --authenticationDatabase "products"五、MongoDB安裝
5.1. Windows下安裝
MongoDB支持以下系統:
Windows 7/Server 2008 R2
Windows 8/2012 R2 and later
Windows 2012 Server和Windows 10需要安裝KB2999226用以提供C Runtime支持。
1. 下載安裝文件MongoDB Download Center操作系統(OS)選擇Windows 64-bit x64,然后點擊Download按鈕進行下載。
2. 安裝MongoDB雙擊下載好的MSI文件開始安裝,注意不要勾選“Install MongoDB as a Service”。
3. 啟動服務在C盤根目錄下創建一個目錄data,用于存放MongoDB數據文件。使用管理員權限開啟CMD窗口,執行以下命令:
"C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe" --bind_ip 0.0.0.0 --port 27017 --dbpath="c:\data"5.2. Ubuntu下安裝
1. 添加MongoDB GPG公鑰
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D42. 添加MongoDB軟件源需根據Ubuntu版本添加軟件源
Ubuntu 14.04 (Trusty)
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.listUbuntu 16.04 (Xenial)
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.listUbuntu 18.04 (Bionic)
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list3.?更新軟件包列表
sudo apt-get update4. 安裝MongoDB
sudo apt-get install -y mongodb-org1.啟動服務在/tmp目錄下創建一個文件夾,用于存放MongoDB數據庫文件(實際生產環境中根據需求指定MongoDB目錄路徑,嚴禁存放在/tmp目錄下)。執行以下命令啟動服務
mongod --bind_ip 0.0.0.0 --port 27017 --dbpath /tmp/mongodb_test六、各類工具檢測漏報原因分析
6.1. Python腳本檢測
網上流傳的各類Python檢測腳本,主要檢測方式是以下兩種:
1.一種檢測方式是使用Python的PyMongo庫,不使用賬號密碼連接MongoDB服務,連接成功則證明存在未授權訪問漏洞。由于PyMongo庫只支持MongoDB 2.6及之后版本,低版本MongoDB存在漏洞時無法發現。
2.另一種檢測方式是使用socket與MongoDB服務端口建立連接后發送數據庫查詢指令,返回的數據中,存在默認庫local,則表示數據庫查詢成功,存在未授權訪問漏洞。在1.9版本的MongoDB服務中,報錯信息中包含local字符,引起誤報。
6.2. Nmap腳本
Nmap的mongodb-brute腳本,先判斷是否開啟驗證,如果開啟驗證再判斷是否存在弱口令。腳本運行的條件是端口為27017或服務名稱為mongodb,由于Nmap端口檢測結果中的服務名稱是mongod,名稱不一致,腳本不運行,存在漏報。另外腳本執行過程中,腳本執行出錯,也會引起漏報。
該問題已向Nmap提交更新請求,檢測非默認端口的MongoDB服務。https://github.com/nmap/nmap/issues/1565
七、Python檢測腳本示例
def mongodb(self, ip):try:socket.setdefaulttimeout(timeout)s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((ip, 27017)) s.send('\x3F\x00\x00\x00\x7E\x00\x00\x00\x00\x00\x00\x00\xD4\x07\x00\x00\x04\x00\x00\x00\x61\x64\x6D\x69\x6E\x2E\x24\x63\x6D\x64\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x18\x00\x00\x00\x10\x6C\x69\x73\x74\x44\x61\x74\x61\x62\x61\x73\x65\x73\x00\x01\x00\x00\x00\x00')result = s.recv(1024)if 'local' in result and 'errmsg' not in result: #增加一個“errmsg”字符串判斷,避免1.9版本中的誤報。print(u'{}[+] {}:27017\tMongoDB存在未授權訪問{}'.format(G, ip, W))with open('weakpass.txt', 'a+') as f:f.write('{}\t27017\tMongoDB存在未授權訪問\n'.format(ip,))except Exception as e:passfinally:s.close()mongodb_check("192.168.1.10","27017")八、參考資料
賬號管理命令
修改用戶權限
db.updateUser("root", {roles:[{role:"readWriteAnyDatabase", db:"admin"}] })修改用戶密碼
db.changeUserPassword(“username","newPasswd")刪除用戶
db.changeUserPassword(“username","newPasswd")MongoDB內建角色:https://docs.mongodb.com/manual/core/security-built-in-roles/
認證相關官方文檔該整改建議中命令方法在4.0版本中測試通過,低版本的MongoDB中,命令或角色定義可能有所變化,整改過程中,建議根據實際使用版本,查詢MongoDB官方文檔。
總結
以上是生活随笔為你收集整理的MongoDB未授权访问漏洞记录(端口:27017,37017)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DirectX11 初探XMVECOTR
- 下一篇: C语言中输入输出fread和fwrite