Sunday, December 22, 2013

Fixing a random error

After struggling to write my second RCE note I had to come across a IAT rebuilder for x64 applications (not x64 IAT rebuilder for x86 applications!):

CHimpREC-64
http://www.woodmann.com/collaborative/tools/images/Bin_CHimpREC_2008-6-24_13.59_CHimpREC.zip

Surprisingly, an error popped up:

The application has failed to start because the side-by-side configuration is incorrect please see the application event log or use the command line sxstrace.exe tool for more detail.

So I had to fire up sxstrace.exe Trace -logfile:SxsTrace.etl
and
sxstrace.exe Parse -logfile:SxsTrace.etl -outfile:SxsTrace.txt

Opening SxsTrace.txt to find a fatal error on last few lines:

ERROR: Cannot resolve reference Microsoft.VC80.MFC,processorArchitecture="amd64",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50727.762".
ERROR: Activation Context generation failed.


It has something to do with VC8.0. . . what could it be?

Yes. . . I didn't have VC++ on my laptop!!

Hurriedly I downloaded and installed the following

Microsoft Visual C++ 2008 SP1 Redistributable Package (x64):
http://www.microsoft.com/en-us/download/details.aspx?id=2092

Then the program ran as normal. . .

SPOILERS:  You can guess what is featured in my 2nd RCE note. . .

Saturday, December 21, 2013

RCE Notes (1)



DISCLAIMER: THE FOLLOWING TEXT IS FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR OF THIS TEXT DOES NOT ADVOCATE OR ENCOURAGE ILLEGAL PRACTICES IN ANY FORM. THE AUTHOR OF THIS ARTICLE IS NOT RESPONSIBLE FOR ILLEGAL USE OF THIS TEXT. ANY COMMERCIAL/MALICIOUS USES BASED ON THE TEXT ARE SOLELY THE READER'S LIABILITY.

