Archive for the ‘Chal12. Twist1 Challenge’ Category

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”.