5 ms·
How we exploited a code execution vulnerability in math.js
- dvitali 10y agoGood job! Thanks for posting
- tbodt 10y agoYou can actually get access to require using this bug: cos.constructor("return process.mainModule.require")()
- CapacitorSet 10y agoOh well, that would have been so much easier. Thank you!
- tbodt 10y agoThe math.js api appears to be broken right now, it just says "error: method.apply is not a function"
- catmanjan 10y agoProbably related to the second exploit which used apply.
- albeebe1 10y agoThat's the definition of a clean presentation. Very clean. Well done.
- deleted 10y ago[deleted]
- comex 10y agoI was bored so I found a bunch more: https://github.com/josdejong/mathjs/issues/821 https://github.com/josdejong/mathjs/issues/821
- frik 10y agoSo the vulnerability is online in the service of mathjs.org: Math.js is available as a RESTful web service: http://api.mathjs.org
- FunnyLookinHat 10y agoYeah - or anyone that doesn't sanitize input before pushing it through mathjs.
- partycoder 10y agoEDIT: removed my suggestion since it was unsafe. Thanks for pointing it out. I was hoping vm to offer you an isolated v8 interpreter without bindings that could used as a sandbox, but this wasn't the case.
- fransr 10y agoThe page explicitly says: "Note: The vm module is not a security mechanism. Do not use it to run untrusted code." https://nodejs.org/api/vm.html#vm_vm_executing_javascript https://nodejs.org/api/vm.html#vm_vm_executing_javascript
- kevsim 10y agoThough the docs pretty clearly state "Note: The vm module is not a security mechanism. Do not use it to run untrusted code."
- emmab 10y agoBlacklists are a losing game. Always use a whitelist.
- CapacitorSet 10y agoThis was actually the second fix I had in mind, after the author mentioned that they would like mathjs to have complete browser support (and therefore couldn't use the `vm` module from Node.js): >If, anyway, you want to make math.eval resistant against arbitrary code execution, I think it would be best to have a whitelist of methods and constructs (i.e. you parse the code that is meant to be evaluated and ensure that every construct is allowed). I analyze JS malware in my free time (see [box-js](https://github.com/CapacitorSet/box-js) https://github.com/CapacitorSet/box-js)), and I found that it is virtually impossible to blacklist functions. For instance, if the parser forbids `[].map.constructor`, I could very well use `[].map["constructor"]`; and if you blacklist the word "constructor", I could use `[].map["rotcurtsnoc".split("").reverse().join("")]`, and so on, there's an infinity of methods one can come up with to avoid blacklists. The examples didn't really work in math.js, but it turns out that there's still [quite a few ways to get around it](https://github.com/josdejong/mathjs/issues/821 https://github.com/josdejong/mathjs/issues/821).
- jmaa 10y agoI'm not really an expert on JS, but I'm guessing that the constructor function is the same function object, although it can be accessed in different ways. Wouldn't it be possible to blacklist the function object itself, instead of the access path?
- CapacitorSet 10y agoThis is what the author attempted to do: if you read the first commit linked in the article, they made it so that math.js wouldn't execute Function when it encountered it (either an actual Function or a variable that equals Function). However, the trick is to make Javascript execute Function, through a function that math.js won't mind executing. What I found was simply using Function.apply and Function.call; the author found Function.bind, and someone in this thread found several more.
- jwilk 10y ago> Gist [here](https://gist.github.com/CapacitorSet/c41ab55a54437dcbcb4e62713a195822 https://gist.github.com/CapacitorSet/c41ab55a54437dcbcb4e627... An unmatched left parenthesis creates an unresolved tension that will stay with you all day.
- CapacitorSet 10y agoWhoops, thank you - it went unnoticed because I didn't proofread the noscript version as much as the default one. I pushed an edit.
- yagop 10y agoNice article. I wrote that lua "wrapper" 2 years ago. I used math.js to avoid RCE on bots, turns out math.js API is vulnerable but doesn't affect the wrapper.
- CapacitorSet 10y agoDid you also write the gnuplot plugin? Because that's also vulnerable, as found by the same @denysvitali: https://github.com/LucentW/s-uzzbot/issues/9 https://github.com/LucentW/s-uzzbot/issues/9
- dvitali 10y agoProof: http://i.imgur.com/BpLtg0b.png http://i.imgur.com/BpLtg0b.png
- yagop 10y agoThat was from @francesco-p (he renammed his account from psykomantis) https://github.com/yagop/telegram-bot/commit/89b92b4cbf81ce1dbc75fc12ac0895f682bf2d5b https://github.com/yagop/telegram-bot/commit/89b92b4cbf81ce1... its in my repo but disabled by default.