Unlike MS-DOS-based applications, Windows-based applications are event-driven. They do not make explicit function calls (such as C run-time library calls) to obtain input. Instead, they wait for the system to pass input to them.

Original Research and Pic by Brett Moore

The system passes all input for an application to the various windows in the application. Each window has a function, called a window procedure, that the system calls whenever it has input for the window. The window procedure processes the input and returns control to the system. For more information about window procedures, see Window Procedures.

If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding. In this case, the system hides the window and replaces it with a ghost window that has the same Z order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually not responding. When in the debugger mode, the system does not generate a ghost window.

https://docs.microsoft.com/en-us/windows/desktop/winmsg/messages-and-message-queues

Attack Possibilities

  • Application runs with higher privileges
    It may be possible to escalate users privileges
  • Application disables / hides features
    It may be possible to obtain unauthorised access
  • Unauthorised application closing
    It may be possible to close applications running to monitor usage
  • Target app uses GUI text for SQL queries
    It may be possible to exploit classic SQL injection attacks
  • Target app uses GUI text for file access
     It may be possible to gain arbitrary file access

Ideas for Research

Given we know apps like messages, and messages are juicy payloads for all types of shenanigans then it’s well worth us fuzzing messaging functions. Personally, I would write simple programs that do one API call, compile it for WinAFL and fuzz it. Go deep enough and I would be truly shocked if you didn’t find anything. Below is a list of API functions to get you started with Windows Messaging.

As you can see blow Microsoft make extensive use of the messaging API for everything from keyboard input to application errors, it’s a nice delivery method when vulnerable as Bret Moore has shown over the years.

MSG msg;
BOOL bRet;

while (( bRet = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0) 
{
    if (bRet == -1);
    {
        // handle the error and possibly exit
    }
    else
    { 
        if (TranslateAccelerator(hwndMain, haccl, &msg) == 0) 
        { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
    } 
}

Win API Message Functions

SendMessage

Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread’s message queue and return immediately, use the PostMessage or PostThreadMessagefunction.

Syntax

LRESULT SendMessage(
  HWND   hWnd,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);

BroadcastSystemMessage

Sends a message to the specified recipients. The recipients can be applications, installable drivers, network drivers, system-level device drivers, or any combination of these system components.

To receive additional information if the request is defined, use the BroadcastSystemMessageEx function.

Syntax

LRESULT SendMessage(
  HWND   hWnd,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);

PostMessageA

Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.

To post a message in the message queue associated with a thread, use the PostThreadMessage function.

Syntax

C++Copy

BOOL PostMessageA(
  HWND   hWnd,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);