9 ms·
I probably deserve to get downvoted to oblivion for this but... I've deployed JSFuck in production! We wanted to obfuscate this bit of code, to make life just
by ollyfg 5y ago
I probably deserve to get downvoted to oblivion for this but... I've deployed JSFuck in production!
We wanted to obfuscate this bit of code, to make life just a little bit harder for reverse engineers. We made this huge function where we pretty much passed in all our application state, and it would run this JSFuck code, and spit out a token. We even made a few tweaks to the code so that you couldn't just reverse it back into JS with something like https://enkhee-osiris.github.io/Decoder-JSFuck/ https://enkhee-osiris.github.io/Decoder-JSFuck/.
Performance was surprisingly alright, and it has never hit an environment where it couldn't execute. All in all, a fun few hours setting it up, and I haven't had to touch it since!
- SNosTrAnDbLe 5y agoIf you can use the decoder, the reverse engineers will use the same, no?
- throwawayboise 5y agoPlease tell me who you work for and the website where this is deployed so I can avoid both.
- dang 5y agoPlease don't cross into personal attack on HN. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- google234123 5y agoYou must have changed it a lot, this seems to produces 100s of kb of obfuscate code for with just a tiny input.
- maple3142 5y agoI think you ultimately need to do something like Function(code)() in JSFuck, so it is always possible to remove the final function call and get the `code` directly.
- deleted 5y ago[deleted]
- zemnmez 5y agomakes me sad to hear that :( I will say, as a reverse engineer, that javascript minifiers like closure compiler will optimize almost all obfuscation out, and the rest you can usually translate to a form which it can understand and then it will do the rest. The effect of obfuscation is not what you expect. It seems like it moves the whole difficulty up, but it only moves up the floor. By doing so it tends to remove all the signals that would warn non-experts of security issues. Remove the obfuscation and then you have all the catastrophic security issues that have accumulated in there like treasures in an egyptian king's tomb https://zemnmez.medium.com/how-to-hack-the-uk-tax-system-i-guess-3e84b70f8b https://zemnmez.medium.com/how-to-hack-the-uk-tax-system-i-g...
- slig 5y agoI'm curious: can you can undo the obfuscation of JScrambler and Obfuscator.io easily? Some time ago I tried to run both through Closure Compiler, but it was way harder than I thought would be.
- zemnmez 5y agoJScrambler I actually did de-obfuscate to bypass some very significant bot detection a few years ago, but it took a bit more doing -- it uses ES6 features IIRC so I had to transpile it down to ES5 via babel first, but it worked OK after that. has a pretty good crack at obfuscator.io, too: https://closure-compiler.appspot.com/home#code%3D%252F%252F%2520%253D%253DClosureCompiler%253D%253D%250A%252F%252F%2520%2540output_file_name%2520default.js%250A%252F%252F%2520%2540compilation_level%2520ADVANCED_OPTIMIZATIONS%250A%252F%252F%2520%2540formatting%2520pretty_print%250A%252F%252F%2520%253D%253D%252FClosureCompiler%253D%253D%250A%250A(function(_0x161d09%252C_0xe210)%257Bvar%2520_0x341340%253D_0x2b43%252C_0xcbe4f7%253D_0x161d09()%253Bwhile(!!%255B%255D)%257Btry%257Bvar%2520_0x228bd5%253D-parseInt(_0x341340(0x1df))%252F0x1%252BparseInt(_0x341340(0x1de))%252F0x2%252BparseInt(_0x341340(0x1e5))%252F0x3*(-parseInt(_0x341340(0x1dd))%252F0x4)%252BparseInt(_0x341340(0x1e3))%252F0x5*(parseInt(_0x341340(0x1e0))%252F0x6)%252BparseInt(_0x341340(0x1e4))%252F0x7%252BparseInt(_0x341340(0x1e1))%252F0x8%252BparseInt(_0x341340(0x1e6))%252F0x9*(parseInt(_0x341340(0x1dc))%252F0xa)%253Bif(_0x228bd5%253D%253D%253D_0xe210)break%253Belse%2520_0xcbe4f7%255B'push'%255D(_0xcbe4f7%255B'shift'%255D())%253B%257Dcatch(_0x39d99f)%257B_0xcbe4f7%255B'push'%255D(_0xcbe4f7%255B'shift'%255D())%253B%257D%257D%257D(_0x4c13%252C0xaf378))%253Bfunction%2520hi()%257Bvar%2520_0x6c4afa%253D_0x2b43%253Bconsole%255B_0x6c4afa(0x1e2)%255D('Hello%255Cx20World!')%253B%257Dfunction%2520_0x2b43(_0x297e02%252C_0x195610)%257Bvar%2520_0x4c1309%253D_0x4c13()%253Breturn%2520_0x2b43%253Dfunction(_0x2b432d%252C_0x1b75d1)%257B_0x2b432d%253D_0x2b432d-0x1dc%253Bvar%2520_0x42fad5%253D_0x4c1309%255B_0x2b432d%255D%253Breturn%2520_0x42fad5%253B%257D%252C_0x2b43(_0x297e02%252C_0x195610)%253B%257Dfunction%2520_0x4c13()%257Bvar%2520_0x57f748%253D%255B'log'%252C'714060KYrWqs'%252C'387282xYOkyR'%252C'3VKGAoe'%252C'7077411TBGlUJ'%252C'10voBdfR'%252C'4109756DrGaTE'%252C'1107756uQYafl'%252C'825618MnVygR'%252C'36fcUkPH'%252C'2546320uORXvN'%255D%253B_0x4c13%253Dfunction()%257Breturn%2520_0x57f748%253B%257D%253Breturn%2520_0x4c13()%253B%257Dhi()%253B https://closure-compiler.appspot.com/home#code%3D%252F%252F%... That's the example from the site. "console.log('Hello world')" gets deobfuscated to "console[a(482)]("Hello World!");"
- Dylan16807 5y agoDid you have a legitimate reason to make things harder for reverse engineers?
- hungryforcodes 5y agoWhy are you reverse engineering my code in the first place?
- oauea 5y agoTo figure out what it's doing, obviously.
- hungryforcodes 5y agoPlease STOP that.
- cybernautique 5y agoI'll make you a promise: if your code never ends up on my machine, I will never try to reverse it. Otherwise, all bets are off.
- hungryforcodes 5y agoWhy would I put it on YOUR machine? It's my code. Don't hack my servers, or all bets are off. /s
- quickthrower2 5y agoJS is often (but not always) transmitted from the server to execute on the client machine
- hungryforcodes 5y agoYou've never heard of NodeJS?
- classichasclass 5y agoI understand the frustration, but as someone having to debug browser bugs with JavaScript edge cases, minified (and in this case ultra-obfuscated) JS is hell on earth to untangle and I wish people wouldn't.
- int0x2e 5y agoJust making sure - you're using js source maps, right? The minifaction should be adding significant pain in your debugging process.
- uryga 5y agoIME, code on prod rarely ships with a sourcemap. and as far as i can tell, GP is talking about other people's minified code, not something where they control the build process
- robocat 5y agoSource maps are used for anti-debugging: https://www.perimeterx.com/tech-blog/2019/javascript-anti-debugging-1/ https://www.perimeterx.com/tech-blog/2019/javascript-anti-de...
- mikeyjk 5y agoThat blog is horrific on mobile
- IncRnd 5y agoFor someone to reverse your code, all they need to do is run it through this. https://enkhee-osiris.github.io/Decoder-JSFuck/
- tdeck 5y agoI think you missed this sentence from the comment you're replying to: > We even made a few tweaks to the code so that you couldn't just reverse it back into JS with something like https://enkhee-osiris.github.io/Decoder-JSFuck/ https://enkhee-osiris.github.io/Decoder-JSFuck/.
- userbinator 5y agoI think I might've actually analysed the code you're describing. We even made a few tweaks to the code so that you couldn't just reverse it back into JS This is why a lot of us keep our tools private... an old tradition of the cracking scene going back decades to the 80s. Think of things like IDA/Hexrays and Ghidra, then realise the most prolific crackers had similar private tools they had written many years before those appeared.
- tonyedgecombe 5y ago>This is why a lot of us keep our tools private How ironic, that you want to open up other peoples code but keep your own hidden.
- spijdar 5y agoNot really ironic or related. The privacy here is, well, keeping the tools entirely private -- no distribution or highly limited distribution, not obscuring their function. Irony would be applying obfuscation or other DRM protection techniques to tools intended to de-obfuscate/reverse engineer which are then distributed/sold. This is fairly common in commercial reverse engineering solutions, although I don't think the irony of the cat and mouse game is lost on the authors in that case...
- bsza 5y agowhy not - after all, none of the open source licenses say that you must actually distribute the program, they only say that you should also include the source code if doing so.
- laumars 5y agoDifferent motives. Think of it like encryption: when someone finds a weakness in a cypher people will generally move onto a new cypher that’s harder to crack. The difference here is the purpose of writing those tools isn’t to improve security, it’s to break code open. So keeping these tools hidden keeps them effective.
- stjohnswarts 5y ago
- z3t4 5y agoA further obfuscation you could also compress it and have the app unpack itself. eJztVUESwyAIfAs3GJ60w/+/UZKiUUwzztT20OZiwgIbWJXAwARTmMAX02qRr0o9Vu02xRmwgKUPTzHv0weu8bGtZFhKyKSnTK0Z/parAJ/VI5WyXp7Uo/HYNc3qNchzKWBACnpCK3uj3N1Quvs6qCSJ4Gvah+++VT9/q3AlWLH5Pg3/cRqO94lR5SM5T6rDKSelDOUKC0+EzQ36l5N/zR7lDqti9Xjsj3U71f4AduQBlR9rUg==
- catchaway_4v93a 5y agoInteresting. I can definitely relate. As an author of a proprietary application written in web technologies, it's easy to be envious of compiled languages. This is my recipe for minification: 1. Apply a convention where all class properties and methods have to end with a trailing underscore (it's trivial to make an Eslint rule to enforce it) 2. Use 2 minification tools in following order: Closure Compiler (simple optimizations mode), then Terser for best output. 3. Configure Terser mangle.properties.regex: /_$/ 4. If it's a desktop app, use Bytenode for Node.js processes (cannot be used for the renderer) I also consider creating a tool to mangle string literals if they match a pattern. I.e. all string literals in the code that end with __ would be mangled. The benefit is that all internal event names and what not will not be visible. Yep, it's not going to hide it completely, but it's just that much harder to RE and understand when there is pretty much nothing descriptive in plain English left in the code (except error messages and third party libraries). Also I had this idea a few years earlier in a previous application where I did not use a module bundler. It was good old ES5 with files merged with Gulp and using prototype pattern. For those who do not know, prototype pattern is essentially like a class, but it's properties and methods do not have to be enclosed in one block. I did not implement it, but theoretically, it would be possible to create a mixer that would take all these prototype classes and their properties and create an output where all properties and methods from all classes would be output in a completely random order, all mixed together. Though looking back, it's probably not such a bright idea, as it would be possible to create an AST program that would reorder the methods back in place.
- richardfey 5y agoTalk about security by obscurity!