MongoDB操作&&注入漏洞&&未授权访问漏洞

Posted 安恒网络空间安全讲武堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB操作&&注入漏洞&&未授权访问漏洞相关的知识,希望对你有一定的参考价值。

注入不止有传统的SQL数据库,NoSQL型数据库也一样存在注入漏洞,在比赛中跟传统的注入相比也算新题型,不少同学可能还不太了解,本文向大家科普MongoDB数据库的常见操作以及攻击的方法——NoSQL注入和未授权访问


MongoDB简介

在 MongoDB中,没有 表、列的概念,取而代之的是 集合(collection)、文档(document)

  • 库(DB):

  • 数据库,包含多个集合

  • 集合(Collection):

  • 一组文档

  • 文档(Document):

  • 键值对的一个有序集,即有序的哈希表

MongoDB内置 javascript解释器,它的文档是 JS中的对象( {...}),就是那种没成员函数的对象

MongoDB默认运行于 27017端口

MongoDB以 BSON格式保存数据,即 BinaryJson


简单操作

CRUD操作

文档插入后会自动添加一个 _id属性,为唯一标识符 {"_id":ObjectId("56064886ade2f21f36b03134")}


Create

创建数据库

 
   
   
 
  1. > use [newdbname]        //不存在则会创建

创建collections

 
   
   
 
  1. db.createCollection()

创建集合

集合的 insert方法,插入单个文档

 
   
   
 
  1. db.collection.insert({

  2.    key1: value1,

  3.    ley2: value2

  4. })


Read

集合的 find方法,第一个参数是用来确定返回的文档,第二个参数确定返回的键值的过滤条件

 
   
   
 
  1. db.collection.find()    // 返回全部文档

  2. db.collection.find({"age": 20})        // 按条件查询

  3. db.collection.find({

  4.    "age": 20,

  5.    "name": "iv4n"

  6. })        // condition1 && condition2

查询条件

$lt $lte $gt $gte $ne
< <= > >= !=
 
   
   
 
  1. db.collection.find({

  2.    "age": {"$gt": 18, "$lt": 30}                  

  3. })            // 返回年龄18< <30

$in $nin $or $not $size
指定列表,成员可为不同类型 不在列表中 条件逻辑或 元操作符,可用于其余任何条件 大小
 
   
   
 
  1. db.collection.find({

  2.    "number": {"$in": [1, 2, 3]}

  3. })

  4. db.collection.find({

  5.    "$or": [{key1: value1}, {key2: value2}]                  

  6. })

  7. db.collection.find({

  8.    "$not": {"age": 20}                  

  9. })

  10. db.collection.find({

  11.    "name": {"$size": 4}                  

  12. })

null值

 
   
   
 
  1. db.collection.find({key1: null})        // 返回所有无key1键的文档

RegExp

 
   
   
 
  1. db.collection.find({"name": {"$regex": /^[a-z]{0,4}$/i}})        // 可加入正则flag位,如i忽略大小写

$slice,返回键中数组切片

 
   
   
 
  1. db.collection.find({},

  2.                  {"comments": {"$slice": 10}})        // 返回前十切片

  3. db.collection.find({},

  4.                  {"comments": {"$slice": 10}})        // 返回后十切片

  5. db.collection.find({},

  6.                  {"comments": {"$slice": [23, 10]}})        // 返回24~33切片,神奇的左开右闭

$where,危险语句,可执行任意 JS函数

 
   
   
 
  1. db.collection.find({"$where": function(){

  2.                   for (var i in this){

  3.                       for (var j in this){

  4.                           if (i!=j && this[i]==this[j])

  5.                               return true;

  6.                       }

  7.                   }

  8.                   return false;

  9.                   }})

本质其实就是传入一个返回值为 bool的匿名函数,对文档进行选择

Update

修改器

$inc,原子操作,并发安全

 
   
   
 
  1. db.collection.update({key: value}, {"$inc": {a: 1}})        //find操作后键值a会自增1

$set,存在则修改,不存在则创建,就像sql语句的 REPLACE一样

 
   
   
 
  1. db.collection.update({"_id": "xxxxxx"}, {"$set": {key: value}})

$unset,set的逆操作

$push,修改文档数组,因为 JavaScript的数组增删元素就是用 pushpop

$each,批量修改数组

 
   
   
 
  1. db.collection.update({}, {"$update": {key: {"$each": [val1, val2, val3]}}})

Delete

 
   
   
 
  1. db.collection.remove()        //删所有文档

  2. db.collection.remove({key: value})        //指定查询条件

  3. db.collection.drop()        //删集合

  4. db.dropDatabase()        删库


NoSQL注入

