MalwareTech Beginner Malware Reversing Challenges shellcode1 Writeup
16 Feb 2019Environment
- Host OS: Kali linux 2018.4
- Guest OS: Windows 7 Home Basic
- Virtualization: Virtualbox 5.2.22
- Debugger: IDA Pro 7.0
Explanation
We have several malware reversing challenges this page on MalwareTech
This is a write-up of “shellcode1”.
shellcode1.exe contains a flag stored within the executable. When run, the program will output an MD5 hash of the flag but not the original. Can you extract the flag?
Solution
1. Opening the shellcode1.exe
Let’s open the shellcode1.exe.
As we can see on a following picture, it shows a MD5 encrypted flag.
Just like strings challenges, we have to “decrypt” this MD5 hash and get original text.
2. Analyzing assembly code
Same as last challenge, to encrypt the original text, a function MD5:digestString is used.
It’s argument is in an offset “Str” and it must be a text which we’re looking for.
However, it is already encrypted and sounds like does not mean anything.
In this assembly code, we can find the “offset Str” one more time.
As we can see, it’s getting the length of Str and storing it into [ecx+4].
Then, figure out what it ecx.
Sounds like the value of ecx is return value of HeapAlloc.
DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
HANDLE hHeap, // A handle to the heap from which the memory will be allocated. This handle is returned by the HeapCreate or GetProcessHeap function.
DWORD dwFlags, // The heap allocation options.
SIZE_T dwBytes // The number of bytes to be allocated.
);
And the return value is a pointer to the allocated momory block.
This means, after these instructions below, values of ecx and ecx+4 are
ecx: pointer to allocated heap
ecx+4: length of Str
Then we still have 3 functions which we have to analyze.
call ds:VirtualAlloc
call memcpy
call [ebp+Dst]
Sounds like return value of VirtualAlloc is set in [ebp+Dst].
According to the official document, the arguments of VirtualAlloc are
LPVOID VirtualAlloc(
LPVOID lpAddress, // The starting address of the region to allocate.
SIZE_T dwSize, // The size of the region, in bytes.
DWORD flAllocationType, // The type of memory allocation.
DWORD flProtect // The memory protection for the region of pages to be allocated.
);
and in this case, VirtualAlloc is called like
LPVOID WINAPI VirtualAlloc(0, 0Dh, 1000h, 40h);
Next, look at memcpy.
void * memcpy(
void * destination, // Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.
const void * source, // Pointer to the source of data to be copied, type-casted to a pointer of type const void*.
size_t num, // Number of bytes to copy.
);
This means, in this case, memcpy is called like
memcpy([ebp+Dst], offset unk_404068, 0Dh)
We can find that the unknown function [ebp+Dst] is from offset unk_404068. Looks like just some encrypted codes. However, we can convert the data to code with C key.
Sounds like this doing followning things.
1. put value of [esi] into edi
2. put value of [esi+4] into ecx
3. Rotate left the values of esi 5 times
4. Do this procedure for esi length + 4 times
At this time, the value of esi is [ebp+var_4]. This means it is heap space allocated.
Now, we have offset Str in the heapspace.
In summerize, the value which Str is modified by this function above is the original text.
3. decryption
Now we know what we have to do.
After selecting the data we need, we can export it with “Edit->Export data” (or Shift+E) and choose C hex for python code.
Then, what we have to do is writing a code for decryption.
#! /usr/bin/python
flag = bytearray([0x32, 0x62, 0x0A, 0x3A, 0xDB, 0x9A, 0x42, 0x2A, 0x62, 0x62,
0x1A, 0x7A, 0x22, 0x2A, 0x69, 0x4A, 0x9A, 0x72, 0xA2, 0x69,
0x52, 0xAA, 0x9A, 0xA2, 0x69, 0x32, 0x7A, 0x92, 0x69, 0x2A,
0xC2, 0x82, 0x62, 0x7A, 0x4A, 0xA2, 0x9A, 0xEB, 0x00, 0x00])
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
for i in range(len(flag)):
flag[i] = rol(flag[i], 5, 8)
print flag
By executing this code, we can obtain the original text.
root@kali:~# ./rol.py
FLAG{SHELLCODE-ISNT-JUST-FOR-EXPLOITS}