热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【技术分享】从PouchDB到RCE:一个node.js注入向量

作者:默白预估稿费:200RMB(不服你也来投稿啊!)投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿前言PouchDB 

https://img8.php1.cn/3cdc5/12b31/a6e/4011008a086ad453.png

作者:默白

预估稿费:200RMB(不服你也来投稿啊!)

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


前言

PouchDB <= 6.0.4 当中包含了一个任意代码注入向量,只要维持express-pouchdb的默认配置,就可以进行无身份验证的远程代码执行。如果你已经发现一个Node.js注入,那么你还会从这篇文章中了解到一些利用技巧。

去年的SANS假日黑客挑战赛之后,我发现我开始对Node.js及其生态系统感兴趣起来。特别是最近两年物联网的兴起,Microsoft和Azure这些大公司对其进行了大力的推广。Node已经成为一些安全问题的核心,比如说几个月之前的Chalker凭据泄露事件。撇开Node包管理器长达一年半的包装问题不谈,它的系统遵循着“小模块哲学”,不同的任务由不同的模块来完成,甚至是检查某值是否在某数组中这样的事情也会交给一个模块来执行。写这篇文章时安装包的下载次数已经超过了2400万次。

这种哲学导致了大型Node应用程序或框架对于树结构的极度依赖,如果没有自动化工具,对于大多数的项目开发组来说,维护将会变得十分困难。Node.js是很容易学习的,它有一个活跃的交流社区,并且积极的鼓励利用第三方的模块去实现应用程序的一些功能。尽管这对于MVP迭代非常有利,但这种做法非常的不明智,可能会给已经保证了最小攻击面的成熟应用带来更多的安全问题。Node的哲学是有用的,因为它使得任何拥有Javascript web 开发能力的人都可以编写服务器端代码,使其成为一个有用的系统编程学习工具,以及新开发人员的进步跳板。

我在此请求所有的安全研究人员都能深入研究Node、libuv等各种类型的node模块,因为第三方模块太多了,往往未经审核就可以进入应用市场,被用户安装使用。其中有很多可能包含了一些非常简单的漏洞,这些应该及时报告给Node.js社区及时解决。Node安全项目的工作人员目前似乎正在处理第三方模块的所有漏洞报告,这将对应用程序安全会有很大帮助。

今年早些时候,我参与了有关 Node.js web 通用应用程序框架和数据存储话题的讨论。我花了一些时间研究PouchDB,这是一种"同步数据库",数据存储、处理方式受到了Apache CouchDB的启发,并且增加了一些自己的特性。在一次研究PouchDB的过程中,我发现了一个远程代码执行漏洞,并且可以在测试服务器上反弹回来一个Shell。于是我编写了PoC,并将其发送给了PouchDB的开发者。


关于PouchDB和express-pouchdb


PouchDB被称为“同步数据库”,但本质上是用Javascript编写的复刻版CouchDB,将数据存储在本地设备以备联机或脱机复制。主要的应用案例应该是Cordova 或Electron支持的应用程序,其中会存在有限连接问题,所以开发者还需要一个本地数据存储。(编者按:PouchDB维护人员Nolan Lawson写道,因为发展中国家的通信水平参差不齐,所以这种用途还是必要的。)

为了复制CouchDB 功能,PouchDB 利用了 Express.js web 框架,以及一个 express-pouchdb插件作为HTTP 中间设备解决方案,便于顺利到达远程数据库,这很像是CouchDB 的 HTTP API。PouchDB用户可以将数据通过HTTP同步到使用此 API的服务器。

奇怪的是,虽然 PouchDB 支持授权和身份验证,但是在使用PouchDB或express-pouchdb教程及默认设置时,既不需要授权,也无需身份验证;pouchdb-auth似乎是一个单独的插件。运行PouchDB文档的示例程序会使得express-pouchdb服务器门户大开。我目前发现的RCE漏洞应该只是对有权限访问数据库的用户有用,但是考虑到默认设置并不安全,这种注入应该可以在默认 express-pouchdb服务器中顺利实现。

