01 背景

NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。NoSQL(不仅仅是 SQL)是数据存储的一个流行趋势;它泛指依赖于不同存储机制的非关系型数据库,这些存储机制包括文档存储、键值对存储和图。

这些数据库的广泛应用是由现代大型应用推动起来的,比如 Facebook、Amazon 和 Twitter,它们需要把数据分布到许多的服务器上。

传统关系型数据库不满足这种扩展性需求,它们需要一个单独的数据库节点去执行同一事务的所有操作。在本文中,我们将分析 NoSQL 的威胁和技术

02 基础知识

Web 应用和服务通常使用 NoSQL 数据库去保存客户数据。

在MongoDB的FAQ里面有这样一段话:

"..with MongoDB we are not building queries from string , so traditional SQL injection attacks are not a problem."

意思是:使用MongoDB,我们不从字符串生成查询,因此传统的SQL注入攻击对此无效(老王自己翻译)

因此大多数的开发者以为这样就高枕无忧了。其实他们的说法并无错误。

传统的SQLi手段是不可行的。因为MongoDB所要求的输入形式是json的格式,

例如:find({'key1';'value1'})在实际的使用中(PHP环境下),一般是这样使用$collection->find(array('key'=> 'value'));对于习惯传统的SQL注入手段的我们来讲,这样的形式很难想到常规的方法去bypass也很难想到办法去构造payload,这种手段就像参数化的SQL语句一样很难注入。

想要找到真的漏洞成因和原理,了解最基础的MongoDB语法是必要的,下面做简略介绍:

条件操作符

$gt : >

$lt : <

$gte: >=

$lte: <=

$ne : !=、<>

$in : in

$nin: not in

$all: all

$or:or

$not: 反匹配(1.3.3及以上版本)

模糊查询用正则式:db.customer.find({'name': {'$regex':'.*s.*'} })

/**

* : 范围查询 { "age" : { "$gte" : 2 , "$lte" : 21}}

* : $ne { "age" : { "$ne" : 23}}

* : $lt { "age" : { "$lt" : 23}}

*/

03  NoSQL攻击途径

Web应用和服务通常使用NoSQL数据库去保存客户数据。

下图展示了一个典型的架构,在此NoSQL用于保存通过Web应用来存取的数据。通过一个驱动程序来进行这个数据库的访问,即一个存取协议包装器,它为多种编程语言编写的数据库客户端提供类库。

尽管该驱动程序自身可能不易受到攻击,但有时它们提供了不安全的API,当应用开发人员错误地使用它们时,就会给该应用引入漏洞了,这些漏洞会被人利用对数据库进行任意操作。

如图所示,攻击者可以伪造一个带有注入代码的Web访问请求,当数据库客户端或协议包装器进行处理时,将会执行预期的非法数据库操作。

图中典型Web应用架构。NoSQL用于保存通过Web应用来存取的数据。通过一个驱动程序来进行这个数据库的访问,即一个存取协议包装器,它为多种编程语言编写的数据库客户端提供类库。

尽管该驱动程序自身可能不易受到攻击,但有时它们提供了不安全的API,当应用开发人员错误地使用它们时,就会给该应用引入漏洞了。NoSQL相关的SQL攻击主要机制可以大致分为以下五类:

· 1.重言式。又称为永真式。此类攻击是在条件语句中注入代码,使生成的表达式判定结果永远为真,从而绕过认证或访问机制。例如,在本文中,我们将展示攻击者如何用$ne操作(不相等)的语法让他们无需相应的凭证即可非法进入系统。

· 2.联合查询。联合查询是一种众所周知的SQL注入技术,攻击者利用一个脆弱的参数去改变给定查询返回的数据集。联合查询最常用的用法是绕过认证页面获取数据。在本文中,我们将展示一个攻击示例,它将通过增加永真的表达式利用布尔OR运算符进行攻击,从而导致整个语句判定出错,进行非法的数据获取。

· 3.JavaScript注入。这是一种新的漏洞,由允许执行数据内容中JavaScript的NoSQL数据库引入的。JavaScript使在数据引擎进行复杂事务和查询成为可能。传递不干净的用户输入到这些查询中可以注入任意JavaScript代码,这会导致非法的数据获取或篡改。

· 4.背负式查询。在背负式查询中,攻击者通过利用转义特定字符(比如像回车和换行之类的结束符)插入由数据库额外执行的查询,这样就可以执行任意代码了。

· 5.跨域违规。HTTP REST APIs是NoSQL数据库中的一个流行模块,然而,它们引入了一类新的漏洞,它甚至能让攻击者从其他域攻击数据库。在跨域攻击中,攻击者利用合法用户和他们的网页浏览器执行有害的操作。在本文中,我们将展示此类跨站请求伪造(CSRF)攻击形式的违规行为,在此网站信任的用户浏览器将被利用在NoSQL数据库上执行非法操作。通过把HTML格式的代码注入到有漏洞的网站或者欺骗用户进入到攻击者自己的网站上,攻击者可以在目标数据库上执行post动作,从而破坏数据库。

