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/.
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!
makes 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-g...
I'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.
JScrambler 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.
To clarify, that's what happens once you pass it through the obfuscation and THEN closure compiler. If you click the link you will see the obfuscation is much more complex
While I think itcs bad to use obfuscation to hide security holes, I do think obfuscation has it's uses. If there's reasons to make data private, then there's reasons to make execution private as well. Not to mention, it was recently proved that indistinguishable obfuscation is possible, so I'm not sure how useful de-obfuscation tools will be in the future
Really enjoyed that blog post, thanks for linking it! How long would you say actually finding those two issues took? The attack surface must've been fairly large, but I guess intuition helps.
I've been using the Google Closure compiler for many years with advanced and every time I look at the code output I'm like "there's no way in a 100 years I would be able to de-obfuscate back to my own code to a great extent". But I don't specialize in reverse engineering, so I might be missing something big.
personally, I find the code it outputs to be easier to understand often than the source because it simplifies a lot of stuff into the most abstract logic. I think it takes some getting used to for your brain to connect those pieces, though
I guess ultra-shortening the names into a,b,c,d,e, etc makes it superficially hard to understand what's going on but I agree on your point about abstract logic.
I 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.
IME, 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
I 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.
Not 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...
why 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.
Different 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.
> You shouldn't have access to it -- it's on my private servers doing stuff for me. How did you get it?
Seems like the logical solution would be to restrict access to it then, rather than obfuscate it making it harder for yourself to maintain. But hey, you do you.
> You shouldn't have access to it -- it's on my private servers doing stuff for me. How did you get it?
Well thanks for chiming in about a completely unrelated topic from website javascript. My comment wasn't getting downvoted until your slapfight with oauea blew up.
That wasn't a top level question though, it was a question to a commenter saying "We wanted to obfuscate this bit of code, to make life just a little bit harder for reverse engineers." That you obfuscate code nobody other than you can even access is completely irrelevant as a reply to that question.
Dude, I write financial applications in Node. Node IS javascript.
These applications run on the back end. Some of the API facing VMs have been attacked and so to be honest I've configured them so that if someone did get access to them, they wouldn't find much. Maybe just some API keys I can invalidate. Although I probably won't do it -- an obfuscator like this could be very handy here.
Did you give a try of Deno. This is a JavaScript runtime but it produce a single binary. This would make sense in your case because it can be harder to inspect it.
I 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.
Interesting. 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)
Not sure if it's what you mean by blank (not a big keyboard geek, but I just got a Moonlander), but when you buy it there's an option for all of the keys to have "-" on them, so it's effectively blank?
I may be misunderstanding what you're asking, but the ErgoDox EZ has two different keycap shapes.
The printed keys are all the same shape and can be moved around as one remaps the keys. However, this results in a flat keyboard. You can get the same effect by buying another set of keycaps from a keycap company.
The blank keys are sculpted, so each key is unique to it's position or a set of positions. This makes reaching keys much easier from the default position, but makes learning the keyboard harder.
I had started down the path of trying to buy replacement keys, ideally blank but with some sort of a clear spot so the keyboard lights can shine through. That was rare enough, and I guess maybe in the end I might just want clear keycaps for the lights. But there's a whole set of lingo in the keycaps that I felt like I had to understand to stand a chance of getting the correct set of keycaps. There wasn't just a "Here's a ErgoDox EZ caps set..."
I just tried buying and didn't see an option beyond color and keycaps. I had even mailed them maybe a month ago just to double check, because for my ErgoDox EZ they were able to do a custom order with the lit keys but black keycaps. They had said they are still looking at doing an "all -" blank set, but didn't have it available yet.
How do you like the Moonlander? I really love my ErgoDox, but the Moonlander looks nice.
Wow! How have I not heard of frida? This should make my normal process much simpler!
1) Decompile App -> smali
2) Decompile App -> Java (non-reversible, but easier to read)
3) Search the app for certificate pinning code (check for network_security.xml or grep for OKHttp pinning functions)
4) Find the code I just found in java, in the smali version
5) Remove the pinning code
6) Recompile smali -> apk
7) Fix whatever was causing the smail not to recompile
8) Recompile again
9) Pray
10) Install on device
11) Run app (that hopefully doesn't crash)
12) Pipe connection through Charles proxy
13) Read api calls!
I'll definitely give it a go.
In general I think there are nowhere near enough resources on decompilation, particularly on a purportedly "open" platform like Android. Really looking forward on the rest of the tutorial coming online.
As an alternative, you could use the XPosed framework. It basically lets you overwrite App and System methods and classes by installing a small module. No need to modify your target apk.
So you can just return true from the method that checks if the correct certificate is in use.
"Unless your APK is internal and not distributed outside a small circle, assume your code has been reverse engineered."
Of course, but doesn't obviate the illegality of stealing protected code.
"Reverse engineers are not your enemy."
Yes, many of them are.
Many of these resources and individuals are involved in illegal and immoral acts around stealing code and IP, and justify it to themselves on some kind of skewed logic.
Nobody really cares that folks are hacking code for fun, and nobody cares that people would use resources for this purpose. This is fine and possibly helpful.
But IP theft is a big deal, and it's very damaging.
"Surely if you're running something that has to be that "closed", most of the key code is server side and the client is just calling APIs"
Unfortunately, this isn't possible in a variety of cases, especially new and upcoming scenarios that require AI to be 'on device'. There are many other such scenarios.
It's very oppressive to a major class of innovation - particularly to those who've worked very hard to assemble something exceptional and useful.
I've switched to using Ian's knot, and have found it to be both faster to tie and easier to set up. I think once you work out how to 'pick up' the laces in the right way, so that they are already in the correct starting position, it gets a lot faster/simpler to think about.
Of course, I haven't been in your shoes - my laces are all the round type and I haven't tried it with flat ones.
I like flat laces a lot because they seem to distribute the force a lot better than round styles. I like my shoes to be fairly minimalist, I don't like overly padded or heavy shoes, and round styles seem to put a lot more pressure on the top of my foot.
The oval style with the sharp edges has a lot of the benefits of the flat style, but is more universally compatible. The flat ones don't always move well in round eyelets, they work better with loops in my experience.
The completely flat style doesn't tie well if one of the laces is twisted though. I think it's a great option for athletic shoes though, where you are more likely to care about a particular level of give, etc, and when you don't want your shoes to become untied. The round style is cheaper, and if you don't notice the difference it's probably a more versatile shoelace.
Looks good! One feature that would definitely get me using this for personal projects is the ability to add/customise axis. You might already have this, but I didn't see it in any of your examples, so if this is present, please advertise it!
My general reaction when seeing a chart without axis is "pretty, but I can't see what it means", where as with decent labelled axis I can dig into it and look at data points, and come to my own conclusions about the data.
Still, this is a useful service that could make life much easier - keep at it!
EDIT: HN is doing some escaping to my example URL, so I adjusted it a little below.
Author here, thanks for the feedback!
My default use case was to use these images as background-images (via CSS) in dashboard widgets that show an accurate trend for how data has changed over time. Therefore my defaults were to hide to x and y-axis and make the chart margin 0 to fit in the widget and look "nice" across the entire thing.
But if you are or become familiar with the Highcharts chart config options, you can update any option you want for the axis via the `raw` param (see more detailed info on the params in github: https://github.com/whatl3y/restcharts). One thing you could do to one of the simple charts provided on the landing page to show the axes is override the default margin values (which is margin: [0, 0, 0, 0]) and make the x-axis and y-axis visible like so:
where [raw]={"xAxis":{"visible":true},"yAxis":{"visible":true},"chart":{"margin":null}}
You can obviously continue to add config to adjust the language on the axes among other things. I realize this could get a little verbose quick, but again the idea was to make a simple, quick view of data, even though you could technically get as complicated as you want with the `raw` param.
If there is one thing I've learned from university, it's this. Keeping units makes your writing messier and longer, but when it comes to checking they are absolutely invaluable.
Your equation to give you volumetric flow gave you (kg/s)? Well density is (kg/m^3) so just divide your answer by density! (this is a problem my friend was having just yesterday)
I think the problem is they don't teach the same units everywhere in the world.
I grew up in Australia with SI units I do a lot of work with Fluid/Thermodynamic calcs. I have a bunch of reference values in my head. I know 1 Atmosphere is ~101.3 kPa, I know speed of sound in dry air is ~330 m/s I know how much energy it takes to raise the temperature of various substances. I know the densities of common materials in my head. All of that helps me sanity check calculations - at a glance I can see things 'this fan is producing too much suction, not possible' or 'There is not enough input energy to see a temperature rise that high' things like that.
I have no idea about any of the non SI units. I couldn't tell you how long a "yard" is or how heavy a "pound" is usually it is fine but occasionally I come across numbers in technical papers or datasheets or similar with stuff in wacky units - PSI, BTU and Fahrenheit are the worst offenders when I have to deal with them it just blue screens my mental models. I see those units so infrequently I have no concept of what a 'reasonable' value expressed in those units looks like. I imagine people who don't work in SI units everyday hit the same difficulties in reverse.
This is interesting because there's actually a unit-agnostic way of doing units more generally... it's "dimensional" rather than unit-based. So regardless of the base units you'll do "length" (which works for all three axes: length, depth, breadth) and "mass" (which works for kg, pounds, whatever) and "acceleration", "force", etc.
Obviously this is slightly more lax and perhaps error-prone than your standard m/s or m/(s^2), etc., but it's one of the lamentably few things computers can do well!
EDIT: ... and I should elaborate: In some sub-fields of Physics they usually go even further and just re-normalize everything to units of 1, so that e.g. the speed of light is c is 1. At that point it's really just about convenience since sqrt(1) = 1, and 1^x = 1, etc. (Lorentz Transformation.)
I believe that bigger_cheese is lamenting his or her inability to do numerical sanity checking in other units. (This loss of numerical information is, perhaps, what you meant by saying that the unit-agnostic approach is 'more lax'.)
For example, if I am looking for a force and I get an answer of 1000 lbs, then dimensional analysis tells me that at least I got a force; but, if my intuition tells me only that the actual force is on the order of magnitude of 1000 N, then I don't know whether my actual answer is way too big, way too small, or about right, unless I know how to convert between Newtons and pounds.
Incidentally, while "units of 1" make correct calculations easy, I think that they are a bad idea precisely because they subvert unit checking; it's hard to know just by looking that 1 + 1 is 1 speed of light + 1 light-year, and hence dimensionally inconsistent.
(Even keeping all SI units can miss some important distinctions; for example, nothing about their SI units (inverse time) allows us to distinguish angular frequency (https://en.wikipedia.org/wiki/Angular_frequency) from temporal frequency (https://en.wikipedia.org/wiki/Frequency), and yet much woe accrues to he or she who does not distinguish radians/time from cycles/time!)
My middle school physics teacher taught us to build those formulas by reverse-engineering the units. This was before we had done enough algebra to know what we're doing so we used triangle diagrams, but boy was it the best thing I ever learned.
Don't understand what something is? Just look at the unit. It tells you!
This reminds me of the way Big Brother is working on a new language that doesn't have words for things you're not allowed to do - if there's no word for it, how can you think about doing it?
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/.
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!