Archive for January 28, 2016

1.1. First solution

Rule in Readme.txt:

AuthKey = un_md5(DecryptKey) + " " + un_md5(EXE's Key)
 DecryptKey = 1dfb6b98aef3416e03d50fd2fb525600
 EXE's  Key = c944634550c698febdd9c868db908d9d
 => AuthKey = visual studio

Scan this target by ExeInfo PE:


Figure 1

We have “AutoHotkey v1.0.48.05 – AutoIt3 v2.x.x” and ExeInfo recommend us use Exe2Aut to Unpack/Decompile this target. Ok, let’s try to use ExeInfo and here is the result:


Figure 2

Open _myExeToAut.log in the same directory, we will have the first MD5 key “220226394582d7117410e3c021748c2a

-=  myExe2Aut >The Open Source Autoit/AutoHotKey Script Decompiler< 1.92 build(54) =- ================================================================================ Unpacking: C:\Documents and Settings\manowar\Desktop\\Chal13\ahk.exe AU3_Signature: A3 48 4B BE 98 6C 4A A9 99 4C 53 0A 86 D6 48 7D £HK¾˜lJ©™LS †ÖH} Script Type 3.0 found. 00032813 -> SubType: 0x03   áú
~ Note:  The following offset values are were the data ends (and not were it starts) ~
Script is password protected!
00032834 -> Password/MD5PassphraseHash: 3232303232363339343538326437313137343130653363303231373438633261
MD5PassphraseHash_ByteSum: 0000075D  '+ 22AF' => decryption key!

Open another file is ahk.ahk, we get the second key “54593f6b9413fc4ff2b4dec2da337806”:

