Wednesday, July 8, 2015

Who bases their product on Mozilla? (I mean, OTHER than Firefox?)

Today's entry is a nameless application that's based on Mozilla's framework.  I'm not sure WHY they did it this way, but it posed some interesting challenges.  To start with, the initial application launcher didn't appear to actually DO anything, and then exited.  I can only assume it did some sort of magic behind the scenes to kick off the application, and then it exits.  It's very small, so I guess that's all it NEEDED to do.  What was kinda interesting, is that it was named the same name as the main executable.  So, if you looked at a task list, you would assume it was the launcher, and not the main application itself.

Once I found the main application, I threw it into IDA like normal, and that reveals nothing worthwhile from the outset, but running it with "Break on DLL load" was VERY informative.  The program loads the usual suspects, and then loads yet ANOTHER xxlicense.dll.  (Name changed to protect the innocent).  I exit the application, and go find xxlicense.dll.  Turns out, it's a screaming 23KB.  At least the LAST target attempted to thwart me by putting their licensing code in a HUGE .dll to make it harder to locate the pertinent bits.  Not so this time.  It's all right there in black and white.  Sorta.  So, I toss that file into IDA, it disassembles nicely, and I figure I'll just go to the exports list, and find the functions that I'm interested in, and start there.  To my surprise, the exports list is almost empty.  It contains 2 entries:  DllEntryPoint, and NSModule.  I've seen this sort of thing in the past when I was tinkering with a COM object's .dll.  So what's going on here?  Well, Mozilla has it's own list of methods that it uses, and IDA doesn't know about them.  (Or at least *I* don't know how to make IDA know about them.)  Either way.  So, no hints about what the functions are named.  We'll have to do it the hard way.  I open the file in Hex Workshop, and examine the strings contained inside.  There are lots of good ones!  I pick a nice one like "'License file ',27h,'%s',27h,' does not exist',0".  Go back to IDA, search for it, and boom.  I now have a pointer back to where the license file is opened.  A careful study of the function shows that it simply opens the file, and calls fgets in a loop to read all the contents into a buffer, after which, it closes the file.  Using IDA's cross reference feature, I see that this function is called from *1* place.  I go to that function, and see that it reads the license file into a buffer, and then passes the buffer to a function that processes it.

It appears that the "fields" in the license are all text, separated by bar "|" characters.  So, there is code to find the first bar, and copy from that point to the end of the license, to a new variable.  They then pass a pointer to this buffer to another function.

In the text area, there are some strings of garbage that aren't ASCII strings.  This always makes me suspicious.  In this case, it was warranted.  We have this:

loc_72AD1730 r
.data:72AD7061                 db 0E0h ; a
.data:72AD7062                 db 0E6h ; µ
.data:72AD7063                 db 0F7h ; ˜
.data:72AD7064                 db 0E0h ; a
.data:72AD7065                 db 0F1h ; ±
.data:72AD7066                 db 0EEh ; e
.data:72AD7067                 db 0E2h ; G
.data:72AD7068                 db 0E7h ; t
.data:72AD7069                 db 0EEh ; e
.data:72AD706A                 db 0E0h ; a
.data:72AD706B                 db 0FCh ; n

The 1st character of that "string" is accessed inside the function that I'm looking at.  It's copied to a buffer, and then there's code that decrypts it.  It's simply XOR'd with 0xA5.  So, looking at the result yields "SECRETKGBKEY".  :-)  Funny guys!

They have that at the start of their buffer, and then copy the rest of the license over to it.  Once they have it all in the same place, they run a simple MD5 against it.  They save off the resultant hash, and return.  The produced hash is then compared against the 1st "field" of the license they read in from the file.  (The data before the 1st bar).  If it matches?  Code is GOOD!

There is one last thing that they do.  Inside the license text is a VERSION of the product.  "Product9" or "Product5".  Even though the hash matches, that doesn't mean that this license is for this version of the product.  So, they compare it.  (After they decrypt it that is!).  So, to keep you from just reading the strings from the .dll, and knowing what to put in the file, they make you work a LITTLE harder.

The product version string is stored with the high bit set, so that makes it also not a visible string when you look for it.  There is a loop that grabs a byte from this "string", ands it with 0x7F, and then compares it to a character from your license.  If they match, it goes on.  Otherwise, the return value is the same as your run of the mill strcmp.  (-1, 0, 1).  Once you product string matches, you're good to go!

One thing you have to be on the lookout for, it expects the LETTERS in your hash to be LOWERCASE.  Uppercase will cause the compare to fail.

So, the steps to make a license.  Take an existing license (Maybe even from another product from the same company!), change the product name to match what you find in the .DLL.  Replace the hash in the 1st field with SECRETKGBKEY.  Generate an MD5 hash on that, and replace SECRETKGBKEY with the hash.  Save, and enjoy your product!






No comments: