码迷,mamicode.com
首页 > 编程语言 > 详细

Server Side JavaScript Code Injection Attack服务端js注入攻击

时间:2015-02-16 01:41:30      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

今天扫描器误报了这个漏洞,我觉着是误报了。

趁机了解一下, 好像是针对nosql与nodejs的服务端, 我觉着可能是js对于nodejs就是可执行的代码, 也就是任意代码执行, 这么一个攻击。

stackoverflow上有一个http://stackoverflow.com/questions/27879131/server-side-javascript-code-injection-attack

巧了,看来我和他用了同款扫描工具,有了同样的问题。

看回答,大意竟是赞同他aspx可能有这个漏洞,我倒觉得这是误报了吧。

找到一份pdf介绍这个攻击的, 特翻译一下

原文:https://media.blackhat.com/bh-us-11/Sullivan/BH_US_11_Sullivan_Server_Side_WP.pdf

服务器端JavaScript注入

布赖恩·沙利文,高级安全研究员,Adobe公司安全软件工程团队,2011年七月

概要

本白皮书乃是为支持黑帽子USA2011的议题,“服务器端JavaScript注入:攻击的NoSQL和Node.js的”而写。本文及附带的会谈将讨论可能出现在软件开发人员创建基于JavaScript的服务器应用程序的安全漏洞,如NoSQL的数据库引擎和Node.js的Web服务器。在最坏的情况下,攻击者可以利用这些漏洞上传并执行服务器上任意的二进制文件,完全控制服务器。

(好吃力啊,接下来我可不管排版和颜色了--俺留)


JavaScript的Web应用程序的客户端层被广泛使用(如浏览器)多年,以提供更丰富,更像桌面 的用户体验。但近年来,对JavaScript的兴趣不只是客户端代码了,大家对码个服务器端兴趣激增。现在有服务器端JavaScript(或叫SSJS)的数据库服务器功能(如CouchDB),文件服务器(Opera Unite)和Web服务器(Node.js)。
当然,许多新的兴趣可以归功为是JavaScript引擎开发商近期取得的巨大的性能提升。微软,Mozilla的,苹果,谷歌和Opera之间的竞争,为了打造速度最快的浏览器,导致搞出了运行远快于前几个版本的过的JavaScript引擎。虽然它可能不可行的,从性能的角度来构建基于JScript的一个全功能的Web服务器,像iE6(例如),是个全不同的问题, 火狐4以此为目标。
另一种可能推动这种转变的是熟悉:很多Web开发人员已经拥有了大量的经验,在构建客户端JavaScript的功能,而在历史上,这些人已经退居编写的Web应用程序前端。但移动到SSJS后端有可能允许组织采取的更好人才储备--利用内部的老人。
背景:客户端JavaScript注入(又名跨站脚本)
虽然SSJS有实实在在的好处,但因为它们是客户端代码一是存在严重的缺点,可以被利用来在服务器上执行该脚本注入漏洞也同样容易不小心引入服务器端的应用程序代码;进而,服务器端JavaScript注入的影响更为关键和有破坏性。
客户端JavaScript注入漏洞是更好地称为他们更常见的名称为“跨站点脚本”(或XSS)。 XSS漏洞的影响可能是
非常有害:XSS一直负责会话劫持/身份盗窃(盗窃会话和/或从DOM cookie);钓鱼式攻击(注射用伪造的登录对话框插入主机应用程序合法页);击键记录;和螟(MySpace的/萨米等等)。