;<COMPILER: v1.0.48.5>
if (pwd== "54593f6b9413fc4ff2b4dec2da337806"){

Open to decrypt above MD5 keys:


Figure 3


Figure 4

Finally, the right Flag is: isolated pawn

1.2. Second solution

Scan this target by RDG Packer Detector:


Figure 5

RDG shows this target is packed by UPX. Let’s try to use UPX to unpack:


Figure 6

Run unpacked file, we get the error messages:


Figure 7

Let’s open OllyDBG and load packed file, scroll down and put BP at “00471BD9 ^\E9 710FFDFF     jmp     ahk.00442B4F” to manual unpack it:


Figure 8

F9 to run, we stop at BP. F8 to trace over, we stop here:


Figure 9

Search all referenced text strings to find “EXE corrupted”:


Figure 10

Double click on the ASCII “EXE corrupted“, we go to the following address: 0x00448273. Scroll up, we can see the jump that will bypass the error message at “00448265 |. /74 16 je short ahk.0044827D”. So we need to place a breakpoint at the call before this jump:


Figure 11

Then press F9, we’ll stop at bp. Press F7 to trace into this call, then F8 to trace over, the routine will show us the address that store the decryption key:


Figure 12

After finish the call at “0044825E |. E8 64860000 call ahk.004508C7 ; \ahk.004508C7”, we back to the jump that will bypass the the error message at “00448273 |. 68 34E34500   push   ahk.0045E334 ; ASCII "EXE corrupted"” and stop here:


Figure 13

This routine will decompile the file with the decryption key above. After trace over the call at address “00448293 |. E8 078A0000   call   ahk.00450C9F ; \ahk.00450C9F” and follow in dump the address at ECX register, we’ll have the exe’s key:


Figure 14

Finally, visit to decrypt above keys that we get!


The content of Readme.txt file: Twist1.exe is run in x86 windows.

Run Twist1.exe and input fake flag:


Figure 1

Let’s open the target in OllyDBG, search all referenced text strings, we have nothing useful information:


Figure 2

Maybe all strings are encrypted and will be decrypt at runtime. Press F9 to run and search again:


Figure 3

Double-click on the “ASCII “Correct!”,LF”, scroll up and set HWBP on Execute at 00401270   E8 EBFEFFFF call   <Twist1.Nop_call>


Figure 4

Restart OllyDBG and press F9 again, we will break at bp. Trace over these calls like the figure bellow and input the fake flag:


Figure 5

After input fake flag and press enter, we will back to OllyDBG. Then trace into this call:

004012C6       E8 75FFFFFF             call   Twist1.00401240


Figure 6

The input flag will be saved to another location, like this:


Figure 7

After the above loop, the unconditional jump will to 0040720D. At 0040720D, the routine will set some values to 00409150 address. If change these value to disassemble, we have this code:

00409150    B8 9A000000     mov     eax, 0x9A
00409155    BA 0003FE7F     mov     edx, 0x7FFE0300
0040915A    FF12            call    dword ptr [edx]
0040915C  - E9 D41FA400     jmp     00E4B135

At 00407294 address, we see the call to this address: call Twist1.00409150. This call will make debug is crashed. So need some tricks to bypass this call and unconditional jump, we will stop at 004072CF /E9 5C010000 jmp Twist1.00407430:


Figure 8

Continue to bypass some calls and checks that make crash when debug:


Figure 9

We go to the routine that take the seventh character of InputFlag to bl, xor bl with 0x36 and save to ds:[0040C450]:


Figure 10

Then the value at [0040C450] will be compared with 0x36, if not equal will exit routine. So we know that the seventh character of InputFlag must be null value and the length of InputFlag is six:


Figure 11

Next, we will see the validation code for each characters of InputFlag.

  • 1st character:
0040760D     33C0             xor     eax, eax       ; eax = 0
0040760F     A0 90B94000     mov     al, byte ptr [0x40B990]; al = InputFlag[0] (1st char of InputFlag)
00407614     E8 12000000      call    Twist1.0040762B
0040762B     33D2             xor     edx, edx       ; edx = 0
0040762D     C0C8 06          ror     al, 0x6        ; rotate 6 bits right in al
00407630     A2 00B04000      mov     byte ptr [0x40B000], al      ; save al to [0040B000]
00407700     8A0D 00B04000    mov     cl, byte ptr [0x40B000]   ; cl = [0040B000]
004076D0     80F9 49          cmp     cl, 0x49                  ; cl = 0x49?
004076D3     0F85 2C020000    jnz     &lt;Twist1.exit_routine&gt;

The following pseudo code:

InputFlag[0] ror 0x6 = 0x49 -&gt; InputFlag[0] = 0x49 rol 0x6 = 0x52 (‘R’)
  • 3rd character:
00407750     880D E0CC4000    mov     byte ptr [0x40CCE0], cl  ; [0x40CCE0] = InputFlag[2]
0040777D     33C0             xor     eax, eax              ; eax = 0
0040777F     8BC8             mov     ecx, eax              ; ecx = 0
00407781     8BD0             mov     edx, eax              ; edx = 0
00407783     A0 E0CC4000      mov     al, byte ptr [0x40CCE0] ; al = InputFlag[2] (2nd char of InputFlag)
00407788     34 77            xor     al, 0x77    ; al = al ^ 0x77
004077A3     3C 35            cmp     al, 0x35    ; al = 0x35?
004077A5     75 59            jnz     short &lt;Twist1.exit_routine&gt;

The following pseudo code:

InputFlag[2] ^ 0x77 = 0x35 -&gt; InputFlag[2] = 0x35 ^ 0x77 = 0x42 (‘B’)
  • 2nd character:
0040780C     8B0D 80CD4000    mov     ecx, dword ptr [0x40CD80]   ; ecx = InputFlag[1]
004077AC     80F1 20          xor     cl, 0x20                    ; cl = cl ^ 0x20
004077C5     80F9 69          cmp     cl, 0x69                    ; cl = 0x69?
004077C8   ^ 75 F0            jnz     short Twist1.004077BA

The following pseudo code:

InputFlag[1] ^ 0x20 = 0x69 -> InputFlag[1] = 0x69 ^ 0x20 = 0x49 (‘I’)
  • 4th character:
00407838     33C0             xor     eax, eax          ; eax = 0
0040783A     33C9             xor     ecx, ecx          ; ecx = 0
0040783C     33D2             xor     edx, edx          ; edx = 0
0040783E     8A15 F4CC4000    mov     dl, byte ptr [0x40CCF4]   ; dl = InputFlag[3]
00407844     8AC2             mov     al, dl            ; al = dl
00407846     A2 00C44000      mov     byte ptr [0x40C400], al   ; [0040C400]=al
00407829     8A15 00C44000    mov     dl, byte ptr [0x40C400]
0040790E     8A15 01C44000    mov     dl, byte ptr [0x40C401]   ; dl = InputFlag[3]
00407914     80F2 21          xor     dl, 0x21          ; dl = dl ^ 0x21
00407917     C3               retn
00407918     80FA 64          cmp     dl, 0x64          ; dl = 0x64?
0040791B     0F84 AD040000    je      Twist1.00407DCE

The following pseudo code:

InputFlag[3] ^ 0x21 = 0x64 -> InputFlag[3] = 0x64 ^ 0x21 = 0x45 (‘E’)
  • 5th character:
004077D1     8B15 F0CC4000    mov     edx, dword ptr [0x40CCF0]  ; edx = InputFlag[4]
004077D7     8915 30CD4000    mov     dword ptr [0x40CD30], edx  ; ds:[0040CD30]=edx
00407DCE     8A15 30CD4000    mov     dl, byte ptr [0x40CD30]    ; dl = InputFlag[4]
00407E02     80F2 46          xor     dl, 0x46                   ; dl = dl ^ 0x46
00407E19     58               pop     eax
00407E1A     3C 08            cmp     al, 0x8
00407E1C    /75 02            jnz     short Twist1.00407E20

The following pseudo code:

InputFlag[4] ^ 0x46 = 0x8 -> InputFlag[4] = 0x8 ^ 0x46 = 4E (‘N’)
  • 6th character:
0040778C     8A0D E4CC4000    mov     cl, byte ptr [0x40CCE4]      ; cl = InputFlag[5]
00407792     880D F4CF4000    mov     byte ptr [0x40CFF4], cl
004078A6     C005 F4CF4000 04 rol     byte ptr [0x40CFF4], 0x4     ; rotate 4 bits left (0x40CFF4 contains 5th char of InputFlag)
00407F77     8A15 F4CF4000    mov     dl, byte ptr [0x40CFF4]
00407F7D     C605 777F4000 FD mov     byte ptr [0x407F77], 0xFD
00407F84     80FA 14          cmp     dl, 0x14                    ; dl = 0x14?
00407F87     75 36            jnz     short Twist1.00407FBF

The following pseudo code:

InputFlag[5] rol 0x4 = 0x14 -> InputFlag[5] = 0x14 ror 0x4 = 0x41 (‘A’)

Finally, we have the correct flag is : “RIBENA”.


Run FPS.exe, we will start the game with a gun:


Figure 1

Use direction key to move character, we will see the strange doll. They can not die if we shoot them. The game will end if we touch them :).


