Introduction:
Hello All, in my previous blogs you guys must have noticed a lot of Windows APIs were used. As a blue teamer it is very easy to detect that malicious Windows APIs are being used basic reverse engineering can reveal the working of the malware.
Today I'll be discussing how analyst reverse engineer malware and how we can hide windows API to make the lives of the analyst hard. Let's get into it.
Simple Reverse Engineering:
Let's first discuss how we can do basic reverse engineering to see the workflow of a malware and also what APIs are being used.
I have a simple reverse shell program I am going to open it up in IDA:
Click on "GO" Work on your own and then load the binary in this case I am going to use a program that uses a common injection technique. After loading that we need to locate the main or the entry point of the binary.
IDA locates the entry point automatically in this case:
Going further in the binary look at the branches of the main function you'll find the windows api:
Looking at the reverse engineered content above we can see that it's pretty easy to locate the windows APIs and figure out the binary is malicious.
Evasion:
Now the second part of the blog will discuss how we can evade the API calls and make it harder for the analyst to figure out which APIs are being used.
I am going to use C++ for the demo. Also note that there are many ways to hide the functions and strings in a program.
Let's begin. While there are many modules that could hide the functions in a program, but in this blog I'll demonstrate how you can hide functions in your program.
In C++ there is a typedef keyword which is used to provide existing datatypes with a new name, in other words we can define VirtualAlloc arguments and change the change of the function from VirtualAlloc to Something else. Using this we can hide our functions and then we will use IDA to see whether we can see the functions after reverse engineering or not.
In the below example we will define the VirtualAlloc function and assign a different name:
typedef LPVOID (WINAPI * testing) (LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
In the above code we have defined VirtualAlloc arguments notice that we haven't use VirtualAlloc function yet, just it's arguments.
We still have to import the function by using GetProcAddress and GetModuleHandle. But the problem is you still have to define the string in the program which will get caught by any analyst. For that we will break the strings into characters and xor encode them.
char vAlloc[] = {0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x41, 0x6C, 0x6C, 0x6F, 0x63};
The above characters are encoded once you decode it VirtualAlloc will be revealed.
We will use GetProcAddress and GetModuleHandle to import the function and then we will use our custom datatype to execute the function.
char kernel_Mod[] = {0x6a, 0x64, 0x73, 0x6f, 0x64, 0x6d, 0x32, 0x33, 0x2f, 0x65, 0x6d, 0x6d}; //Kernel32.dll
testing test1 = (testing) GetProcAddress(GetModuleHandle(kernel_mod), vAlloc) ;
So in the above code we have used our custom datatype and defined test1 variable, we will use that variable to execute virtualAlloc function:
exec = test1(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
The above code will execute the function and change allocate the shellcode. There by successfully executing the function, and popping the calculator:
Now let's load it up in IDA and see if we can see the functions or not.
Great! In the above screenshot as you can see we cannot see the functions that we have defined in our program. We can check the imports as well:
Awesome! That's it for today.
Again this is just one method there are other ways to hide functions in a program.
Happy Hacking :)