SalesAgent 3.0 BUY NOW Cracking (Goth)
Well, I assume that you've taken all obligatory precautions
(backup the registry and such ...), installed our target and restarted
Win95.
PART I - Look what the cat dragged in
First you'll see how our target behaves. Start your program. You'll get the usual
'Time Trial' window. We won't bother to 'Try first' head right to 'Buy now'. Fill in
some stuff and push 'Next' until you reach the 'Select Payment Method' window. Now,
do you have your credit card info handy? If not, you should reverse our target to
see which numbers are valid or visit some fancy hacker site and get a credit card
generator (e.g. CreditMaster) or simply enter:
Card: American Express
No.: 00000000
Exp.: 01/05
Name: Goth
And push 'Next' until you get to the 'Select Communication Methods" window. For various
reasons it's necessary to make sure you CAN'T connect to anything, switch off your modem,
cut your cable or whatever and push 'Next'. Oops, unable to connect and so on. Cancel the
whole 'Buy now' thing.
Now, you could observe our target with trial period expired. But you all know what will
happen, don't you? Yes, the 'Try first' button will vanish and it WON'T come back if you
set your RTC back. Well, it's a time trial. So at this point you could have the bright
idea to fire up SoftICE, bpx GetSystemTime, track down the bytes to patch in the EXE/DLL
and ready you are.
- NO YOU DON'T!
What you'll do at this point is pushing 'Buy now' again. (Sometimes when I get these
strange attacks of dumbness, I can't believe there's a 'Buy now' button but no way to
enter any registration code or such and I'll try again... ;-)
You see all fields of your 'User Registration' window filled with information you've
entered before. Close the program and start again. Info is still there. SalesAgent
stores user info somewhere!
PART II - The Anatomy of SalesAgent 3.0
You should now examine our target's files to get a rough overview of what's going on. Well,
five should be more than enough I took a deep look at RSAGNT32.DLL. Use BRW and/or W32dasm.
Look at the import and export tables, resources, headers and so on ... Check if they're
encrypted/compressed. Use your imagination. What file can perform what task? How does the
scheme work? FEEL it ...
Having felt enough you should come at least to these results:
- If your program has more than one EXEs, they all have the same size
=> can't be the real EXEs => some kind of loader
- ********.DL_s are encrypted => the real EXEs will be loaded, decrypted, whatever ...
RSAGNT32.DLL connects to internet server, contains resources for
ENTERING REGISTRATION CODE
Now, how does our start process look like?
You start the program which uses RSAGNT32.DLL to check if you're in your trial period and
then presents the 'Trial' window. If you push 'Try first' the encrypted DL_ is being
temporary decrypted and started. If you push 'Buy now' the RSAGNT32.DLL is used for
getting user information, internet connection and REGISTRATION. After registration
the *.DL_ files should be permanently decrypted.
So how do we get RSAGNT32.DLL to let us register?
PART III - Faking a mail/fax order
I've used W32Dasm to disassemble RSAGNT32.DLL. First I examined it's import table to see
what it is able to and to look for suspicious imports. Huh, you'll find a lot. What should
make your bells ring is that it's able to modify registry entries but also uses the absolete
PrivateProfileString (*.INI) stuff. This needs further investigation.
W32dasm finds the first appearance of GetPrivateProfileStringA here:
...
* Reference To: KERNEL32.GetPrivateProfileStringA, Ord:0112h
|
:100015EE 8B35A8010210 mov esi, dword ptr [100201A8]
* Possible StringData Ref from Data Obj ->"rsagent.ini"
|
...
Oops, it tries to read from a file called RSAGENT.INI And where are these *.INI thingies
usually kept? Right, we'll find it in our 'Windows' directory:
[ReleaseSoft]
firstName=Goth
lastName=Nosferatu
company=!
street1=!
street2=!
city=!
state=
zip=12345
country=United States
geoType=110
phoneNum=!
faxNum=!
email=!
personalCode=
toneDial=1
callWait=0
needAccess=0
accessCode=9
intlPrefix=
callWaitStr=
mailStat-975135=0
ATTN=AT
MTONEDIAL=T
PULSEDIAL=P
DIALTHIS=D
WORDRESULT=V1
HANGUP=H0
ADDINIT=E0
ESCAPE=+++
OKAY=OK
NOCARRIER=NO CARRIER
CONNECTED=CONNECT
NODIALTONE=NO DIALTONE
BUSY=BUSY
|
It wasn't there right after the installation. So it must have been created while we tried
to register the target in PART I. Examine it. Look for something that could help us to
register. Well, till 'email=!' (Yes, I'm a lazy bastard. I entered all these '!')
nothing of importance. But wait, 'personalCode='!
Where have we seen this before? If you did as I told you in PART II you would know where.
Use BRW. Look at dialog 2011! What is this dialog's title? 'Complete Mail / Fax Payment'!
Hm, Mail?, Fax? can't remember any Mail / Fax order opportunity during 'Buy now' procedure.
Take a look at dialog 2001. Our old friend from PART I 'Select Communication Method' but
this dialog allows ordering by phone and mail/fax. So it should be possible to get to
dialog 2011 without completing the internet/modem connection!
All entries are pretty self explainary but what's about this 'mailStat-975135=0' entry?
Let's change it to 1, restart NU and try 'Buy now' procedure again. Anything changed? Of
course! We are finally at dialog 2011. There we have a 'Personal Code' and what we
haven't is an 'Unlocking Code'. But not for long ...
PART IV - RSAGNT32.DLL's builtin KeyGenerator
We know that our 'Unlocking Code' will be recieved by dialog 2011. So you should
bpx GetDlgItemTextA in SoftICE. Enter a dummy unlock code (e.g. gothtog) and after
pressing F12 SoftICE will popup here:
:10005612 mov edi, 10032E20 <= our unlocking code
:10005617 or ecx, FFFFFFFF
:1000561A xor eax, eax
:1000561C repnz
:1000561D scasb
:1000561E not ecx
:10005620 dec ecx
:10005621 cmp ecx, 0000000A <= is it 10 chars long?
:10005624 je 10005665 <= Yes! => Go for validation check!
:10005626 lea edx, dword ptr [esp+10] No! => ...
* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is not valid for
this program."
|
:1000562A push 10023890
:1000562F push edx
:10005630 call 10014590
Step over the next instructions, toogle zero flag at 10005624 and step on till you reach:
:100056A8 push ecx
:100056A9 push edx
:100056AA push eax
:100056AB call 1000B980 <= calculate the real code
:100056B0 add esp, 0000000C
:100056B3 lea ecx, dword ptr [esp+000000D8]
:100056BA push 10032E20 <= our code
:100056BF push ecx <= real code
:100056C0 call 1001F5C0 <= compare
:100056C5 add esp, 00000008
:100056C8 test eax, eax <= if compare fails (eax!=0)
:100056CA jne 1000597C <= we'll get 'Sorry, that...'
... ...
At 100056BA we dump ecx and get a perfect 10 chars long unlock code like: 'RQXKNKQJPP'
(This code is only valid if your personal code was '1234567890' and the program was
Dreamweaver! BTW, you the unlock codes changes if you modify your 'personalCode' entry
and your 'mailStat-975135' in RSAGENT.INI!) Leave SoftICE (F5). Enter the unlock code
and we get a 'Enter your serial' window. (Weird!) Here we enter our unlock code again and
it's done!
PART V - Summary and Additions
We won't have to deal with any encryption routines since SalesAgent 3.0 can be defeated
in less than 2 min:
- change 'personalCode=' to 'personalCode=1234567890' and 'mailStat-975135=0' to
'mailStat-975135=1' in RSAGENT.INI (if there's no RSAGENT.INI create one!)
- start the 'Buy now' procedure and
- enter 'RQXKNKQJPP' as unlock code (only if your cracking Dreamweaver)
|
SalesAgent 3.0 TRY FIRST Cracking (Victor Porguen)
Back in the 'old days' we used to create reasonably deceptive viruses that used 'stealth'
techniques to hide code changes from CRC and integrity checkers. Simply put, when the
integrity checking routine opened the file, or made a file read, the viral code would
substitute the correct code in place of the modified code thus preventing detection
regardless of the complexity of the CRC algorithm. This same concept can be applied
to cracking time limited programs that go to the trouble of checking the integrity of
the executable from the disk file (as opposed to checking the code while it is in
memory).
Programs protected by SalesAgent's can have the common x-day Try-Buy interface that we
have all grown to know and love. An example of this could be WinFAX Pro 9.0 from Symantec,
which is the example program for this essay. Cracking the date limitation while SoftICE is
loaded in memory is a rather trivial exercise. Nevertheless we must first address the
actual 'crack' before we can examine the more interesting aspect of defeating the file
integrity check. The usual methods of tracing through the code, setting appropriate
breakpoints, and so forth will lead you to the routine that awaits the 'click' on either
the 'Buy Now', 'Try First' or 'Cancel' option - of course, the 'Try First' option is
disabled after 30 days. One of the simplest methods for locating this area of code is to
place a breakpoint on DialogBoxParamA. When SoftICE pops up, F11 will execute the CALL,
click on 'Try First' and SoftICE will pop up once more, and then F12 will break on the
RETurn out of the subroutine, which will be OFFSET 00408BA7. You will now be sitting
smack dab in the middle of the date checking routine and the necessary crack should be
readily apparent. Here is the disassembly:
:00408B75 A3E8864300 MOV [004386E8],EAX
:00408B7A 892D14864300 MOV [00438614],EBP
:00408B80 E84B960100 CALL 004221DO
:00408B85 83C408 ADD ESP,08
:00408B88 85CO TEST EAX,EAX
:00408B8A 751D JNZ 00408BA9
:00408B8C 6868044300 PUSH 00430468
:00408B91 68A0834300 PUSH 004383AO
:00408B96 E835960100 CALL 004221DO
:00408B9B 83C408 ADD ESP,08
:00408B9E 85CO TEST EAX,EAX
:00408BAO 7507 JNZ 00408BA9
:00408BA2 E809D5FFFF CALL 004060BO
:00408BA7 EB05 JMP 00408BAE
:00408BA9 B801000000 MOV EAX,00000001
:00408BAE 83F8FF CMP EAX,-01
:00408BBI 55 PUSH EBP
:00408BB2 7514 JNZ 00408BC8
:00408BB4 FF1540D24200 CALL [USER32!PostQuitMessage]
A two second review of this disassembly reveals the fact that if the program executes the
instruction at 00408BA9 there will be no expiration of the program. Further, if the program
does NOT execute the CALL at 00408BA2 the "nag" screen will never display.
From these two facts flow the obvious conclusion that if the CALL at 00408B80 returns EAX
as anything but zero, then the program will be cracked. Setting the system date forward to
expire the program and setting a breakpoint on 00408B8A and 'forcing the jump' through
manual clearing of the zero flag while under SoftIce confirms that this is indeed the
crack. When I first attacked this program I thought to myself 'Hmm, that was rather
disappointing ... only five minutes to crack the program.'
However, when I made the actual byte change in the diskfile FAXMNG32.EXE, it produced page
faults. I immediately assumed I had mistyped the patch (which was nothing more than
making the conditional jump unconditional). However, under SoftICE the patch was
exactly as it should be - and there was no theoretical reason that this patch should
create page faults unintentionally, therefore the page faults must be on purpose
(and I couldn't have been more pleased). The first step, of course, was to set a
debug register breakpoint for memory reads on the one-byte patch to see if the integrity
routine was checking memory. It wasn't, so the only other possibility was that it was
checking the file from the disk. Setting a breakpoint on CreateFileA and reviewing the
names of the files that were to be opened confirmed that the program was indeed checking
itself on disk - and not just once, it was running a thread in the background that was
constantly checking the integrity of the file. How nice. Simply renaming the file and
keeping a copy of the original file intact was not the solution since the program was
bright enough to actually open and check the file under the name that it was executing
as well as the correct name of FAXMNG32.EXE.
It is at this point that we address the issue for which this essay is really named:
Defeating File Integrity Checks Through Redirection. The first step in the process is
determining the location of the CALL that is opening FAXMNG32.EXE for checking.
Setting a breakpoint on CreateFileA as detailed above finds the call in jiffy-quick time.
Here is the disassembly of the call that repeatedly opens FAXMNG32.EXE and which we will
'cut out' below:
:00421B72 55 PUSH EBP
:00421B73 51 PUSH ECX
:00421B74 53 PUSH EBX
:00421B75 52 PUSH EDX
:00421B76 50 PUSH EAX
:00421B77 FF1568D04200 CALL [KERNEL32!CreateFileA]
:00421B7D 8BF8 MOV EDI,EAX
The next step is to find an area of code that is suitable to hold our 'stealth' routine
that will substitute an 'unhacked' copy of the file for the cracked copy. If we look back
to where we know we must insert the crack we see the CALL 004221D0 at offset 00408B80,
which we know is the key to defeating the date check. If this code routine is not called
elsewhere in the program, we can use that code area to house our routine and have that
CALL return EAX as nonzero (which is the CRACK!). Setting a breakpoint on 004221D0
confirms that the routine is only used to check the date, thus we now have room to work.
First, we apply the crack so that the CALL at offset 00408B80 always returns EAX as non-
zero. Putting the value of one in AL and RETurning will do nicely. Thus we now have the
following short crack code at offset 004221D0:
:004221DO BOO1 MOV AL,01
:004221D2 C3 RET
Now we must create the routine, right after the short crack code, that will check the name
of the file that is to be opened and, if it is the target file FAXMNG32.EXE, change the
name to be opened to a file that is identical but unhacked ("virgin"). If it is not the
target file, simply open whatever file is named and chain back to the correct code. If it
is the target file, open the 'virgin' file that is identical to the original unhacked
FAXMNG32.EXE, and then chain back to the correct code. For the "virgin" file I chose to
name it !AXMNG32.EXE because of the simplicity of changing one letter in the name. Here
is a disassembly of the code that
1) Scans the address on the stack for zero, indicating the end of the filepath name
2) Checks the name of the file, and if it is the target file, replace the first letter
of the name with an "!", which is the name of the virgin file
3) Open the file (whether the name was changed or not) and JMP back to the correct code.
:004221D3 5B POP EBX
:004221D4 53 PUSH EBX
:004221D5 8A03 MOV AL,[EBX]
:004221D7 43 INC EBX
:004221D8 OACO OR AL,AL
:004221DA 75F9 JNZ 004221D5
:004221DC 83EBOD SUB EBX,OD
:004221DF 813B4641584D CMP DWORD PTR [EBX],4D584146
:004221E5 7515 JNZ 004221FC
:004221E7 817B044E473332 CMP DWORD PTR [EBX+04],3233474E
:004221EE 750C JNZ 004221FC
:004221FO 817B082E455845 CMP DWORD PTR [EBX+08],4558452E
:004221F7 7503 JNZ 004221FC
:004221F9 C60321 MOV BYTE PTR [EBX],21
:004221FC FF1568D04200 CALL [KERNEL32!CreateFileA]
:00422202 E976F9FFFF JMP 00421B7D
The final step is to write the 'cut out' code, which is simply nothing more than replacing
the CALL CREATEFILEA with a jmp to our stealth routine. Here is the disassembly of the code
that is listed above after the six byte 'cut-out' patch:
:00421B72 55 PUSH EBP
:00421B73 51 PUSH ECX
:00421B74 53 PUSH EBX
:00421B75 52 PUSH EDX
:00421B76 50 PUSH EAX
:00421B77 E957060000 JMP 004221D3
:00421B7C 90 NOP
:00421B7D 8BF8 MOV EDI,EAX
That's it. The program is now completely cracked. The background thread that continually
checks the file integrity is redirected to a virgin copy of the executable each time it is
called - which of course allows it to pass any CRC, checksum, or similar algorithm.
As a final note, I will point the reader to http://www.releasesoft.com,
who apparently authored the 'integrity checking system' that Symantec used on WinFax.
Apparently, the protection system is quite widespread. Pity, really.
|
|