04  威胁

举出几个例子:

//查询age = 22的记录db.userInfo.find({"age": 22});//相当于:select * from userInfo where age = 22;//查询age > 22的记录db.userInfo.find({age: {$gt: 22}});//相当于:select * from userInfo where age > 22;

我们发现,在find的参数里,age对应的value设置为数组(这个数组包含特殊的mongoDB特别定义的变量名作为操作符,变量名对应的value作为操作对象)将会起到条件查询的作用。

就PHP本身的性质而言,由于其松散的数组特性,导致如果我们输入value=A那么,也就是输入了一个value的值为1的数据。如果输入value[ne=>2),在MongoDB的角度来,很有可能从原来的一个单个目标的查询变成了条件查询($ne表示不等于-not equel):

从xxx.find({'key': 'A'})变成了xxx.find({'key':{$ne:'A'}})

显然这样已经出现了非常严重的安全问题。

JSON查询以及数据格式

尽管相对安全,但流行的JSON表述格式仍可受到新类型的注入攻击。我们将举例说明MongoDB中的此类攻击,MongoDB是一个面向文档的数据库,已经有多个大型供应商予以采用,其中包括eBay、Foursquare和LinkedIn。在MongoDB中,查询和数据以JSON格式描述,这在安全方面要优于SQL,因为它是更充分定义的,容易进行加密和解密,而且在每种编程语言中都有不错的原生实现。像SQL注入那样对查询结构的破坏,在JSON结构的查询中会更难实现。在MongoDB中常见的插入语句应该是这样的:

db.books.insert({ title: 'The Hobbit', author: 'J.R.R. Tolkien' })

这会插入一个新的文档到books的集合中,它具有title(标题)和author(作者)字段。常见的查询条件应该是这样的:

db.books.find({ title: 'The Hobbit' })

除限制要查询的字段之外,查询中还可以包括正则表达式和条件。

PHP重言式注入

让我们审视一下图中所画的架构,一个使用PHP实现后端的Web应用,它将用于查询数据存储的请求编码为JSON格式。让我们使用一个MongoDB示例去演示数组注入漏洞吧,从技术和结果上来看这是一个与SQL注入有些类似的攻击手段。

图中使用MongoDB的PHP应用。一个使用PHP实现后端的Web应用,它把用于查询数据存储的请求编码为JSON格式。PHP编码数组为原生JSON。嗯,数组示例如下:

array('title' => 'The Hobbit', 'author' => 'J.R.R. Tolkien');

将由PHP编码为以下JSON格式:

{"title": "The Hobbit", "author": "J.R.R. Tolkien"}

如果一个PHP具有登录机制,由用户浏览器通过HTTP POST(它像HTTP GET一样容易受到攻击)发送过来用户和密码,常见的POST URL编码应该是这样的:

username=Tolkien&password=hobbit

后端PHP代码针对该用户对它进行处理并查询MongoDB,如下所示:

db->logins->find(array("username"=>$_   POST["username"],   "password"=>$_POST["password"]));

这本身合情合理没什么问题,直觉上开发人员可能喜欢用以下查询:

db.logins.find({ username: 'tolkien', password: 'hobbit'})

然而,PHP针对关联数组有个内置的机制,这让攻击者有机可乘,可发送以下恶意的数据:

username[$ne]=1&password[$ne]=1

PHP会把该输入解析为:

array("username" => array("$[ne] " =>   1), "password" =>   array("$ne" => 1));,

它会编码为如下MongoDB查询:

