Juice-shop: Deserialization vulnerability

Created on 9 Feb 2017  ·  19Comments  ·  Source: bkimminich/juice-shop

This would probably be a little tricky to implement (and even harder to implement safely) but could be interesting...just a thought...

https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

challenge

All 19 comments

What about doing something simple using eval on the received JSON is a specific endpoint? There is no concept of deserialization of complex type in JS like in Java or .NET to the best of my knowledge.
Another option will be adding another backend in .NET/Java just for that...

I found this library https://www.npmjs.com/package/serialize-to-js had an arbitrary code execution flaw https://snyk.io/vuln/npm:serialize-to-js:20170208 in version <=0.5.0:

var serialize = require('serialize-to-js')
var payload = '{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });}()"}'
serialize.deserialize(payload)

Now how to make that a challenge... without opening up the entire backend for unwanted mischief?

We can:

  • use it only in a specific endpoint, that receives complex JSON (which is the hint)
  • leak out the packages.json, maybe where the receipts are stored.

This gives us A3, A8 and A9...

Just added https://github.com/bkimminich/juice-shop/issues/269#issuecomment-345910453 to the server start to try out if the vulnerability is exploitable. It spawns a node.js process successfully! Now this would need to be

  • [x] wrapped into and exposed as an API endpoint
  • [x] hardened against real mischief
  • [x] come up with a way to determine successful exploitation in a challenge

Node comes with a vm module which we could you to prevent the user to access any of the "harmful" node modules (e.g. "process" or "fs").

https://nodejs.org/api/vm.html

Note: The vm module is not a security mechanism. Do not use it to run untrusted code. Sounds Juice Shop-style! I'll try it out! Maybe breaking out of the sandbox could even become a tier 2 challenge at some point! 🤓

And, I could make the challenge condition rather easy, like making it another DoS where I check for timeout after 2sec and challenge solves when it occurs. Should be more flexible and interesting than my current idea of asking specifically for dir or ls getting called.

Now with VM (https://github.com/bkimminich/juice-shop/blob/develop/routes/b2bOrder.js) but timeout does not trigger in my unit test: https://github.com/bkimminich/juice-shop/blob/develop/test/server/b2bOrderSpec.js#L41-L49

Just made a unfortunate discovery, the vm module doesn't work at all in this context. As the injected code gets executed from the sanitize-js module which is passed into the vm, the code gets executed by node directly with direct access to all node apis.

This does unfortunately mean that the vm doesn't provide any security benefits whatsoever 😢

For the to-read-list on this matter: http://odino.org/eval-no-more-understanding-vm-vm2-nodejs/

I changed the impl from serialize-to-js to node-serialize which now at least makes the RCE exploit work. Unfortunately the timeout from vm does not trigger, so it's actually a too huge vuln at the moment...

How about dropping vm and instead spawning a child process doing the deserialization and check from the main process if the child is still running after 2sec (and kill it & solve the challenge)? @J12934, do you think this could work? I'm out of ideas... 😢

Child Processes would still be kind of dangerous. At least it would’t stop the user from doing stuff like “rm rf /“, or just spawning some other processes. The ability to run custom code without any restrictions sounds especially bad when the juice-shop ist centrally hosted, in a CTF for example.

I found another libary while researching the vm module.
https://www.npmjs.com/package/safe-eval

It just calls eval from inside the vom context, which should allow restricted code execution. As the eval is packaged with vm integration which should avoid the problems.
I kind of like it, as eval is the “natural bad choice” for deserializing objects in js which sounds like a natural fit for us 😏
https://stackoverflow.com/questions/6487167/deserializing-a-json-into-a-javascript-object

We could make it a more obvious that something weird is going on, by letting the Frontend send malformmed JSON Objects but valid JS Objects. Like using single quotation marks instead of double ones.

I think my Swagger Docs for the "enterprise API" are already quite revealing that there is some deserialization possible... 😀 http://juice-shop-staging.herokuapp.com/api-docs

I'll give that safe-eval a try, sounds really like the thing the Juice Shop dev team would pick... 👍

safe-eval did the trick! I let it time out after 1sec (because otherwise the unit test timeout of 2sec would fire first sometimes 😁) and it only counts the challenge as solved if the timeout was the Error reason.

As always, kudos to @J12934 for sanitizing my bad implementation ideas! 🤣

I'm not sure if this is a :star::star::star::star: or :star::star::star::star::star: challenge... As long as the Swagger docs route is not spoilered anywhere, I'm tending towards five stars. This means the package.json.bak cannot be updated from now on to avoid sneaking the safe-eval and swagger-ui-express dependencies in...

@J12934 Hehe, this one is actually working now against the Juice Shop: https://nodesecurity.io/advisories/337 ... I added some simple circuit breaker blocking everything with .exit() in it for now. But as we all know, blacklists don't really help, they only delay the inevitable disaster... :-) ... I was thinking of making this into another challenge, actually, to break out of the sandbox and do something not harmful... ideas are welcome! ;-)

This thread has been automatically locked because it has not had recent activity after it was closed. :lock: Please open a new issue for regressions or related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

santosomar picture santosomar  ·  25Comments

bkimminich picture bkimminich  ·  19Comments

thefishermanhacker picture thefishermanhacker  ·  13Comments

ingben picture ingben  ·  11Comments

bkimminich picture bkimminich  ·  42Comments