Globeriz Project
by Globeriz
Submitted on: 21 Dec 2013
Analysis started: 20 Dec 2013
---------------------------------------------------------------------------------------------------------------------------
Product Name: JoyToKey
Version: 5.4.2 (5.42.305)
Official Website:http://joytokey.net/en/
Main executable: JoyToKey.exe
Executable size: 1.62MB (1,629,184B)
MD5: 88defd0e09b0d0759f268ab7689388df
SHA-1: e1d3f28a96b8d767ce6c3943ef9f9ea66b263f76
---------------------------------------------------------------------------------------------------------------------------
Product Desciption (according to official site):
JoyToKey (or Joy2Key) enables PC game controllers to emulate a mouse and the keyboard input, so that windows applications and web games can be controlled with your favorite joysticks! Whenever joystick buttons and sticks are pressed, JoyToKey converts them into keyboard strokes and/or mouse movements so that the targeted application will work as if you are using a real keyboard and a mouse!
---------------------------------------------------------------------------------------------------------------------------
Screenshot of Application (click to enlarge:


---------------------------------------------------------------------------------------------------------------------------
Difficulty level: Easy[ ] Normal [x] Hard [ ] Insane [ ] Nightmare [ ]
---------------------------------------------------------------------------------------------------------------------------
Achieved:
License key sniffing [20 Dec 2013]
KeyGen [21 Dec 2013]
---------------------------------------------------------------------------------------------------------------------------
//start
PEiD:Borland C++ 1999 //no shell, yay!

Observations:
Unlicensed product diaplays [Unregistered] in title bar
New files created after closing application for first time
License code input in format XXXX-XXXX-XXXX
Shows popup window if registration failed/succeeded
No interesting changes to registry

Notations:
a""                    ASCII literal
<licenseKey>                placeholder for license Key, e.g. 1234-5678-ABCD
Assumption(s):
Valid license key characters: ABCDEFGHJKLMNPQRSTUVWXYZ123456789

Magic string(s):
ABCDEFGHJKLMNPQRSTUVWXYZ123456789 //missing I, O and 0
DEKIMOUSE
JTE4

Sniffed License Key(s):
[withheld]

Validation files:
JoyToKey.ini
            Essential Content:
            [License]
            Key=<licenseKey>

Notes on runtime debugging:

Loop for serial calculation
00426032  |> 8B45 FC        |MOV EAX,DWORD PTR SS:[EBP-4]
00426035  |. F7EE           |IMUL ESI
00426037  |. 03C7           |ADD EAX,EDI
00426039  |. 8945 FC        |MOV DWORD PTR SS:[EBP-4],EAX
0042603C  |. FF45 F4        |INC DWORD PTR SS:[EBP-C]
0042603F  |. 035D F8        |ADD EBX,DWORD PTR SS:[EBP-8]
00426042  |. 837D F4 04     |CMP DWORD PTR SS:[EBP-C],4
00426046  |.^7C CC          \JL SHORT JoyToKey.00426014

//asm note: IMUL ESI --> eax *= esi

//1.loop start
1. //hypothesis: calculation based on a"4"
eax=0x00
edi=0x1b
esi=0x21           //suspected CONSTANT
[edx]=a"456789"
2. //a"E"
eax=0x37b+0x04=0x37f             //0x1b * 0x21 = 0x37b
ebx=<part of JTE4>      //[ebp+8]=a"JTE4"
[edx]=a"EFG...789"       //EFGHJKLMNPQRSTUVWXYZ123456789
edi=0x04
3. //a"T"
eax=0x735f+0x11=0x7370         //0x37b * 0x21 = 0x735f
edi=0x11
[edx]=a"TUV...789"        //TUVWXYZ123456789
4. //a"J"
eax=0xee170+0x08=0xee178
edi=0x08
[edx]=a"JKL...789"
// end of first loop
//extra: [esp-4]=a"ABC...789"
//We can then establish a"4ETJ" = 0xee178

//Main Analysis:
(1) Odd-looking string literal
004038C1    |. BA E2975400    MOV EDX,JoyToKey.005497E2                ;  ASCII "DEKI-MOUS-E"

(2) Loop for calculating first 8 digits
00426011  |. 8945 F4        MOV DWORD PTR SS:[EBP-C],EAX
00426014  |> 33FF           /XOR EDI,EDI
00426016  |. 33C0           |XOR EAX,EAX
00426018  |. 8B15 307A5500  |MOV EDX,DWORD PTR DS:[557A30]           ;  JoyToKey.00557A06
0042601E  |. 3BF0           |CMP ESI,EAX
00426020  |. 7E 10          |JLE SHORT JoyToKey.00426032
00426022  |> 8A0B           |/MOV CL,BYTE PTR DS:[EBX]           //start of nested loop
00426024  |. 3A0A           ||CMP CL,BYTE PTR DS:[EDX]
00426026  |. 75 04          ||JNZ SHORT JoyToKey.0042602C
00426028  |. 8BF8           ||MOV EDI,EAX
0042602A  |. EB 06          ||JMP SHORT JoyToKey.00426032
0042602C  |> 40             ||INC EAX
0042602D  |. 42             ||INC EDX
0042602E  |. 3BF0           ||CMP ESI,EAX
00426030  |.^7F F0          |\JG SHORT JoyToKey.00426022
00426032  |> 8B45 FC        |MOV EAX,DWORD PTR SS:[EBP-4]
00426035  |. F7EE           |IMUL ESI
00426037  |. 03C7           |ADD EAX,EDI
00426039  |. 8945 FC        |MOV DWORD PTR SS:[EBP-4],EAX
0042603C  |. FF45 F4        |INC DWORD PTR SS:[EBP-C]
0042603F  |. 035D F8        |ADD EBX,DWORD PTR SS:[EBP-8]
00426042  |. 837D F4 04     |CMP DWORD PTR SS:[EBP-C],4
00426046  |.^7C CC          \JL SHORT JoyToKey.00426014
00426048  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]

