最近参加了一次线下ctf比赛,水了一个二等奖,题目里面考了一个NoSQL的注入,这种数据库之前也没接触过,多亏了主办方给的提示。为了不辜负主办方的用心良苦,自己也下来专门研究了一下NoSQL,学过之后才发现题目考的内容真的很基础…十分羞愧…


NoSQL介绍:

NoSQL:是一项全新的数据库革命性运动,NoSQL的拥护者们提倡运用非关系型的数据存储。现今的计算机体系结构在数据存储方面要求具 备庞大的水平扩 展性,而NoSQL致力于改变这一现状。目前Google的 BigTable 和Amazon 的Dynamo使用的就是NoSQL型数据库。

随着web2.0的快速发展,非关系型、分布式数据存储得到了快速的发展,它们不保证关系数据的ACID特性。NoSQL概念在2009年被提了出来。NoSQL最常见的解释是“non-relational”,“Not Only SQL”也被很多人接受。(“NoSQL”一词最早于1998年被用于一个轻量级的关系数据库的名字。)

NoSQL被我们用得最多的当数key-value存储,当然还有其他的文档型的、列存储、图型数据库、xml数据库等。在NoSQL概念提出之前,这些数据库就被用于各种系统当中,但是却很少用于web互联网应用。比如cdb、qdbm、bdb数据库。

NOSQL的优势:

易扩展

NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。

大数据量,高性能

NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了。

灵活的数据模型

NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的web2.0时代尤其明显。

高可用

NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如Cassandra,HBase模型,通过复制模型也能实现高可用。

NoSQL相关的SQL攻击:

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

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

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

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

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

NoSQL MYSQL区别:

nosql的定义是not only sql,包括键值数据库,列式数据库,文本数据库,图形数据库等

mysql是一种传统的关系型数据库。 关系型数据库一般都可以通过sql语句进行操作。sql的语法一般遵循SQL99标准,也就是说上层的应用可以通过同样的sql语句访问不同的数据库。 而nosql对sql的支持并不像关系型数据库一样。以hbase为例,它本身并不支持sql,我们可以通过hbase shell进行操作,上层应用可以通过hbase API读写数据库。但是我们也可以通过hive(hive sql,类sql语法)来访问hbase。还有一些hbase skin(可以理解成hbase客户端),支持了部分sql语法以方便用户使用,比如pheonix。

Nosql注入案例:

使用SQL数据库存储用户名密码的系统,我们检测用户名与密码的过程可能是这样的:

我们使用MongoDB进行最简单的用户名与密码检测可能是这样的:

在最普通的SQL注入中,我们可以构造下面这样的请求:

这个请求会形成这样的SQL语句:

成功注入!

采用同理的方法,针对上面的MongoDB查询方式,你可以构造下面的请求:

这个请求会形成这样的MongoDB查询:

成功注入!

如上案例就是使用重言式,我们也主要介绍一下这种方法,因为这道ctf题就是考这个点

我们使用一个MongoDB示例去演示数组注入漏洞

MongoDB所要求的输入形式是json的格式,例如:

在实际的使用中(PHP环境下),一般是这样使用

对于习惯传统的SQL注入手段的我们来讲,这样的形式很难想到常规的方法去bypass也很难想到办法去构造payload,这种手段就像参数化的SQL语句一样很难注入。

想要找到真的漏洞成因和原理,了解最基础的MongoDB语法是必要的

条件操作符:

比如:

我们发现,在find的参数里,age对应的value设置为数组(这个数组包含特殊的mongoDB特别定义的变量名作为操作符,变量名对应的value作为操作对象)将会起到条件查询的作用。就PHP本身的性质而言,由于其松散的数组特性,导致如果我们输入value=A那么,也就是输入了一个value的值为1的数据。如果输入value[$ne]=2也就意味着value=array($ne=>2),在MongoDB的角度来,很有可能从原来的一个单个目标的查询变成了条件查询($ne表示不等于-not equel): 从

变成了

防御:可以通过函数is_array()将输入参数转变为字符串类型来解决。如:

接下来看一下比赛的题,当时忘截图题目了..不过无所谓..目测各位大佬都是秒杀..

image

ko image


参考资料:

http://www.infoq.com/cn/news/2011/01/nosql-why

https://www.cnblogs.com/wangyayun/p/6598166.html

http://www.freebuf.com/articles/database/95314.html