摘自:http://www.infoq.com/cn/articles/nosql-injections-analysis

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”]));

NoSQL联合查询注入

SQL注入漏洞经常是由于未对用户输入进行适当编码而直接拼接查询造成的。在MongoDB之类的流行数据存储中,JSON查询结构使攻击变得更难了。然而,这并不代表不可能。

让我们看一个通过HTTP POST发送用户名和密码参数到后端的登录表单,它通过拼接字符串的方式得到查询语句。例如,开发人员可能会这么做:

string query = “{ username: ‘” + post_   username + “’, password:   ‘” + post_passport + ‘ “ }”

具有有效输入时,得到的查询语句是应该这样的:

{ username: ‘tolkien’, password:    ‘hobbit’ }

但具有恶意输入时,这个查询语句会被转换为忽略密码的,在无需密码的情况下登录用户账号。恶意输入示例如下:

username=tolkien’, $or: [ {}, {‘a’:   ‘a&password=’ }],
$comment: ‘successful MongoDB injection’

该输入会被构建到该查询中:

{ username: ‘tolkien’, $or: [ {}, {   ‘a’: ‘a’, password ‘’ } ], $comment: ‘successful MongoDB   injection’ }

只要用户名是正确的,这个查询就可以成功。转换成SQL的表述,这个查询类似于以下语句:

SELECT * FROM logins WHERE username =    ‘tolkien’ AND (TRUE OR (‘a’=’a’ AND password = ‘’))    #successful MongoDB injection

密码成为这个查询多余的一部分,因为()内的条件总为真,所以不会影响到查询的最终结果。

这是怎么发生的呢?以下为拼接出的查询串,用户输入为加粗字体,剩余的文本串为无格式字体:

{ username: ‘tolkien’, $or: [ {}, {    ‘a’: ‘a’, password ‘’ } ], $comment: ‘successful MongoDB    injection’ }

这个攻击在任何只要用户名正确的情况下都将成功,一般得到个用户名并不是什么难事。

NoSQL JavaScript注入

$map = “function() { for (var i = 0; i < this.items.length;   i++) { emit(this.name, this.items[i].$param);    } }”; $reduce = “function(name, sum) {    return Array.sum(sum); }”; $opt = “{ out: ‘totals’ }”; $db->execute(“db.stores.   mapReduce($map, $reduce, $opt);”);

这段代码把每个条目按名称给定的$param合计起来。当时,$param预期是接收数量(amount)或价格(price)的,这段代码将按预期进行运转。但是,因为用户输入未被转义,所以恶意输入(它可能包含任意JavaScript)将被执行。

看一下如下输入:

a);}},function(kv) { return 1; }, {    out: ‘x’ });db.injection. insert({success:1});return 1;db.stores.mapReduce(function() { {    emit(1,1

第一部分的数据会闭合最初的MapReduce函数,然后攻击者就可以在数据库上执行想要的JavaScript了(加粗部分)。最终,最后一部分调用一个新的MapReduce以保持被注入代码的原始语句的平衡。在把会被执行的用户输入合并到为字符串后,我们得到以下代码(注入的用户输入加粗显示):

db.stores.mapReduce(function() { for (var i = 0; i < this.items.length;   i++) { emit(this.name, this.items[i].a); } },function(kv) { return 1; }, { out:   ‘x’ }); db.injection.insert({success:1}); return 1;db.stores.   mapReduce(function() { { emit(1,1);   } }, function(name, sum) { return Array.   sum(sum); }, { out: ‘totals’ });”

这个注入看起来与经典的SQL注入非常相似。防御此类攻击的一种方式是在数据库配置中禁止执行JavaScript。如果JavaScript是必需的,那么最好的策略是不使用任何用户输入。

背负式查询

把一个键及相应的值加到使用Memcached的数据库中的一组操作。当从命令行界面调用时,这组函数使用两行输入,第一行是:

set <KEY> <FLAG> <EXPIRE_TIME>   <LENGTH>,

然后第二行由要保存的数据构成。

当PHP配置的函数被调用时,它接收的两个参数看起来是这样的:

$memcached->set(‘key’, ‘value’);

研究人员表示,该驱动程序未能针对带有回车\r(0x0D)和换行的\n(0x0A)的ASCII码采取措施,导致攻击者有机会注入包含有键参数的新命令行和其他非计划内的命令到缓存中8。

看一下如下代码,其中的$param是用户输入并作为键来作用:

$memcached=new Memcached(); $memcached ->addServer(‘localhost’,11211); $memcached->set($param, “some value”);

攻击者可以提供以下输入进行注入攻击:

“key1 0 3600 4\r\nabcd\r\nset key2 0 3600 4\r\ninject\r\n”

在本例中,增加到数据库中的第一个键是具有“some value”值的key1。攻击者可以增加其他的、非计划内的键到数据库中,即带有“inject”值的key2。

这种注入也可以发生在get命令上。

NOSQL安全攻击的更多相关文章

  1. RESTful记录-RESTful服务

    按照REST架构,一个RESTful Web服务不应该继续服务器的客户端的状态.这种限制被称为无状态.它负责客户以它的上下文传递给服务器,然后服务器可以存储这样的上下文,以处理客户端的进一步请求.例如 ...

  2. [面试专题]前端需要知道的web安全知识

    前端需要知道的web安全知识 标签(空格分隔): 未分类 安全 [Doc] Crypto (加密) [Doc] TLS/SSL [Doc] HTTPS [Point] XSS [Point] CSRF ...

  3. 小型单文件NoSQL数据库SharpFileDB初步实现

    小型单文件NoSQL数据库SharpFileDB初步实现 我不是数据库方面的专家,不过还是想做一个小型的数据库,算是一种通过mission impossible进行学习锻炼的方式.我知道这是自不量力, ...

  4. NOSQL之【redis的安全策略】

    原文:http://redis.io/topics/security 1.Redis的安全模式 可信环境下的可信用户才可访问redis.这意味着,将redis服务器直接暴露在Internet或者不可信 ...

  5. 注入攻击-SQL注入和代码注入

    注入攻击 OWASP将注入攻击和跨站脚本攻击(XSS)列入网络应用程序十大常见安全风险.实际上,它们会一起出现,因为 XSS 攻击依赖于注入攻击的成功.虽然这是最明显的组合关系,但是注入攻击带来的不仅 ...

  6. Memcached笔记——(四)应对高并发攻击【转】

    http://snowolf.iteye.com/blog/1677495 近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源.他们的最 ...

  7. NoSQL注入的分析和缓解

    本文要点介绍: 1.了解针对NoSQL的新的安全漏洞 2.五类NoSQL攻击手段,比如重言式.联合查询.JavaScript 注入.背负式查询(Piggybacked queries),以及跨域违规 ...

  8. web安全之攻击

    转自 知乎https://www.zhihu.com/question/22953267 作者:潘良虎链接:https://www.zhihu.com/question/22953267/answer ...

  9. 使用nosql实现页面静态化的一个小案列

    页面静态化,其实就是将动态生成的php页面,变成静态的HTML页面,让用户直接访问.有一下几方面好处: 1,首先就是访问速度,不需要去访问数据库,或者缓存来获取哪些数据,浏览器直接加载渲染html页即 ...

随机推荐

  1. C# 多线程小试牛刀

    前言 昨天在上班时浏览博问,发现了一个问题,虽然自己在 C# 多线程上没有怎么尝试过,看了几遍 CLR 中关于 线程的概念和讲解(后面三章).也想拿来实践实践.问题定义是这样的: 对于多线程不是很懂, ...

  2. GRYZY #8. 公交车

    公交车(bus) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK在玩一个游戏. 有k群小怪兽想乘坐公交车.第i群小怪兽想从xi出发乘坐公交车到yi.但公交车 ...

  3. 解决树莓派8G的SD卡只能识别3.3G,SD卡扩容

    8GB microSD在Windows下使用Win32 Disk Imager下载映像后,在RPi中只能识别出3.3GB.而本身还有很多容量没有释放出来. 使用sudo raspi-config工具可 ...

  4. [Javascript] Replicate JavaScript Constructor Inheritance with Simple Objects (OLOO)

    Do you get lost when working with functions and the new keyword? Prototypal inheritance can be compl ...

  5. LeetCode 3_Longest Substring Without Repeating Characters

    LeetCode 3_Longest Substring Without Repeating Characters 题目描写叙述: Given a string, find the length of ...

  6. leetcode Valid Palindrome C++&amp;python 题解

    题目描写叙述 Given a string, determine if it is a palindrome, considering only alphanumeric characters and ...

  7. MongoDB---出现no write has been done on this connection解决方式

    no write has been done on this connection 这个问题出现了好几天.日志里面一天出现几十次no write has been done on this conne ...

  8. Android自己定义View基础篇(三)之SwitchButton开关

    自己定义View基础篇(二) 自己定义View基础篇(一) 自己定义View原理 我在解说之前,先来看看效果图,有图有真相:(转换gif图片效果太差) 那来看看真实图片: 假设你要更改样式,请改动例如 ...

  9. 使用dataguard将单实例数据库转换为rac数据库

    我们常常将oracle rac数据库通过dataguard容灾到一个单实例数据库中.当生产库出现问题后能够将生产库切换到dgserver上.而当生产库rac修复完毕后.我们相同能够通过dg将数据回切到 ...

  10. activity栈管理的3种方式

    一.背景 在android开发过程最经常使用的组件非activity莫属. 通过分析activity的各种跳转,执行同学能够分析用户的各种行为.更重要的一点是在做插件化的过程中,我们经常会对activ ...