db.logins.find({ username: {$ne:1 },   password {$ne: 1 })

因为$ne是MongoDB用来判定条件是否不相等的,所以它会查询登录集合中的所有用户名称不等于1且密码也不等于1的记录。因此,本次查询将返回登录集合中的所有用户。换成SQL的表述法,就等同于以下查询语句:

SELECT * FROM logins WHERE username <>   1 AND password <> 1

在这种情况下,漏洞就为攻击者提供了一个不必有效凭证即可登录应用的方式。在其他变体中,该漏洞可能会导致非法数据访问或由无特权的用户执行特权操作。为缓解这个问题,我们需要转换从需求中接收的参数为适当类型,在本例中,可使用字符串,如下所示:

db->logins->find(  array("username"=>(string)$_    POST["username"],  "password"=>(string)$_    POST["password"])); 

------------END--------------

加小唐老师微信领取

500元专属课程优惠券

+

 领取最新技术资料和面试题

你可能还想看软件测试到底在学什么(职业发展概览)面试中的工具问题 看这一篇就够了面试官:请你说说微信发红包,有哪些测试点MySQL学习笔记1-关系数据库概述

mongodb cond 模糊查询_NoSQL注入之MongoDB相关推荐

  1. mongodb cond 模糊查询_为了实现在线库的复杂查询,你还在双写吗?

    一.在线库不支持在线复杂查询 做在线业务的开发者经常会碰到这样的难题:在线数据库上面运行稍微复杂点的查询,在线业务就挂了!不管是单机数据库如MySQL.PG,还是分布式数据库,HBase.MongoD ...

  2. mongodb 之 模糊查询

    mongodb的模糊查询需要熟练掌握 正则匹配($regex),和全文检索($text),或者直接使用正则表达式. 一.mongodb中正则($regex)的用法: 1.{field:{$regex: ...

  3. mongodb java条件查询_java实现对mongodb,泛型封装增删查改、条件查询等操作

    本文实现一个通用泛型封装实现类,需要给定一个集合对象,类似mysql中与java对应的表:思想就是把给定的对象解析出所有非空字段,保存到一个BasicDBObject中,这里一定要保证java对象与m ...

  4. mongodb模糊查询 php7_详解php7如何实现MongoDB模糊查询

    php7如何实现MongoDB模糊查询?MongoDB模糊查询语句相信对大家来说都不陌生,本文主要给大家介绍了在php 7中MongoDB实现模糊查询的方法,文中给出了详细的介绍和示例代码,对大家具有 ...

  5. MongoDB 模糊查询包含/不包含字符串

    MongoTemplate模糊查询,spring boot MongoDB模糊查询 模糊查询 不包含 content  的记录 String content = "192.168.1.2&q ...

  6. php mongodb 子查询,MongoDB数组子查询elemMatch

    MongoDB数组子查询elemMatch 在 MongoDB数组子查询elemMatch详解 语法 db_name.collection_name.find({field:{$elemMatch:{ ...

  7. MongoDB文档查询操作(三)

    关于MongoDB中的查询,我们已经连着介绍了两篇文章了,本文我们来介绍另外一个查询概念游标. 本文是MongoDB系列的第七篇文章,了解前面的文章有助于更好的理解本文: 1.Linux上安装Mong ...

  8. spring boot 集成 mongodb 通过id查询问题

    spring boot 集成 mongodb 通过id查询问题 java 连接 mongodb 查询时通过id 查询不到数据,但其他字段是可以的,现在请各位大佬看看会是什么原因 通过id为参数查询 具 ...

  9. 关于解决MYSQL的like模糊查询效率的一种方案

    大家都知道like %suibin% 这种查询的效率极低,而MYSQL也建议不要这样模糊查询,常用的是把数据同步到CACHE里: 1.比如同步到ES里用ES模糊查询.或者同步数据到MongoDB实现模 ...

最新文章

  1. Django配置celery执行异步任务和定时任务
  2. redirect和forward
  3. 【译】使用Sovrin构建Android应用程序
  4. Linux中最方便的管理员获取方法
  5. APUE读书笔记-第15章-进程间通信
  6. ROS中使用Eigen库[不定期更新]
  7. html转换成keynote,keynote代码高亮【转】
  8. USB接口的键盘描述符范例
  9. MySql数据的启动和停止以及SQLyog图形化工具的下载
  10. 经典排序算法 - 耐心排序Patience Sorting
  11. 通用 字符串工具类
  12. 苹果蓝牙耳机怎么接电话_拆解报告:高仿苹果AirPods真无线蓝牙耳机
  13. SPSS数据分析之分类变量频率分析
  14. 移动政务中的小程序技术
  15. 填坑Go-“can‘t load package“
  16. 诚之和:谁在抢救瑞幸咖啡?
  17. 如何辅导孩子做学前班数学题?
  18. 牛顿?不不不,是牛逼顿
  19. Java学生签到考勤请假系统源码
  20. 如何修复无法打开的Excel文件,三大原因三大方法为你解决

热门文章

  1. 基于KPCA 和 STFT 非侵入式负荷监控(Matlab代码实现)
  2. FBX BlendShape/Morph动画解析
  3. 触目惊心!2017年化工行业事故203起死亡238人!附重大事件回顾
  4. ios 输入法扩展_iOS 11自带输入法新增3个小功能,贴心!
  5. 2.4G无线音频模块方案测评之RODE录音麦
  6. 电脑开始怎么设置计算机用户名,如何修改电脑登录用户名以及密码呢?5秒钟让你学会...
  7. 股市大跌对于IT行业的我们应该如何应对!2020年Android开发的未来发展方向该如何走?
  8. python数字转换_python数字转换为字符串的两种方式
  9. Excel2002制作自动记录考勤表(转)
  10. 为什么MacBook、MacOS的程序坞(dock栏docker栏)有些只有一条竖线有些两条