此漏洞主要与 _temp_view 端点,以及视图如何在 PouchDB 中内部工作有关。在Couch/Pouch中,视图和设计文件都是脚本文件,允许管理员进行自定义的数据转换。_Temp_view 端点运行一次性视图。CouchDB 表示从性能角度出发,这些不应该被应用于生产环境中。

用户使用 _temp_view 端点可以添加任意的 Javascript 函数来处理提供的数据。一般来说,对于一个安全研究人员来说挖掘到服务端任意代码执行漏洞总是会让人激动的,所以我在发现这个端点之后立刻开始“找茬”。


PouchDB和_temp_view


现在让我们看看 PouchDB 是如何实现此视图基础构造的。我们已经在使用 Javascript了,因此对于解释型编程语言Javascript来说是很简单的:有一个很好的内置函数叫做eval,十多年来几乎每一位Javascript开发者都被告知最好不要使用这一函数。碰巧的是,在express-pouchdb中 PouchDB用来运行视图的函数就是eval。假设用户通过npm下载安装pouchdb,该函数会在lib/index.js:6201中被触发。(注:较新版本的Node包管理器其实已经对于PouchDB的另一个依赖tough-COOKIE易受到Regexp DoS攻击发出警告。)

http://p6.qhimg.com/t015304a2590d5b7a08.png

  这个eval函数使用的是另一个node插件scope-eval,该插件通过Function.apply在一定范围内传送数据。本模块代码全部以CoffeeScript形式呈现。

http://p6.qhimg.com/t01500aac0821a970b2.png

在此范围之外没有找到该函数的沙箱,那么,是否可以全局访问呢?


任意代码执行:从信息泄露到拒绝服务到反弹shell


我最开始试图注入一个Node请求,但是没有成功,因为在注入代码范围内不存在请求。尽管在范围内查看所有数据几乎是不可能的,但是幸好我们也不需要查看所有信息,我只需要一个注入 console.log。我的测试服务器包含了对于 Node.process的引用,这是一个含有内部过程状态的全局引用,还包含了对于许多函数的引用。

在这一阶段,注入漏洞使得从this.process.env窃取信息变得十分容易,其中可能会泄露AWS密钥、CSRF密钥等;注入this.process.exit()还会出现一个可注入的、一次性拒绝服务漏洞,或者对使用同一用户身份运行PID的其他租户进程造成损害。

但是代码执行又是什么情况呢?正如上文所述,我们没有办法访问请求,一个Node.js 开发人员使用的主函数当中会包含自己的Node代码。在这种情况下,这都不是问题,只是限制我们加载Node Javascript模块。通过Node加载模块,我们在注入点会有一个所有模块的引用树,这些模块都是由this.process.mainModule树中的Express服务器运行的JS主脚本加载的,以及在本地Node绑定的this.process.binding加载。

在渗透测试中,我认为最好首先在 process.env 附近挖掘出密钥,然后检查其他可能含有process.mainModule内存配置数据的加载模块。树上的每片”叶子“都包含了模块导出的函数引用;我最初编写了一个小导航函数,用来查找含有child_process的函数,但是没有找到。

注:关于“你有RCE,现在能做什么?”这一话题,将会在我之后要写的"Node.js/Express.js应用程序通用漏洞利用代码"一文中进行更加深入的探讨。文章大致已经完成了,但我还想在发表之前得到一些更清楚的PoC代码。

在Node本机,我们有bindings,这是Node内部库使用的本机C-to-JS 绑定。获得一个shell最常用的两个绑定就是Process和spawn_sync,两个都由Node的内部 child_process 模块所使用的。为了PoC目标,同时限制有效荷载大小,我选择使用 spawn_sync,这会产生系统中,这非常显而易见,因为你创建了一个新进程会导致监听器受阻,从而终止服务。为了证明此漏洞,我们打算选择隐身,以便更快捷的达成目标,而不是一味重复 child_process模块中一半的内容。


实现远程代码执行的payload


this.process.binding(‘spawn_sync’)代码是一个C绑定;使用这一代码时会存在一些不安全因素,也可能会引发一些底层漏洞。(如果你是一个底层逆向工程师,那我确认你一定可以在这里挖掘出一些我没有发现的问题)我们将执行的方法是 SyncProcessRunner::Spawn ,这会带来一些参数,并生成一个相关进程。

知道了这些,我们就可以在用户使用类似有效荷载运行的Node.js进程的同时运行任意二进制文件。

http://p6.qhimg.com/t01e37d3e100ff9afea.png

我正在为此编写一个Metasploit 模块。此exploit的伪代码和存在漏洞的应用程序源码在GitLab都可以找到;等到修补程序获得现有用户群的认可,我就会发布我的结果以及Metasploit 模块。


结论,修补程序以及解决方案


每个新框架和数据库出现时,我们都从来不会信任用户输入。PouchDB在2012年意识到存在不同的eval问题,然后关闭了该问题,尽管在文本中没有将其作为一个问题提出。这个RCE exploit在PouchDB 5.4.4和express-pouchdb 1.0.6中测试成功,PouchDB 5.4.5也存在同样的问题。

在与PouchDB维护人员和Node Security的工作人员取得联系之后,我们针对6.0.5中的注入推出了一个修补程序。用户仍应实施纵深防御,并且努力限制某些来自express-pouchdb的URI。一个常见的解决方法就是在express-pouchdb中设置 minimumForPouchDB标志。在撰写本文时这不会违反任何规定。PouchDB用户首先应该确认身份验证,其次是授权,并且最好是在PouchDB反向代理之前。不要允许 _temp_view之类的路径,这会使得服务器上存在远程代码执行。再次强调,一个开发者从来不会信任任何的用户输入。


披露时间轴


调查开源漏洞时,我遵循了谷歌Zero项目的披露时间线和进程。我在发现漏洞的第一时间与团队取得了联系,同时发送了一个有效的PoC,以及一个用Python编写的可反弹shell的exploit。

撰写本文时,PouchDB还没有回复自己的安全报告进程,所以我联系了信任的核心维护人员,希望能够得到开发者的公共配置文件。

2016.07.29:发现漏洞,用PoC上报给 @nolanlawson。

2016.07.30:通过 Twitter 联系Nolan,他说邮件被自动划分为了垃圾邮件,但是还没有得到证实。

2016.07.31:通过电子邮件将漏洞信息发送给 @calvinmetcalf 。

2016.08.01:Calvin没有回应;发送邮件和Twitter给Dale Harvey,所有的核心维护人员都积极看待这一问题。

2016.08.06:联系Nolan Lawson,他确认收到了漏洞报告。

2016.08.18:确认正在编写修补程序,将建议以及披露时间轴发送给Node安全项目工作人员,CVE仍旧悬而未决。

2016.09.18:发布针对PouchDB 6.0.5的修补程序。

2016.09.19:NSP 证实正在准备发布安全警告。

2016.10.17:NSP 发布安全警告。

2016.10.27:商定90天内披露时间轴。


推荐阅读
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 【MEGA DEAL】Ruby on Rails编码训练营(97%折扣)限时特惠!
    本文介绍了JCG Deals商店提供的Ruby on Rails编码训练营的超值优惠活动,现在只需29美元即可获得,原价为$1,296。Ruby on Rails是一种用于Web开发的编程语言,即使没有编程或网页设计经验,也能在几分钟内构建专业的网站。该训练营共有6门课程,包括使用Ruby on Rails进行BDD的课程,使用RSpec 3和Capybara等。限时特惠,机会难得,赶快行动吧! ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
author-avatar
喜欢上爱的感觉了
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有