长亭百川云 - 文章详情

我们是如何发现并利用math.js中的远程代码执行漏洞的

Web安全与前端

81

2024-07-13

↗点击上方“Web安全与前端”关注我们

本文简要介绍了如何发现,利用和报告远程代码执行(RCE)漏洞。也就是说这是一个发现漏洞,并负责任的报告它们的指南。

第一步:发现

在使用封装了math.js API的工具时(http://api.mathjs.org/v1/?expr=expression-here),我们发现了它似乎可以执行javascritp代码,尽管有一些限制:

特别要说的是, eval被替代为了一个安全版本。Function和setTimeout/ setInterval也不能使用:

第二步:利用

现在我们发现代码执行有一些限制,我们得绕过他们。

有四种标准方法来执行JavaScript中的字符串:

  • eval("code")

  • new Function("code")

  • setTimeout("code",     timeout)

  • setInterval("code",     interval)

在math.js环境中,这些不能直接访问,因为它们没有被定义,或者被安全函数重新定义了。但是,它们可以间接访问:特别是Function可以作为现有函数的构造函数间接访问 - 这是导致发现漏洞的关键。

例如,Function("return 1")可以替换为Math.floor.constructor("return1")。所以要执行return 1,我们可以用Math.floor.constructor("return1")()。

我们知道在math.js环境下cos是一个函数,所以我们使用:

> !calc cos.constructor("return 1")()

Result: 1

成功!

这样我们就可以简单的require一些本地模块,并获得对操作系统的访问权限,是吗?不,并没有那么快:尽管math.jsAPI服务器在Node.js环境中运行,我们却无法使用require。

> !calc cos.constructor("return require")()

Error: require is not defined

但是,我们可以使用process,它有一些很赞的功能:

虽然process.env包含了丰富的信息,但它不能真正做任何有趣的事情:我们需要更深入,使用process.binding,它让Javascript绑定到操作系统。虽然他们没有官方文档,并且在内部使用,但可以通过阅读Node.js源代码来重构其行为。例如,我们可以使用process.binding("fs")在操作系统上读取任意文件(在适当的权限下):

为了简洁起见,我们将跳过!calc cos.constructor("code")包装器,并粘贴相关的JS代码。

我们马上就要完成了:现在我们需要找出一种打开shell并运行任意命令的方法。如果您有Node.js的经验,您可能知道child_process,它们可以通过spawnSync生成进程:我们只需要使用操作系统绑定来复制此功能(请记住,我们无法使用require)。

这比看起来简单:您可以直接使用child_process源代码,删除不需要的代码(未使用的函数和错误处理),将其减小并通过API运行。

这样,我们可以生成任意进程并运行shell命令:

第三步:报告

现在我们发现了一个漏洞,并最大化的利用了它,我们需要决定如何处理它。因为我们是利用它找一些乐趣,并没有恶意的意图,那么就走把它报告给维护者并成为“白帽子”的这条路。我们通过维护者GitHub上的个人资料上的电子邮件地址联系了他,邮件细节如下:

  • 漏洞的简短描述(mathjs.eval中的远程代码执行漏洞);

  • 一个攻击实例,演示它是如何工作的(总结为什么cos.constructor("code")()可以执行和通过process.bindings可以执行什么);

  • 在可用服务器上的演示(我们演示了输出whoami和uname -a);

  • 如何修复的建议(例如在Node.js中使用vm模块)。

在两天的时间里,我们协助作者一起修复了这个漏洞。值得注意的是,在他发布了一个修复(2f45600)之后,我们发现了一个类似的漏洞(如果你不能直接使用构造函数,可以使用cos.constructor.apply(null,"code")()),这个在(3c3517d)中被修复。

时间线

  • 2017年3月26日22:20 CEST:第一次成功利用

  • 2017年3月29日14:43 CEST:向作者报告漏洞

  • 2017年3月31日12:35 CEST:报告第二个漏洞(.apply)

  • 2017年3月31日13:52 CEST:这两个漏洞被修复了


此漏洞由@CapacitorSet和@denysvitali发现。感谢@josdejong及时修复漏洞和JSFuck发现[].filter.constructor技巧。

Jos澄清:math.js并不像之前说的那样“执行 JavaScript”,而是“使用自己的数学语法、自己的运算符、函数制作自己的解析器,但这些函数当然还是JavaScript函数“。

原文链接在阅读原文中~~

安全&前端

长按二维码
关注我们

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2