soffensive blog

Small challenge from Gynvael Coldwin

Gynvael Coldwin posted a small challenge at the end of his last podcast on Windows Kernel Debugging with Artem Shishkin:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Welcome back agent 1336.
No mail.
> mission --take
MISSION 012               goo.gl/qudiHJ             DIFFICULTY: ██░░░░░░░░ [2╱10]
┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅

Our agents managed to install a hardware keylogger in suspects computer. After
they retrieved it and dumped the recorded data, here is what showed up:

  58 f0 58 1b f0 1b 58 f0 58 44 f0 44 2d f0 2d 2d f0 2d 35 f0 35 41 f0 41 29
  f0 29 59 43 f0 43 f0 59 29 f0 29 23 f0 23 44 f0 44 31 f0 31 52 f0 52 2c f0
  2c 29 f0 29 1b f0 1b 4d f0 4d 24 f0 24 1c f0 1c 42 f0 42 29 f0 29 12 42 f0
  42 f0 12 24 f0 24 35 f0 35 32 f0 32 44 f0 44 1c f0 1c 2d f0 2d 23 f0 23 49
  f0 49

Could you help us decoded it to know what was typed?

Good luck!

---------------------------------------------------------------------------------

If you decode the answer, put it in the comments under this video! If you write
a blogpost / post your solution online, please add a link in the comments too!

P.S. I'll show/explain the solution on the stream in ~two weeks.

Our first guess was that the characters use some well-known encoding such as ASCII, but this turned out to be wrong assumption. In order to obtain some knowledge about the structure of the recorded data, we ran some statistical analysis of the different byte values:

Practical Reverse Engineering Exercise Solutions: Page 35 / Exercise 7

Exercise 7 on page 35:

Sample H. The function sub_10BB6 has a loop searching for something. First recover the function prototype and then infer the types based on the context. Hint: You should probably have a copy of the PE specification nearby.

Due to alignment issues, our routine is located at 10BB2 and has the following disassembly:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
sub_10BB2:

 mov     eax, [esp+4]   
 push    ebx    
 push    esi
 mov     esi, [eax+3Ch] 
 add     esi, eax   
 movzx   eax, word ptr [esi+14h]
 xor     ebx, ebx
 cmp     [esi+6], bx
 push    edi
 lea     edi, [eax+esi+18h]
 jbe     short loc_10BEB

loc_10BCE:                            
 push    [esp+0Ch+arg_4]
 push    edi
 call    ds:dword_169A4
 test    eax, eax
 pop     ecx
 pop     ecx
 jz      short loc_10BF3
 movzx   eax, word ptr [esi+6]
 add     edi, 28h
 inc     ebx
 cmp     ebx, eax
 jb      short loc_10BCE

loc_10BEB:                              
 xor     eax, eax

loc_10BED:                             
 pop     edi
 pop     esi
 pop     ebx
 retn    8

loc_10BF3:                             
                mov     eax, edi
                jmp     short loc_10BED

The PE file format and offsets have been described in detail here: http://www.sunshine2k.de/reversing/tuts/tut_pe.htm

Practical Reverse Engineering Exercise Solutions: Page 35 / Exercise 6

Exercise 6 on page 35 of the book Practical Reverse Engineering presents us with a malware samples.

These can be downloaded at the following page:

https://grsecurity.net/malware_research/

In this exercise, we are expected to have a look at the following routine sub_13842:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.text:00013842 sub_13842      
.text:00013842                 mov     eax, [ecx+60h]
.text:00013845                 push    esi
.text:00013846                 mov     esi, [edx+8]
.text:00013849                 dec     byte ptr [ecx+23h]
.text:0001384C                 sub     eax, 24h
.text:0001384F                 mov     [ecx+60h], eax
.text:00013852                 mov     [eax+14h], edx
.text:00013855                 movzx   eax, byte ptr [eax]
.text:00013858                 push    ecx
.text:00013859                 push    edx
.text:0001385A                 call    dword ptr [esi+eax*4+38h]
.text:0001385E                 pop     esi
.text:0001385F                 retn

Firstly, we see that the function prototype takes two parameters, which are not saved on the stack but in the two registers ecx and edx. This can be deducted from the fact that these two registers are immediately referenced without prior initialization.

Practical Reverse Engineering Exercise Solutions: RtlValidateUnicodeString

This blog post contains my solution for the decompilation exercise of the RtlValidateUnicodeString function in the Windows Kernel. The following contains the disassembly without annotations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
kd> uf rtlvalidateunicodestring
ntdll!RtlValidateUnicodeString:
77686f6c 8bff            mov     edi,edi
77686f6e 55              push    ebp
77686f6f 8bec            mov     ebp,esp
77686f71 837d0800        cmp     dword ptr [ebp+8],0
77686f75 0f85fc380300    jne     ntdll!RtlValidateUnicodeString+0xb (776ba877)

ntdll!RtlValidateUnicodeString+0x12:
77686f7b 6800010000      push    100h
77686f80 ff750c          push    dword ptr [ebp+0Ch]
77686f83 e809000000      call    ntdll!RtlUnicodeStringValidateEx (77686f91)

ntdll!RtlValidateUnicodeString+0x1f:
77686f88 5d              pop     ebp
77686f89 c20800          ret     8

ntdll!RtlValidateUnicodeString+0xb:
776ba877 b80d0000c0      mov     eax,0C000000Dh
776ba87c e907c7fcff      jmp     ntdll!RtlValidateUnicodeString+0x1f (77686f88)

The function prototype is given here:

Practical Reverse Engineering Exercise Solutions: LiveKd / WinDbg Cheat Sheet

Here are a couple of commands I regularly use for reverse engineering:

  • uf <function>: Unassemble function
  • dt nt!_ktss: Show the definition of the data structure _ktss
  • ?? sizeof(_ktss): Show the size the data structure _ktss occupies in memory
  • .hh uf: Show help for the function uf
  • x nt!*createfile*: Search all functions having the string createfile in its name
  • !vtop <PDPT-pointer> <virtualAddress>: Compute physical address of given virtual address and the pointer to the page directory pointer table

Practical Reverse Engineering Exercise Solutions: KiInitializeTSS

Another exercise for us is the decompilation of the KiInitializeTSS function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
nt!KiInitializeTSS:
82847359 8bff            mov     edi,edi
8284735b 55              push    ebp
8284735c 8bec            mov     ebp,esp
8284735e 8b4508          mov     eax,dword ptr [ebp+8]
82847361 b9ac200000      mov     ecx,20ACh
82847366 66894866        mov     word ptr [eax+66h],cx
8284736a 33c9            xor     ecx,ecx
8284736c 6a10            push    10h
8284736e 66894864        mov     word ptr [eax+64h],cx
82847372 66894860        mov     word ptr [eax+60h],cx
82847376 59              pop     ecx
82847377 66894808        mov     word ptr [eax+8],cx
8284737b 5d              pop     ebp
8284737c c20400          ret     4

We obtain the function prototype: (source)

1
2
3
4
5
VOID
NTAPI
KiInitializeTSS(IN PKTSS Tss)
{
}

Structure of _KTSS: