Monday, March 21, 2011

*FACEPALM*

This was just too good to not share.

Just had a look at an app for a friend that used a dongle. (Some weird brand/model of dongle that I'd never heard of before). So, I run the normal analysis on the application, and see that the author has chosen to pack his executable. Not a bad idea! If you want to do this for the protection/anti-tamper benefits of a compressed application, I would HIGHLY recommend not using an open source, and publicly available compressor. In this case, it was UPX. (http://upx.sourceforge.net/)

A quick look around the net, and I had an app that not only could tell you ALL about the compression on the app, but also removed it, cleaned up the .exe and everything else. Spit out a virgin looking executable.

So, on to the next step. Load it into IDA, and have a look around. I quickly find the "USB Dongle not found" string, and trace that back to a function that does a couple of things (calls ebp+xxx based functions), and makes a decision about the results. A little digging revealed that they were dynamically loading a DLL from inside themselves, (Almost like a resource), and then doing a loop of "GetProcAddress" to get the addresses of the functions they wanted. Each was stored in an ebp+xxx location. Turns out that he only called the dongle function from 2 places, once on startup, and then he spawned a thread that checked that the dongle was STILL attached every 3 seconds. Not bad dude, not bad at all.

Then, while looking at the functions that called the dongle function, I noticed a comparison of ebp+644, and if this value was 0, it skipped not only the startup check, but didn't create the thread to continuously check the key either. What's going on here?

It was ... A command line option to skip the protection completely. When the program started, one of the first things that he did was to get the command line, and to use strstr to search for his magic string. If found, it would clear the flag, and the protection routines never got executed.

FAIL!

Tuesday, March 1, 2011

The perils of commercial protection

I just finished up looking at a commercial package that runs on Linux, and uses a SmartKey dongle from some guys in Italy. The dongle design looks as good as any other, and as Rainbow used to advertise a long time ago, "people never attack the key". This was true in this case as well. There were 4 or 5 apps in the package that were protected. (They basically just read memory locations from the key to see if the options pertinent to their situation were enabled or not). For instance, the report generation module would check the key to see if the memory location set aside for it had the correct value in it, or not, and used this value to determine whether to generate the reports, or, I don't know, put a "this is a demo version" banner on them or something. Anyway, you get the idea.

Now, on to the perils of commercial protection. Specifically "off the shelf protection". The programmer who wrote the apps seemed like he knew how to write apps, but not really design a good protection system. And it's this scenario that exposes the peril most directly. As I said above, there were 4 or 5 apps that were protected. He wrote them in C, and linked against the library provided by the dongle manufacturer to implement his checks. The big problem here, is that you now have a big glob of code in each of your protected executables that's not only the SAME in every app, but is the heart of your protection system. In a posting prior to this one, I detail how I gutted and "repurposed" a function in the Sentinel .DLL in an app called SNMPc. This would certainly be possible with these apps as well, but instead of gutting a common library, you'd be doing a simple search and replace of some code in each executable. In this particular case, the library contained an error message that would print if something happened to cause the communications with the key to get out of sync. So, the procedure for each app was:

Run through IDA
Search for string
Trace backwards to find caller(s)

Using this technique, I was able to completely understand what data the dongle contained, and how each byte was used in each program. So, instead of providing the protection that the author expected, it actually made his apps EASIER to crack.

In the span of a couple of hours, I was able to rewrite the "checker program" that the client app used to verify your permissions in C, and have it work flawlessly. All with information that I had garnered thanks to the staticly linked routines in his apps.