开放Web应用安全项目(OWASP)目前XSS排名第二危险的威胁,Web应用程序(SQL注入后),以及2011年CWE/ SANS排名前25位最危险的软件错误XSS排名为第4的威胁(从下降在2010年的名单#1)。


XSS漏洞不仅是极其危险的,在Extreme Tweaker都极为普遍。由Web应用安全联盟(WASC)2008年发布的Web应用程序安全统计报告1估计,全球网站39%至少包含一个XSS漏洞。双方的WhiteHat的Security2和Cenzic3最近的独立研究表明有更大的百分比:WhiteHat估计,64%的网站很容易受到XSS, Cenzic估计68%的漏洞率。


其中一个原因是XSS如此普遍的是,它是那么容易就会一不小心引入应用程序代码。考虑客户端的JavaScript代码,用来处理股票报价请求。 (该代码使用JSON作为消息格式和XMLHttpRequest的作为请求对象。)

(谷歌把这都翻译了)--改不动了, 以下为原生谷歌翻译内容
<HTML> ...
<SCRIPT>
VAR XHR=新的XMLHttpRequest(); xhr.onreadystatechange=功能(){
如果((xhr.readyState==4)&&(xhr.status==200)){VAR stockInfo=的eval(“(”+ xhr.responseText+‘)‘);警报(“当前价格”+ stockInfo.symbol+
“是$‘+ stockInfo.price);
}}
函数makeRequest(tickerSymbol){xhr.open(“POST”,“stock_service”,真正的); xhr.send(“{\”符号\“:\”“+ tickerSymbol+”\“}”);
}
</ SCRIPT>...
<HTML>


此代码看起来简单,但eval可能引入一个严重的漏洞。如果攻击者能够影响从股市的服务来注入脚本代码的响应,调用EVAL将执行在victim‘s浏览器上下文的脚本代码。在这一点上attacker‘s最可能的举措是将提取的页面的DOM任何认证或会话cookie,并将它们发送回自己,这样他就可以承担受害人的身份,并接替他的会话。


1 http://projects.webappsec.org/w/page/13246989/Web-Application-Security-Statistics
2 https://www.whitehatsec.com/home/assets/WPstats_winter11_11th.pdf?doc=WPstats_winter11_11th3 http://www.cenzic.com/downloads/Cenzic_AppSecTrends_Q1-Q2-2010.pdf
?
一个新的向量:服务器端JavaScript注入
现在考虑旨在JSON解析请求,但该代码执行在服务器层实现一个Node.js的web服务器的JavaScript代码非常相似块。
VAR HTTP=要求(“HTTP”); http.createServer(功能(请求,响应){
如果(request.method===‘POST‘){
VAR数据=‘‘;
request.addListener(‘数据‘,函数(块){数据+=块;});
request.addListener(‘端‘,函数(){
变种stockQuery=的eval(“(”+数据+“)”); getStockPrice(stockQuery.symbol);
...});


在同一行的代码(传入JSON数据的EVAL)是负责作为在先前的客户端实例的注入漏洞在这个段中。然而,在这种情况下,该漏洞的影响比的victim‘s饼干泄漏严重得多。
例如,假设在这种情况下,一个合法的,非恶意的JSON消息,股票报价服务看起来是这样的:
{“符号”:“AMZN”}
对eval则呼叫评估字符串:
({“符号”:“AMZN”})
然而,在这种情况下,没有什么可以阻止攻击者简单地发送其自己的JavaScript代码来代替正常的JSON消息。例如,他可以派:
到Response.End(“成功”)
服务器代码会执行此命令注入,并返回文本“成功”作为HTTP响应的主体。如果攻击者发送这种探测请求,并收到“成功”作为回应,他知道,服务器将执行他随意提供的JavaScript,而且他可以继续发送一些更具破坏性的攻击。


拒绝服务


拒绝服务的有效的攻击可以简单地通过发送命令执行:
而(1)
这种攻击将会使目标服务器使用其处理器100%的时间来处理无限循环。服务器将挂起并且无法处理任何其他的传入请求,直到管理员手动重新启动该过程。
It‘s值得一提的这个DoS攻击是如何不对称的。攻击者doesn‘t需要淹没目标数以百万计的请求;相反,仅使用一个八字节净荷单个HTTP请求足以禁用目标。
另一种DoS攻击是简单地退出或终止正在运行的进程:
process.exit()
process.kill(process.pid)


文件系统访问


攻击者的另一个潜在的目标可能是从本地系统读取文件的内容。 Node.js的(以及一些NoSQL的数据库引擎,如CouchDB的)使用CommonJS的API;文件系统访问支持(通过要求关键字)的“FS”模块,包括:
变种FS=要求(“FS”);
新的模块可以在任何时候被require‘d中,因此,如果当前运行脚本没有原先包括文件系统访问功能(例如),攻击者可以简单地通过包括适当的要求命令连同他的攻击的有效载荷添加该功能中。下面列出的袭击分别当前目录和父目录的内容:
到Response.End(要求(“FS”)。readdirSync(‘。‘)。的toString())到Response.End(要求(“FS”)。readdirSync(‘..‘)。的toString())
从这里,这是一个简单的事情来构建整个文件系统的完整的目录结构。要列出一个文件的实际内容,攻击者发出以下命令:
到Response.End(要求(“FS”)。readFileSync(文件名))
然而,不仅能攻击者读取文件的内容,他也可以写信给他们。这种攻击预先考虑字符串“黑”到当前正在执行的文件的开始 - 尽管,当然,更多的恶意攻击是可能的。
变种FS=要求(“FS”);
变种currentFile= process.argv[1]; fs.writeFileSync(currentFile,
‘黑‘+ fs.readFileSync(currentFile));
最后,我们注意到的是,也可以创建在目标服务器上的任意的文件,包括二进制可执行文件:
要求(“FS”)writeFileSync(文件名,数据,“BASE64”)。
其中filename是生成的文件名(如“foo.exe的”)和数据是将被写入新文件的基地 - 64编码的内容。攻击者现在只需要一种方法来执行这个二进制文件的服务器,我们将在下一节中展示的。

二进制文件的执行

现在,攻击者已经写了他的攻击二进制到服务器,他需要去执行它。我们最终的服务器端的示范JavaScript注入攻击的有效载荷说明他如何能做到这一点。
需要(‘child_process‘)产卵(文件名)。
在这一点上,任何进一步的漏洞利用仅由attacker‘s想象力的限制。

NoSQL的注射

服务器端JavaScript注入漏洞不仅限于通话的eval里面的node.js脚本。该处理包含JavaScript的用户指定的参数的NoSQL数据库引擎也可以是脆弱的。 MongoDB的,例如,支持使用JavaScript功能用于查询规范和地图/减少的操作。因为MongoDB的数据库(如其他NoSQL数据库),并没有严格的定义数据库模式,使用JavaScript的查询语法允许开发人员编写针对不同的文档结构任意复杂的查询。
例如,let‘s说我们有一个MongoDB的集合,包含代表书籍的一些文件,相当于电影的一些文件,并代表音乐专辑的一些文件。这个JavaScript查询功能将选择不是被写,拍,或者记录在指定年份的指定集合中的所有文档:
功能(){
VAR search_year=将input_value;
返回this.publicationYear== search_year||
this.filmingYear== search_year|| this.recordingYear== search_year;
}
如果应用程序开发人员正在构建在PHP(例如)这个应用程序的源代码可能是这样的:
$查询=“功能(){VAR search_year=\‘”。 $_GET [‘年‘。 ‘\‘;‘。
“返回this.publicationYear== search_year||‘。
“this.filmingYear== search_year||‘。
“this.recordingYear== search_year;}”;
$光标=$系列 - >找到(阵列(‘$其中‘=>$查询));
此代码使用“年”的请求参数作为搜索参数的值。然而,正如在传统的SQL注入攻击,因为查询语法是一个特设的方式(如查询用户输入串联沿线的语法)正在建设中,该代码很容易受到服务器端JavaScript注入攻击。例如,这个要求是针对系统的有效DoS攻击:
?HTTP://server/app.php年=1995年“;而(1); VAR%20foo=‘吧

NoSQL的盲注

使用针对NoSQL数据库SSJS注入攻击时的另一种可能的攻击向量是使用盲的NoSQL注射以提取出的NoSQL数据库的全部内容。为了演示如何攻击可能会奏效,let‘s继续刚才的MongoDB的例子。
要执行任何一种成功的盲目注入攻击,攻击者需要看到server‘s反应条件为真与它的响应假条件的差异。这是微不足道的,通过注射SSJS完成,其实甚至比经典的“OR1=1”SQL注入攻击更加简单:
?HTTP://server/app.php年= 1995‘;回报(真); VAR%20foo=‘栏中输入http://server/app.php年= 1995‘;回报率(假); VAR%20foo= “酒吧
如果在这两个喷射之间的server‘s响应的任何差别,那么攻击者现在可以“要求”服务器的任何真/假“问题”,并提出足够的问题,他将能够提取出库的全部内容。
要问的第一个问题是,有多少藏品都是在数据库中?或者更准确地说,是有只有一个集合中的数据库?或是否有确切两个集合在数据库中?等:
回报(db.getCollectionNames()==长度1);回报(db.getCollectionNames()==长度2); ...
一旦攻击者已经建立了许多的集合如何存在,下一步是确定他们的名字。他检查每个集合名称的数组中,首先要确定的名称的长度,然后,以确定名字本身一个字符时间:
回报(db.getCollectionNames()[0].length== 1);回报(db.getCollectionNames()[0].length==2); ...
回报(db.getCollectionNames()[0] [0]==‘一‘);回报(db.getCollectionNames()[0] [0] ==‘B‘); ...
一旦集合名称已被提取后,下一步是获得数据收集。再次,攻击者首先需要确定有多少文档每一组中(在本实施例的第一个集合的名称是“foo”的):
回报(db.foo.find()的长度== 1);回报(db.foo.find()==长度2); ...
在一个传统的盲SQL注入攻击,在这一点上的下一个步骤将是确定每个表的列结构。然而,柱结构的概念,没有意为缺乏一个共同的架构的NoSQL数据库中的文档。集合中的每个文档都可以从每一个其他文件完全不同的结构。但是,这个事实不需额外防止提取的数据库内容。攻击者只需调用“tojsononeline”方法来返回文档内容为JSON字符串,然后将提取的数据一个字符的时间:
回报(tojsononeline(db.foo.find()[0])的长度==1);回报(tojsononeline(db.foo.find()[0])的长度==2); ...
回报(tojsononeline(db.foo.find()[0])[0]==‘一‘);回报(tojsononeline(db.foo.find()[0])[0]==‘B‘); ...
最终,这种方法将产生在该数据库中的每个集合中的每一个文件的全部内容。


结论和缓解

应该指出的服务器端JavaScript注入漏洞更像是SQL注入比跨站点脚本的剥削。 SSJS注射不需要中间受害用户反映XSS或基于DOM的XSS的方式做任何的社会工程;取而代之的是,攻击者可以直接与任意创建的HTTP请求攻击应用程序。
正因为如此,对SSJS注入防御也类似于SQL注入防御:
?避免创建“点对点”通过连接脚本与用户输入的JavaScript命令。
?在SSJS用于验证用户输入的正则表达式的命令。
?避免使用JavaScript的eval命令。特别是,在解析时
JSON输入,使用更安全的替代,如的JSON.parse。

Server Side JavaScript Code Injection Attack服务端js注入攻击

标签:

原文地址:http://blog.csdn.net/u010211892/article/details/43845857

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!