🪟Windows API confidence abuse basics

In this article i will focus on how to use the legitimate Windows API functions like EnumUILanguagesW to execute shellcode in a more stealthy manner than a simple CreateThread. Unlike traditional shellcode execution techniques, this approach utilizes a "begnin" system function commonly employed for enumerating available UI languages making it much harder to detect.

Step 1: Injecting Shellcode into Memory

Once the shellcode is decrypted (using a method like ROT1 decryption), it is injected into memory, ready for execution. The shellcode needs to be placed in executable memory as described before. For simplicity purposes we will keep use a "dirty" way to allocate it, so we can focus on the important part of the execution chain. (not much a problem in Go beacause memory management is automated)

ptr := unsafe.Pointer(addr)
copy((*[1 << 30]byte)(ptr)[:], shellcode)

Step 2: Stealthy Execution via EnumUILanguagesW

The core of this technique lies in calling EnumUILanguagesW, a function typically used to enumerate the languages installed on a system. While this function is legitimate (and so poorly monitored), it can be repurposed to execute shellcode stored in memory, which significantly reduces the chances of detection.

Using EnumUILanguagesW to Execute Shellcode

//windows API functions definition
kernel32 := windows.NewLazySystemDLL("kernel32.dll")
procEnumUILanguagesW := kernel32.NewProc("EnumUILanguagesW")

// Calling EnumUILanguagesW, passing the shellcode memory address
_, _, err := procEnumUILanguagesW.Call(
    addr,             // Address of shellcode in memory
    0,                // MUI_LANGUAGE_ID - not needed in this case
    0,                // lParam - null
)

Why functions like EnumUILanguagesW are better

Using a common and legitimate Windows function like EnumUILanguagesW for executing shellcode provides several advantages:

  1. Legitimate Function: EnumUILanguagesW is part of the Windows API and is used by various applications, making it a low-profile function that’s often overlooked by security tools.

  2. No Suspicious Behavior: Unlike functions that spawn new threads with CreateThread, this technique doesn’t trigger obvious flags for most security products that monitor such behaviors.

  3. Minimal Footprint: The shellcode executes within the context of the calling application, without spawning new processes or threads, making it much harder to detect through traditional monitoring methods.

  4. Bypassing Detection: Security tools focused on detecting malicious use of process creation may miss this technique, as the shellcode is executed via a common API used in many legitimate processes.

Credits

This trick is not a result of my own researches, i just implemented it in go (and that obiously was quite simple as you can see). the function i taken in example is a kind of "LOLBin', you can retrieve a non exhastive list with cpp implementations at this link The full code is available here

Last updated