Since I talked about how to enumerate Windows-based systems – a step you will have during an engagement, it is only natural to expand more on the topic (Windows, not enumeration, at least for now).
You might have successfully enumerated, exploited, established persistence, and maybe even exfiltrated data… but there’s much more to it, and a lot of stuff comes into play. In the upcoming articles, I will cherry-pick the stuff that is most interesting to me, but I will also try to provide you with a general overview so that you can more easily structure and map out the stuff I’ve been talking about.
This one is geared more towards red team type of activity, as the knowledge of the Windows API can be leveraged when you care about evasion e.g., as a red teamer (of course, it’s not only about evasion…); something a pentester usually doesn’t have to worry about. Just keep that distinction in the back of your mind.
However, in the case of red team engagements, since the emulation of an adversary is essential, you will see stuff that usually doesn’t get included in your pentests or vulnerability assessments. Phishing is permitted (out of scope in most of the pentests) and is usually something red teams will opt for (gotta keep that stuff realistic, right?); evasion is also vital since an adversary will try to stay on your corporate network as long as it is possible for them. It’s also kinda in the name; you are in the role of the red team, and the evasion pertains to throwing the blue team off your tracks. This is quite different and very interesting for us here, as it opens a plethora of new options you will think about and probably use during the engagement.
Terms like living off the land, phishing, bypassing UAC, bypassing AVs, C2, etc. all come into play! And more. Much more. This is terrifyingly fun, and even though the Windows API might not be the most attractive topic of the bunch here, its important to have a firm grasp on the stuff you’re abusing, and I wanted to give you just a brief overview of how one would abuse the system calls for their nefarious purpose.
Red teams will regularly abuse the Windows API to hide and evade the blue team, in the same way, they’ll use shellcode to evade AVs, or use the LOL (living off the land) methodology, and much more (evade runtime detection, logging and monitoring, generally employing tool agnostic approach in this endeavor).
Okay! So that’s a bit more of an intro, but I wanted to level with you here and set some expectations while also (hopefully) making the upcoming articles (as well as this one and the previous one) more sensible in the grand scheme of things.
The Windows (Win32) API
The first distinction to be aware of here is that Windows has two main modes through which it accesses hardware, the kernel, and the user mode. This goes back to the release of the Win32 API which is a library that’s used to interface between the user applications and the kernel.
The API here calls the interfaces and sends the info to the system which is then processed in the kernel mode. These two modes are essential because they determine how much access a driver or an application gets – kernel, memory, or hardware access. Also, note that with some languages and their interaction with the Win32 API, the application can go through the runtime first before going through the API.
The Win32 API breakdown can be briefly described as follows:
In/out parameters – these are the values that call structures define
API calls -this is the API called that’s used, with addresses to functions that are coming from the pointers
Call structures – this is what defines the API call and its parameters
DLLs – these are the DLLs for the Win32 API, we have core DLLs – KERNEL32, USER32, ADVAPI32, and other DLLs that are a part of the API like NTDLL, COM, NETAPI32, etc.
Headers – these are the libraries that get imported at runtime, they are defined through the header files or imports, function addresses are obtained through pointers
Since every API call of the Win32 library lives in memory and requires a pointer to a memory address the way you get those pointers for the needed functions is obscured because of the Address Space Layout Randomization – ASLR implementations. This is for security reasons as you guessed it.
If an attacker can discover where a DLL is loaded in any process, the attacker knows where it is loaded in all processes. Which is a quote from Mandiant’s blog post about the ASLR. From the same blog post – A low-privileged account can be used to overcome ASLR as the first step of a privilege escalation exploit.
This is also why Microsoft implemented the Windows Header File.
windows.h is a Windows-specific header file for the C and C++ programming languages which contains declarations for all of the functions in the Windows API, all the common macros used by Windows programmers, and all the data types used by the various functions and subsystems. It defines a very large number of Windows specific functions that can be used in C.
Basically, any Win32 function can be called once you’ve included the windows.h or the Windows Header File.
Another important implementation is the P/Invoke, which allows you to access structs, callbacks, and functions in unmanaged libraries from your managed code. Most of the P/Invoke API is contained in two namespaces: System and System.Runtime.InteropServices. Using these two namespaces gives you the tools to describe how you want to communicate with the native component.
What P/Invoke does is give you a way to do the complete process of calling the Win32 API. You can then invoke the function as a managed method you created even though you’re calling an unmanaged function.
The structure of the API calls is well documented by Microsoft but you can also check out the pinvoke.net: the interop wiki! for more information.
Every API call has a pre-defined structure for its input/output parameters. For example the VirtualProtect function – memoryapi.h it looks something like this:
[in] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flNewProtect,
[out] PDWORD lpflOldProtect
For the parameters expected i/o and accepted values, Microsoft has the explanation within the docs.
Lastly, I will list some API calls that are known for their possible malicious use. Also, MalAPI.io tries to document these, so it might be worth checking out.
VirtualProtect – Changes the protection on a region of committed pages in the virtual address space of the calling process.
GetProcAddress – Retrieves the address of an exported function (also known as a procedure) or variable from the specified dynamic-link library (DLL).
GetComputerNameA – Retrieves the NetBIOS name of the local computer. This name is established at system startup, when the system reads it from the registry.
GetModuleFileNameA – Retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process.
GetAdaptersInfo – The GetAdaptersInfo function retrieves adapter information for the local computer.
RegisterHotKey – Defines a system-wide hot key. Also, MalAPI says: RegisterHotKey is used to create a system wide hotkey. This function is commonly used by spyware or keyloggers to recieve a notification when a certain combination of keys are pressed.
Conclusion (for now)
I’ve just given a very brief overview here since the whole of the Win32 API is much larger. But for our purpose here, it should suffice. The main point I wanted to get across is for you to realize the potential options you might have with this and be aware of how some threat actors might leverage those system functions that are basically inseparable from the system itself.
A fun practice might be to check out what MITRE ATT&CK has documented on Native APIs and check out the Windows API calls known to be used for malicious purposes.
Cover image by Clint Adair
#win32 #API #windows