//psuedo-code translation for loop above:
00426011  |. 8945 F4        [EBP-C]:=EAX
00426014  |> 33FF           /EDI:=0
00426016  |. 33C0           |EAX:=0
00426018  |. 8B15 307A5500  |EDX:=0x00557a06           ;  JoyToKey.00557A06 //=a"ABC..789" (null-terminated ASCII string), i.e.[edx]=a"ABC...789"
0042601E  |. 3BF0           |setflags (ESI-EAX)     //note: ESI=0x21
00426020  |. 7E 10          |if (ESI>=EAX) then goto JoyToKey.00426032 //skips nested loop
00426022  |> 8A0B           |/CL:=first char of EBX            //start of nested loop, note:[ebx]=a"<licenseKey>"
00426024  |. 3A0A           ||setflags CL-<first char of EDX>
00426026  |. 75 04          ||if CL != <first char of EDX> then goto JoyToKey.0042602C //INC EAX
00426028  |. 8BF8           ||EDI:=EAX
0042602A  |. EB 06          ||goto JoyToKey.00426032 //MOV EAX,DWORD PTR SS:[EBP-4]
0042602C  |> 40             ||EAX++
0042602D  |. 42             ||IEDX++
0042602E  |. 3BF0           ||setflags (ESI-EAX)
00426030  |.^7F F0          |\if (ESI>EAX) then goto JoyToKey.00426022   //while loop condition -> start of nested loop
00426032  |> 8B45 FC        |MOV EAX,DWORD PTR SS:[EBP-4]
00426035  |. F7EE           |EAX:=EAX*ESI
00426037  |. 03C7           |EAX:=EAX+EDI
00426039  |. 8945 FC        |DWORD PTR SS:[EBP-4]:=EAX
0042603C  |. FF45 F4        |INC DWORD PTR SS:[EBP-C]
0042603F  |. 035D F8        |EBX=EBX+EBP-8]
00426042  |. 837D F4 04     |setflags ([EBP-C]-4)             //number of digits checked
00426046  |.^7C CC          \JL SHORT JoyToKey.00426014
00426048  |. 8B45 FC        EAX:=DWORD PTR SS:[EBP-4]

//C++ for above routine:
{
edi = 0;
eax = 0;
*ebx = "XXXX-XXXX-XXXX";
*edx = "ABCDEFGHJKLMNPQRSTUVWXYZ123456789";
if (eax <= esi) goto loc0 //esi=0x21
            do {
            cl = ebx[0];
                        if (cl != edx[0]) {
                                    eax++;
                                    edx++;
                        } else {              //ebx[0] = edx[0]
                                    edi = eax;
                                    goto loc0
                        }
            } while (esi>eax)
loc0:
. . .
eax=eax*esi+edi;
. . .
}

(3) Loop for calculating last 4 digits:

//Note: EBX=last 4 digits
//EAX=EBP-1C   > 00557A06  ASCII "ABCDEFGHJKLMNPQRSTUVWXYZ123456789"
 step 4 each recursion, i.e. "GHJK...6789" -> finally "9999"

00537778  |> 8B10           /MOV EDX,DWORD PTR DS:[EAX]
0053777A  |. 83C0 04        |ADD EAX,4
0053777D  |. 8BCA           |MOV ECX,EDX
0053777F  |. 81EA 01010101  |SUB EDX,1010101
00537785  |. 81E2 80808080  |AND EDX,80808080
0053778B  |.^74 EB          |JE SHORT JoyToKey.00537778
0053778D  |. F7D1           |NOT ECX
0053778F  |. 23D1           |AND EDX,ECX
00537791  |.^74 E5          \JE SHORT JoyToKey.00537778