我将 MongoDB装在我的 Debian9虚拟机上,创建了以下内容:

 
   
   
 
  1. > use sqli

  2. switched to db sqli

  3. > db

  4. sqli

  5. > db.createCollection("users")

  6. { "ok" : 1 }

  7. > db.users.insert({"uname": "admin", "passwd": "admin"})

  8. WriteResult({ "nInserted" : 1 })

  9. > db.users.insert({"uname": "iv4n", "passwd": "iv4n"})

  10. WriteResult({ "nInserted" : 1 }

  11. > db.users.find()

  12. { "_id" : ObjectId("5ba3412314139eac63f891f7"), "uname" : "admin", "passwd" : "admin" }

  13. { "_id" : ObjectId("5ba3424114139eac63f891f8"), "uname" : "iv4n", "passwd" : "iv4n" }

以下是php代码,这里是PHP 7.x,和5.x的mongoDB库使用有差异:

 
   
   
 
  1. <?php

  2. // init mongoDB engine

  3. $server = new MongoDB\Driver\Manager("mongodb://localhost:27017");


  4. $uname = $_POST["uname"];

  5. $passwd = $_POST["passwd"];

  6. $filter = ["uname" => $uname,

  7.          "passwd" => $passwd,

  8. ];

  9. $option = [

  10.    "projection" => ["_id" => 0],

  11.    "sort" => ["_id"=> -1],

  12. ];


  13. $query = new MongoDB\Driver\Query($filter, $option);

  14. $cursor = $server->executeQuery("sqli.users", $query);

  15. foreach ($cursor as $doc){

  16.    if ($doc->passwd == $passwd){

  17.            echo "Login Successfully!<br>";

  18.            echo "username is: ".$doc->uname."<br>";

  19.            echo "password is: ".$doc->passwd."<br>";

  20.    } else {

  21.            echo "Invalid user and pass";                                                   }

  22. }

  23. ?>

index页面为一个post方法登录

这里的 filter为查询条件,语句为 db.users.find({"uname":$uname,"passwd":$passwd})

正常登录,用户名密码错误无回显

MongoDB操作&&注入漏洞&&未授权访问漏洞


$ne选择器注入,返回所有不等于的 document,传入数据库的语句实际是 db.users.find({"uname":{"$ne":"a"},"passwd":{"$ne":"a"}})

MongoDB操作&&注入漏洞&&未授权访问漏洞

可以看到,返回了数据库的全部信息


$lt/$gt注入:

前面说过,MongoDB内置的是Javascript的解释器,所以它在字符串的大小判断也遵循JS的逻辑

JS的字符串大小判断逻辑:按字节从左比较ascii码,假如相等则比较下一字节,不等则返回当前位的比较结果

MongoDB操作&&注入漏洞&&未授权访问漏洞

所以我们可以利用大小操作符来注入:

MongoDB操作&&注入漏洞&&未授权访问漏洞


正则注入:

$regex,传入数据库的语句实际为 db.users.find({"uname":{"$regex":"^a"},"passwd":{"$ne":"a"}})

MongoDB操作&&注入漏洞&&未授权访问漏洞

可以看到,返回了以a开头的用户信息,实际上它和SQL的正则盲注是一样的道理


上述的注入例子还相对更安全,PHP5版本的mongoDB库是允许代入查询字符串的,那样会导致更多的注入漏洞(就像SQL注入的闭合、注入,相信大家都比我懂,就不献丑了)


未授权访问

MongoDB最初安装部署后是不会添加auth选项的,一般的初始化步骤是:

  1. 不开启auth选项时连接数据库,添加管理员账户

  2. 开启auth,利用管理员账号登录连接,添加数据库账户

但是很多开发者并不知道这些Tips,没有开启auth选项,且数据库监听了公网,就导致了MongoDB的未授权访问

其实MongoDB的未授权访问和Redis数据库是差不多的,这里我们利用一个工具NoSQLMap来进行数据库信息枚举,有SQLMap那么也就有针对NoSQL数据库的NoSQLMap,它可以注入以及利用未授权访问漏洞

MongoDB操作&&注入漏洞&&未授权访问漏洞

我将数据库不开启auth启动,然后NoSQLMap的1选项设置想关信息

接着点击2选项,提示存在未授权访问漏洞

点击枚举数据库信息

这个工具目前来说还不是很完善,动不动就会直接exception退出,和SQLMap相比差距还是很大。更多的功能等待大家去探索


以上是关于MongoDB操作&&注入漏洞&&未授权访问漏洞的主要内容,如果未能解决你的问题,请参考以下文章

命令执行漏洞

web安全文件上传漏洞&代码函数&格式后缀&场景

joomla core注入漏洞

Nginx 配置错误导致漏洞 漏洞复现 (CRLF注入漏洞&目录穿越漏洞)

图创图书管理SQL注入漏洞

追洞小组 | ThinkPHP5 SQL注入漏洞&敏感信息泄露