Figure 2

Let’s use IDA and OllyDBG combination to analyse target. In OllyDBG, search all referenced text strings, we find the “Game Clear” string:


Figure 3

Double clicking on this string will bring us to the routine:


Figure 4

In IDA we have:


Figure 5

With this information, we can see that the text in message box is encrypted. So we need to decrypt this string. Follow in Dump in OllyDBG:


Figure 6

In IDA, select this text and press “X” to find another routine references to it.


Figure 7

Double clicking on sub_403400+2D:


Figure 8

This routine will be used to decrypt the text of message box. First, we see that the eax register is used as index of encrypted string, I named it is Msg_text. Value of eax is set by the call sub_403440, so that eax will have values in range [0…52], ecx = eax * 0x210. Ecx register is used as specific offset to set value to cl, then use xor to decrypt: Msg_txt[eax] = Msg_txt[eax] ^ cl. This is the pseudo-code for the snippet:

unsigned int sub_403400()
unsigned int i; // eax@1
unsigned int j; // ecx@2
int v2; // edx@2

i = sub_403440();
if ( i != 0xFFFFFFFF )
	j = 0x84 * i;
	v2 = dword_409190[0x84 * i];
	if ( v2 &gt; 0 )
		dword_409190[j] = v2 - 2;
		dword_409194[j] = 0;
		Msg_text[i] ^= byte_409184[j * 4];
return i;

Try to set bp and debug in OllyDBG, we know cl register will have value is 0x0, 0x4, 0x8, 0xC,…


Figure 9

Here is the code to find the Flag:

#include <stdio.h>
#include <stdlib.h>

int main()
    unsigned char encrypted_str[52]={0x43, 0x6B, 0x66, 0x6B, 0x62, 0x75, 0x6C, 0x69, 0x4C, 0x45, 0x5C, 0x45, 0x5F, 0x5A, 0x46, 0x1C, 0x07, 0x25, 0x25, 0x29, 0x70, 0x17, 0x34, 0x39, 0x01, 0x16, 0x49, 0x4C, 0x20, 0x15, 0x0B, 0x0F, 0xF7, 0xEB, 0xFA, 0xE8, 0xB0, 0xFD, 0xEB, 0xBC, 0xF4, 0xCC, 0xDA, 0x9F, 0xF5, 0xF0, 0xE8, 0xCE, 0xF0, 0xA9, 0x00};
    unsigned char flag[100]={0};
    int i=0;

    for (i=0; encrypted_str[i]!=0;i++)
        flag[i] = encrypted_str[i] ^ (i*4);
    flag[i] = '\x00';

    printf("The right flag is: %s", flag);
    return 0;

Figure 10