Skip to content

Instantly share code, notes, and snippets.

@etherx-dev
Forked from taviso/messages.c
Last active April 3, 2021 06:18
Show Gist options
  • Save etherx-dev/a41e884e1250566e83f670c4ee47e842 to your computer and use it in GitHub Desktop.
Save etherx-dev/a41e884e1250566e83f670c4ee47e842 to your computer and use it in GitHub Desktop.
Enumerating Windows Messages ( PROOF OF CONCEPT) - (i guess, this is so weired)... https://googleprojectzero.blogspot.com/2019/08/down-rabbit-hole.html#ftnt1 <-- "plain text" file RCE exploit in windows.
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
#pragma comment(lib, "USER32")
FARPROC NtUserPostMessage;
BOOL CALLBACK QueryWindowMessageProc(HWND Window, LPARAM Param)
{
BOOL ReturnCode = TRUE;
DWORD Result;
CHAR Title[1024] = {0};
GetWindowText(Window, Title, sizeof Title);
for (DWORD MsgNum = 0; MsgNum <= UINT16_MAX; MsgNum++) {
switch (MsgNum) {
// Whitelisted messages.
case WM_NULL:
case WM_SIZE:
case WM_MOVE:
case WM_GETHOTKEY:
case WM_GETICON:
case WM_RENDERFORMAT:
case WM_DRAWCLIPBOARD:
case WM_CHANGECBCHAIN:
case WM_DWMNCRENDERINGCHANGED:
case WM_THEMECHANGED:
case WM_GETTEXT:
case WM_GETTEXTLENGTH:
case WM_TOUCH:
// WM_SYSMENU, used by explorer to make the right click menu on the previews.
case 0x313:
// Unknown, probably theme related.
case 0x31B:
continue;
}
if (NtUserPostMessage(Window, MsgNum, 0, 0)) {
fprintf(stderr, "Message %#x to \"%s\" was allowed!\n", MsgNum, Title);
ReturnCode = FALSE;
} else {
Result = GetLastError();
if (Result != ERROR_ACCESS_DENIED && Result != ERROR_INVALID_MESSAGE) {
fprintf(stderr, "Message %#x to \"%s\" didn't work, but wasnt denied (%#x).\n",
MsgNum,
Title,
Result);
}
}
}
fprintf(stderr, "Window %p \"%s\" completed.\n", Window, Title);
return ReturnCode;
}
int main(int argc, char **argv)
{
ULONG_PTR WindowId;
DWORD MessageId;
DWORD ThreadId;
CHAR Title[1024] = {0};
CHAR Class[1024] = {0};
// Windows will try to parse the data you provide to PostMessage() so it
// can marshal it. I only want to know if the message is allowed, so
// I'll use the system call directly and skip all the marshaling.
//
// This way I can just check if I got ERROR_ACCESS_DENIED and not worry about
// exceptions interfering with the test results.
NtUserPostMessage = GetProcAddress(LoadLibrary("WIN32U"), "NtUserPostMessage");
if (argc != 2) {
fprintf(stderr, "Usage: %s THREADID\n", *argv);
return 1;
}
ThreadId = strtoul(*++argv, NULL, 0);
EnumThreadWindows(ThreadId, QueryWindowMessageProc, 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment