目录
信息搜集
bypass 黑名单机制
绕过沙盒执行系统命令
总结
这是一道 Node.js 沙盒逃逸的题目,在此记录一些技巧。
信息搜集
进入题目环境:
直接给出了一个可执行任意代码的入口 /run.php?code=<code>,直接复制第二个 demo 的路径和请求参数到地址栏访问看看:
执行了 new Date(); 这行代码,并且将日期结果回显到页面上,说明 demo 确实没欺骗我,这里有执行任意代码的入口。
再复制第一个 demo 的路径和请求参数到地址栏访问:
没有表达式的执行结果,那么可能是有敏感字符串的黑名单检测机制。经过我尝试输入其他的 Node.js 语句,发现有以下字符串被列为黑名单:
' (单引号)
" (双引号)
+ (加号)
process
constructor
exec
...(可能还有其他的,但在我的 exp 中没有测试出来)
到这里,我已经知道我的任务了:
- 绕过敏感字符串的黑名单机制,构造任意代码;
- 构造能够逃逸沙盒的代码;
- 利用代码执行系统命令,读取 flag。
bypass 黑名单机制
首先是单引号或者双引号,我的代码需要用到它们,但都被禁用了,我选择用 `` 代替单双引号声明字符串。
process、constructor 和 exec 都是被用于命名方法或者属性的标识符,它们本身不是字符串,但是由于在 JavaScript 中,除了可以通过 . 访问属性和方法,还可以通过中括号 [] 访问,中括号里面是方法或属性的字符串名称:
我可以把标识符转换为字符串,不过还是不能出现 process 等敏感字符串的字眼,用 concat() 可以连接字符串即可:
最终,绕过黑名单机制的访问一个方法或者属性的形式类似如下:
绕过沙盒执行系统命令
构造的代码需要绕过沙盒,以及能够执行系统命令,这两个目标放在一起说,因为沙盒存在的目的本身就是为了不让用户执行危险的操作,执行系统命令就是其中之一。
其实,大多数 CTF 题都能在网上找到思路,很多时候就是出题人根据最近的 CVE 出的。所以,沙盒绕过的 exp 可以直接在网上找现成的(主要是我不会......)。
在此之前,我需要知道这是哪个沙盒模块,这利用 Error 对象的 stack 属性看下调用栈:
是 vm2 模块,这就好办了,直接在 snyk 网站搜索这个模块的 CVE:
试一下最新的 bypass exp,点击链接:
有 PoC,复制到本地,改一下:
主要是把敏感字符串换掉。完成后,复制这段代码到地址栏中访问:
OK,结束。
总结
JavaScript 声明字符串的几种方式:
- 单引号 ''
- 双引号 ""
- 反引号 ``
- Buffer.from()
- 正则表达式,然后 toString() 得到字符换,再 substring() 去掉左右的 /,例如: /apple/.toString().substring(1,6)
JavaScript 拼接字符串的方式:
- + 加号
- String.concat() 方法:"proce".concat("ss")
JavaScript 可以用点号或中括号访问属性和方法:
- this.constructor
- this['constructor']
Error 对象的 stack 属性可以返回调用栈,包括程序文件的路径,利用这点查看用的哪个沙盒模块。
沙盒逃逸用的是现成的 exp,我还需要深入学习,就不写了。