(4) Key comparison location:
00426139  |. 3BF0           CMP ESI,EAX             //EAX=calculated serial, ESI=calculated "JTE4"=0xee178
//Note: If calculated serial = calulated "JTE4" then verification will succeed
Some selected calulated serials:
//Call first 4 digits group1, middle 4 digits group2, last 4 digits group3. . .
Serial                            Calculated serial
AAAA-AAAA-AAAA       0x0
AAAA-AAAA-AAAB       0x1
AAAB-AAAA-AAAA       0x1
AAAB-BAAA-AAAB       0x1                   //interesting. . . looks like a comparison of each group (groups of 4 digits)
AAAB-AAAA-AAAC       0x3
AAAC-AAAA-AAAB       0x3
9999-AAAA-AAAB         0x121881
//so I assume the result is group1+group2+group3
AAAA-AAAB-AAAA       0x8c61              //=0x01*0x21*0x21*0x21
AAAA-AAAA-AAA9        0x20
//Now, we can see the calculation is in radix 20
AAAA-AAA9-AAAA        0x118c20          //=0x20*0x21*0x21*0x21
//Since 0x118c20 > 0xee178, we can use the last 4 digits to calculate the correct serial while the first 8 digits can be totally random
//Now, see if we can reduce to 3 check digits
AAAA-AAA9-A9AA        0x8820
//So no, we must use 4 check digits
9999-9999-9999             0x121880          //wait. . . the value isn't quite right. . .I assume group1+group2+group3 ?
9999-9999-AAAB           0x1                   //wtf?
3333-3333-AAAB           0x1
AAAB-BAAA-AAAC       0x2                  
//if group1=group2 then take group3?
ZXCV-VCXZ-AAAB        0x1
//What if group2=group3?
AAAB-VBNM-MNBV      0x1
//What if group1=group3?
EGHJ-AAAB-EGHJ        0x8c61
EGHJ-AAAA-AAAA       0x24bf9                        //well. . . maybe it's more complicated than I think?
9997-8999-9999             0x121881         
//I give up. . .better look into the actual code closely. . .
0042612B  |. 8B4D D8        MOV ECX,DWORD PTR SS:[EBP-28]                       //[ebp-28]=result of group2, [ebp-48]=result of group1, [ebp-58]=result of group1
0042612E  |. 8BD0           MOV EDX,EAX          //eax=result of group3
00426130  |. 33CF           XOR ECX,EDI             //edi=result of group1
00426132  |. 83C4 08        ADD ESP,8
00426135  |. 8BC1           MOV EAX,ECX
00426137  |. 33C2           XOR EAX,EDX
00426139  |. 3BF0           CMP ESI,EAX
//therefore. . . EAX at last line is calculated as follows:
ecx = g2
edx = g3
ecx = ecx xor g1
eax = ecx
eax = eax xor edx
//i.e.
eax = (g2 xor g1) xor g3 = g1 xor g2 xor g3
//Now the calculation of serial is clear, we have to reverse the process to write a keygen
//Using properties of xor:
a xor b = c <--> a = c xor b
//We want to let eax=0xee178, so we must find g1,g2,g3 such that
g1 xor g2 xor g3 = 0xee178
g1 = 0xee178 xor g2 xor g3       //where g2,g3 can be random
//Now it's left to check if solution of g1 falls within range:
0x0 =< g1 =< 0x121880 <--> 0x0 =< 0xee178 xor g2 xor g3 =< 0x121880
//There exists some combination of g2 and g3 that doesn't satisfy the constriant above
//In fact, to satisfy the constraint, g2 xor g3 < 0xee178
(5) Algorithm draft:
Format:
XXXX-XXXX-XXXX
Order:
[1][2][3][4]-[8][7][6][5]-[9][10][11][12]
Range of a group:
0x0~0x121880
Range of calculated serial:
0x0~0x1FFFFF
Keygen can be composed by 2 parts:
1. Calculation of serial in each group
2. Calculation of check digits
Flowchart of keygen:
Generate random first 8 digits -> calculate the two groups -> check if 0xee178 xor g1 xor g2 =< 0x121880 ->
yes: Calculate g3 -> Full license key is given
no: Regenerate random first 8 digits, start over
//Now we can write a keygen using our favorite program, and we are done.
//end
---------------------------------------------------------------------------------------------------------------------------
Test your understanding:
1. Complete the unknown part of the license key to make it usable: GLOB-ERIZ-xxxx
2. Write another keygen that allows user to input the first 7 digits and the keygen will calculate the rest to make it usable.
3. Is there any problem if the keygen allows user to input 8 digits instead of 7?
4. Try to make a patch for the program to force it accept any license keys.