14 ms·
JavaScript Obfuscation Techniques by Example
- efortis 4y agoFor mangling, I made a proxy that creates meaningful names in dev, and sequential or pre-baked ones in production. For example, FileFields.js: const FF = proxyFieldNames('FF', { foo: null, bar: null }) // DEV: FF.foo → FF_foo // PROD: FF.foo → 'a' https://github.com/uxtely/js-utils/tree/main/proxy-fields-obfuscator https://github.com/uxtely/js-utils/tree/main/proxy-fields-ob... As a bonus, it's helpful for renaming, autocompleting, and finding usages.
- ffhhj 4y agoWhy obfuscating JS when there is WASM?
- whatshisface 4y agoBusiness people demand it to protect intellectual property without realizing the ease of reversing it / wanting to say they're doing something to protect IP that their own superior will not realize doesn't help. It is making the best of an impossible situation, the paradox of sending your code to every single customer for them to run it while also wishing nobody could see it. The more aggressive they make patent law the less useful it seems to become for protecting any actual investment, so here we are, clinging to wooden totems...
- iratewizard 4y agoWith how mediocre most developers today are, obfuscation is enough.
- whatshisface 4y agoToo mediocre to type "deobsfucate" into Google? The first result is a deobsfucator. https://deobfuscate.io/ https://deobfuscate.io/
- iratewizard 4y agoToo mediocre to read deobfuscated JavaScript, yes. Many such cases.
- edflsafoiewq 4y agoCan't tell if you mean they can't deobfuscate, or that their code isn't worth the effort of deobfuscating.
- throwntoday 4y agoProbably both
- jollybean 4y agoIt's a supply demand thing. If you publish your code on github, it's more likely to be compromised than if it's just in the webapp, very well obfuscated. A sufficiently motivated actor will break it, and frankly break almost anything else, so it's a game of probabilities etc.. Obfuscation probably does make sense so long as it's not obviously getting in the way of dev. and, with the key understanding that 'it can be broken'. Physical security at most companies can be thwarted with enough effort, it doesn't mean we don't do it.
- e9 4y agoYou can use wasm disassembler (like https://github.com/JoseFMP/wasm-disassembler https://github.com/JoseFMP/wasm-disassembler) as a starting point to understand what’s happening. It would be much harder if it was obfuscated on top of that.
- uetttyywwww 4y agoWhy WASM when you can create a full VM with its own custom bytecode implementation complete with nonsense instructions and compile to that.
- selfmodruntime 4y agoAn incredibly cool example of this is the newest iteration of the HIVE malware which does exactly that. They build a custom VM via RCE in a buggy image format parser which allowed them to execute custom code on an iOS device.
- LoganDark 4y agoThis is already what (a lot of) Lua obfuscators do for game cheats, since Lua has a reference implementation that generates bytecode, that can be easily modified to generate the most awful, encrypted, obfuscated mess ever.
- aardshark 4y agoThis is how ReCaptcha is implemented, right?
- muhehe 4y agoWhy obfuscate, when you can just follow modern trends and use webpack (or similar) which gives you completely unreadable shit.
- foobiekr 4y agoend of the day once you can apply a tool like ghidra to a given program, understanding what it is doing is straightforward unless they went to extremely great lengths beyond simple obfuscation reversing is one of the few classic skills from the home computing era that is alive and well in 2022. it's kind of nice.
- sphynxie 4y agoI certainly agree with your tone/sympathize with your frustration but I will say that on several occasions I have followed the webpack breadcrumbs to figure out what the hell is going on with a vendor's misbehaving script, knowing it's going to be faster than going through support. Some of these methods would make that much harder.
- cabirum 4y ago"Modern"? Webpack/code bundlers is quite an ancient tech by now. Regard it as an intermediate representation (IR) of your code, a stage between your readable source code and browser bytecode/jit. The "shit" is still readable since webpack also generates source maps.
- kitten_mittens_ 4y agoDo you mean ancient like something has replaced it? Or old enough to be in widespread use?
- moritzwarhier 4y agoThat's because Webpack includes a minifier (Terser) by default when running in production mode (I think since version 5, which went a lot in the direction of convention-over-configuration). It is easy to disable if you want to. Terser transforms non-global identifiers lexically and does some simple substitutions. Normally you want to bundle modules with their dependencies anyway, maybe transpile code... Then why not minify? Et voila, some completely unreadable shit.
- etamponi 4y agoSorry for the slightly offtopic question: this page caused Chrome on my mobile phone to freeze completely. I had to reboot my phone, and even after that, I had to figure out a way to close the tab without opening Chrome. Did it happen to someone else?
- uwuemu 4y agoNope, but I can see the jsfuck example doing something like that as it kinda weirdly lagged on mine (android 12, chrome 103).
- deleted 4y ago[deleted]
- jeroenhd 4y agoYes, actually. Works perfectly fine on Firefox but on both Chrome and Bromite it causes the browser to crash. My phone just let me kill the app after a few seconds but there's definitely something weird going on here. Interesting, I have Bromite set up to disable JIT by default, so if it's because it weird JS, it's a bug in both the JIT engine and in the interpreter. Edit: I doubt it's JS related because this site doesn't seem to use JS (unless there's some UA sniffing going on). I'm guessing this is a Chrome bug, hopefully not an exploitable one! Android 11, Chrome 103.
- abirch 4y agoAlthough I won't ship you my phone, it worked on 103.0.5060.71 chrome on Android
- GOATS- 4y agoDamn, I thought I was crazy. I had to reset Chrome to get it working again, could finally read the article after I installed Firefox. Android 12 with Chrome v103.
- captainbland 4y agoHad the same problem. The browser was essentially soft locked as the tab would be brought back after restarting the app until I cleared Chrome's storage which closes all tabs (and clears history, cookies, etc. too which is a bit annoying).
- deleted 4y ago[deleted]
- uwuemu 4y agoBefore someone asks why would you obfuscate, here's common use case: There's plenty of paid/proprietary Electron apps these days and they're not just websites, some of them do some heavy lifting under the hood and people want to protect that better than what Electron offers out of the box (read: nothing).
- peanut_worm 4y agoIf you obfuscate client side javascript that is being served in a browser you should get banned from the internet
- deleted 4y ago[deleted]
- cachvico 4y agoWhat?
- salawat 4y agoI second this proposal.
- Kiro 4y agoWhy would serving it in the browser or not matter? It's like saying all code should be open source, which is a valid opinion but I don't see why writing JavaScript and serving it in the browser would be any different. It's not like I automatically agree on making my code fully available just because I happen to target the web. Sure, you can de-obfuscate JS but you can also reverse engineer other software.
- pcthrowaway 4y agoUsers of the webpage can't determine whether they want to run the scripts from looking at the scripts if it's (well)obfuscated. Very few users may even want to do this (perhaps none), but in theory it's a nice thing that has historically been made possible by the web. Unlike binaries or backend code, the user gets the source themselves to run in their browser... fine, if you want to obfuscate it you can, but I think it's fair for users to also dislike websites that do this. I'm not talking about minifiers/bundlers which are used to make the content more user-friendly, I'm specifically talking about steps taken to make the web less accessible and less free.
- aussieshibe 4y agoI'm curious. Could you explain why you feel this way? I can understand the desire to be able to vet code that a website wants to run on your device. I don't see why that preference should create an imperative for websites to either accommodate you or be banned from the internet.
- Animats 4y agoYou want to see obfusication? Check out FreeSlots.com. Look at view source on one of the slot machines.[1] Can anyone decode this and figure out the odds generator? [1] view-source:https://www.freeslots.com/slot515.min.js?v=84 https://www.freeslots.com/slot515.min.js?v=84
- melissalobos 4y agoTo answer your question, yes. Someone absolutely can decode that and figure out the odds. If they couldn't then there would be less obfuscation used. A browser ABSOLUTELY has to be able to run the javascript. Anyone dedicated enough can de-compile that javascript to a program. Is it easy? No, but people do it all the time. I have had to deal with client that thought they could keep some bit of code secret on a browser before. I have had to explain many many times that anything the browser can do a human can do. So if a browser can run the code, at some point a human can too.
- throwntoday 4y agoI think what the parent meant was, can someone looking at it decode what is going on. Not asking whether it is possible in general.
- michaelsbradley 4y agoThat's why they wrote "Anyone dedicated enough can de-compile that javascript..." Meaning, effectively, it can be de-obfuscated into code with control flow that's readily understood by a human, even if it would take some patience and practice (and the right tools) to perform the de-obfuscation. Re: the FreeSlots.com program, https://deobfuscate.io https://deobfuscate.io shows that most of the obfuscation is related to decoding characters per some algorithm of their devising and eventually eval'ing the string as a JS program. There are likely several tricky rounds of that technique (and others) used at layers within the obfuscated code. If the FreeSlots devs are clever, then they likely have a scheme to randomly generate the code they want (producing their desired result in terms of odds), where the random part is w.r.t. how the obfuscation layers are composed. Done well, that could make it rather difficult to mechanically de-obfuscate their code changing over time, i.e. without a human intervening to help identify the distinct layers because... parsers are hard.
- don-code 4y agoThis actually gave me some new context on why Web technologies can be slow: fast as the runtime might have become, it spends useless cycles converting hex to ASCII, thrashing the stack, and so on. I wonder if it wouldn't be faster to encrypt the JavaScript code, and use something like the existing Widevine DRM to distribute the keys.
- tjkoury 4y agoA favorite trick of mine is to replace regular length variable names with absolutely massive ones that all share the same first 1024 characters, plays hell with debugger UIs and makes differentiation all but impossible without writing a custom lexer. Add into that a bit of Z̶͚͎̙̭͈͚͚̘͗̑̉̈́͌̆̀̚͝ă̶̡͉̠͍̻͔̯͔͖̪̤̤̫̓̽̏̉̎͌͒̆͘̕ḻ̴̡̡̝̫̠͇̻͎̥̲̜͆͌͑̍ͅg̸͈͒̏̀͂̈͊̂̾̑̈́̑͝o̴̡̙͍͉͓̘̮͗̏̒̂̃̏̓́̕ͅ and you’ve got a stew going, baby!
- efortis 4y agoThat reminded me of a base4 encoding using these characters: '0' 'O' '1' 'I' The code looked like: var O11IOOO1I011 = 1<<1, II00001OOO1O = 1<<2;
- _8j50 4y agoOP is talking about protected legit JS but I see malware use similar techniques as well. The latest one I have seen has a legit JQuery code on top but eventually functions with english words as names that do weird string operations are seen intermixed with jquery. The script is meant to be run by the windows script host to download malware.
- p0larboy 4y agoI can imagine obfuscation as a useful thing for Chrome extensions where, in some cases, your business logic cannot exist on server.
- cfcf14 4y agoInterestingly enough, passing even the most complex example in the link to GPT-3 with the prompt "What does this code output when run?" returns the correct result.
- LoganDark 4y agoNow I wonder if it's possible to train a neural network to run JavaScript. Or lay out a web page.
- aardshark 4y agoSomething else that sites do, which is not really deobfuscation, but an anti-debugger technique, is to run a loop checking whether the DevTools are open and crash the page via catastrophic regex backtracking if they are. You can get around this by intercepting the request and returning a copy of the js with this check patched out, but it's just another hurdle in the way of casual inspection.
- LoganDark 4y agoThen it turns out the anti-debugger code was contained in a function that gets stringified, so if you change the source code at all, the script stops working. So you have to manually substitute usages of the function-as-string with the string representation of the original obfuscated function...