Simple Reverse - 0x25(2023 Lab - WinMalware - 作業)

Simple Reverse - 0x25(2023 Lab - WinMalware - 作業)

Description

在 next stage payload 的 my_start 導出函數中,惡意程式透過 dynamic API resolution 手法取得了一些 APIs。請問其從 user32.dll 取得的 API 的名稱為何? A list of all exported functions of user32.dll

Flag format: FLAG{WindowsAPIname}

Background

Dynamic API Resolution Background

Recon

根據前一個筆記,我們已經知道他怎麼找API,只是我們還不知道他用的到底是哪一個API,因為他有事先用過hash,題目也是要我們找到這一個部分,最簡單的做法是把user32.dll的所有API都用作者自定義的hash function做一遍,直到找到他要的那一個,目前問題最大的應該是不知道__ROL4__的意思,根據x86 and amd64 instruction reference

The rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit positions, except for the most-significant bit, which is rotated to the least-significant bit location. The rotate right (ROR) and rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except for the least-significant bit, which is rotated to the most-significant bit location.

所以很明顯的,這一段就是把hash左移11次,然後加上1187和api_name的字元

1
2
3
4
5
api_name = dll_base + name_array[k];
hash = 0;
do
    hash += __ROL4__(hash, 11) + 1187 + *api_name++;// do self-defined hash function
while ( *api_name );

Exploit

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
41
42
43
44
45
kernel32_dll = open('./kernel32.dll.txt', 'rb').readlines()
msvcrt_dll = open('./msvcrt.dll.txt', 'rb').readlines()
user32_dll = open('./user32.dll.txt', 'rb').readlines()
kernel32_function_hash = [0x5F00766C, 0x6D555364, 0x42B4FA0, 0xC473C85A]
msvcrt_function_hash = 0xCD841E17
user32_function_hash = 0x416f607


def __ROL4__(v, b, bit_size):
    return (v << b) | (v >> (bit_size - b)) & (2**(bit_size) - 1)

# kernel32 Function Hash Compare
for function_hash in kernel32_function_hash:
    for i in range(len(kernel32_dll)):
        name = kernel32_dll[i].strip()
        hash = 0
        for j in range(len(name)):
            hash += __ROL4__(hash, 11, 32) + 1187 + name[j]
            hash = hash & (2**(32) - 1)
        if hash == function_hash:
            print("[+] kernel32 Function    - " + hex(function_hash) + " is " + name.decode())
            break

# msvcrt Function Hash Compare
for i in range(len(msvcrt_dll)):
    name = msvcrt_dll[i].strip()
    hash = 0
    for j in range(len(name)):
        hash += __ROL4__(hash, 11, 32) + 1187 + name[j]
        hash = hash & (2**(32) - 1)
    if hash == msvcrt_function_hash:
        print("[+] msvcrt Function      - " + hex(msvcrt_function_hash) + " is " + name.decode())
        break

# user32 Function Hash Compare
for i in range(len(user32_dll)):
    name = user32_dll[i].strip()
    hash = 0
    for j in range(len(name)):
        hash += __ROL4__(hash, 11, 32) + 1187 + name[j]
        hash = hash & (2**(32) - 1)
    if hash == user32_function_hash:
        print("[+] user32 Function      - " + hex(user32_function_hash) + " is " + name.decode())
        break
print("Flag = FLAG{" + name.decode() + "}")
1
2
3
4
5
6
7
8
$ python exp-lab-6.py
[+] kernel32 Function    - 0x5f00766c is LoadLibraryA
[+] kernel32 Function    - 0x6d555364 is GetProcAddress
[+] kernel32 Function    - 0x42b4fa0 is VirtualAlloc
[+] kernel32 Function    - 0xc473c85a is FlushInstructionCache
[+] msvcrt Function      - 0xcd841e17 is memcpy
[+] user32 Function      - 0x416f607 is MessageBoxA
Flag = FLAG{MessageBoxA}

結果如上