Trustwave SpiderLabs Exposes Unique Cybersecurity Threats in the Public Sector. Learn More

Trustwave SpiderLabs Exposes Unique Cybersecurity Threats in the Public Sector. Learn More

Services
Capture
Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

twi-managed-portal-color
Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

twi-briefcase-color-svg
Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

tw-laptop-data
Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

twi-database-color-svg
Database Security

Prevent unauthorized access and exceed compliance requirements.

twi-email-color-svg
Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

tw-officer
Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

tw-network
Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Solutions
BY TOPIC
Offensive Security
Solutions to maximize your security ROI
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Partners
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

Fake Dialog Boxes to Make Malware More Convincing

Let’s explore how SpiderLabs created and incorporated user prompts, specifically Windows dialog boxes into its malware loader to make it more convincing to phishing targets during a Red Team engagement.

The following GIF shows a demo of the end result, where the loader appears like an installer (XYZ is a fictitious company used as an example throughout the rest of this article):

a

 

Mariusz Banach’s (mgeeky) presentation “Desperate Infection Chains” proposes the following taxonomy to describe how an initial access payload can be crafted:

b

The “decoy” element serves to “continue pretext narration after detonating malware.” In Banach’s presentation, he describes how APT groups open PDF files while installing their malware to avoid raising suspicion by convincing phished users that everything was going as expected. The idea is that adding user prompts to malware loaders make them appear more like legitimate software to achieve a similar effect.

 

Red Team Engagement Example

SpiderLabs sent phishing emails to employees at, let’s call it, XYZ Corp., that pretended to be from the firm’s IT department. The phishing email’s pretext was the IT department had pushed updates to the corporate VPN due to a security vulnerability. However, the email says not all employees received the update requiring them to install the patch manually. The emails contained two attachments - a PDF guide and a ZIP file containing the malware.

SpiderLabs designed the PDF guide to look like a legitimate internal document from the IT department and included instructions on how to unzip and execute the “security patch installer” (i.e. the malware):

c

The fake installer seen above did not have any actual functionality. For instance, if the user clicked “Cancel” instead of “Install” at the prompt, the embedded C2 shellcode would still execute.

Additionally, the progress bar and the warning to refrain from disrupting the program did not affect the loader’s execution. If the malware failed to execute, it would display a popup window asking, “Do you want to submit diagnostic data to your IT administrator?” This was to convince users not to respond to the email or submit IT tickets so SpiderLabs could elude detection by the Blue Team. While installer file formats like MSI/MSIX could achieve a similar visual effect, SpiderLabs created a fake installer manually with dialog boxes because it executed its C2 malware via DLL-sideloading. This meant the logic and resource files for the fake installer had to be contained within the loader DLL.

 

Creating dialog boxes - Step 1: GUI

Now, let’s look at how SpiderLabs created the fake installer with dialog boxes.

We started with an empty C++ project in Visual Studio:

d

 

Added a dialog resource to the project: 

e

f

g

 

The team used the resource editor to design the dialog box. We then adjusted the dimensions, added two “static text” labels and a progress bar, renamed the “Ok” button to “Install,” and placed a “Finish” button directly behind the “Cancel” button. The purpose of this is explained later in the article.

h

 

We customised the labels / appearance by right-clicking a component and viewing its “Properties” (e.g. the red boxes in the screenshot below show the options to centre the dialog box and change its font):

i

 

Preview and test the dialog box conveniently by selecting it in the resource editor, and clicking Format > Test Dialog:

j

 

Visual Studio generated two files - “resource.rc” and “resource.h”. The resource files are compiled into a binary format and linked with the final executable. The following shows the contents of resource.rc that Visual Studio generated. Note that SpiderLabs also added version information/metadata. This can help with avoiding some EDR detections (see: https://redops.at/en/blog/meterpreter-vs-modern-edrs-in-2023)

// Microsoft Visual C++ generated resource script.

//

#include "resource.h"

 

#define APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 2 resource.

//

#include "winres.h"

 

/////////////////////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

 

/////////////////////////////////////////////////////////////////////////////

// English (United States) resources

 

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

#pragma code_page(1252)

 

#ifdef APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// TEXTINCLUDE

//

 

1 TEXTINCLUDE

BEGIN

   "resource.h\0"

END

 

2 TEXTINCLUDE

BEGIN

   "#include ""winres.h""\r\n"

   "\0"

END

 

3 TEXTINCLUDE

BEGIN

   "\r\n"

   "\0"

END

 

#endif   // APSTUDIO_INVOKED

 

 

/////////////////////////////////////////////////////////////////////////////

//

// Dialog

//

 

IDD_DIALOG1 DIALOGEX 0, 0, 320, 101

STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

CAPTION "XYZ VPN Security Patch Installer"

FONT 8, "Segoe UI", 400, 0, 0x1

BEGIN

   DEFPUSHBUTTON   "Finish",IDOK,254,73,50,14

   PUSHBUTTON     "Cancel",IDCANCEL,254,73,50,14

   LTEXT           "Click 'Install' to begin, or 'Cancel' to exit",IDC_STATIC,19,31,280,10

   LTEXT          "XYZ VPN Security Patch 4.2.0 installation",IDC_STATIC,19,16,280,10

   DEFPUSHBUTTON   "Install",IDOK2,196,73,50,14

   CONTROL         "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,19,48,280,14

END

 

 

/////////////////////////////////////////////////////////////////////////////

//

// DESIGNINFO

//

 

#ifdef APSTUDIO_INVOKED

GUIDELINES DESIGNINFO

BEGIN

   IDD_DIALOG1, DIALOG

   BEGIN

       LEFTMARGIN, 7

       RIGHTMARGIN, 313

       TOPMARGIN, 7

       BOTTOMMARGIN, 94

   END

END

#endif   // APSTUDIO_INVOKED

 

 

/////////////////////////////////////////////////////////////////////////////

//

// AFX_DIALOG_LAYOUT

//

 

IDD_DIALOG1 AFX_DIALOG_LAYOUT

BEGIN

   0

END

 

 

/////////////////////////////////////////////////////////////////////////////

//

// Version

//

 

VS_VERSION_INFO VERSIONINFO

FILEVERSION 4,2,0,0

PRODUCTVERSION 4,2,0,0

FILEFLAGSMASK 0x3fL

#ifdef _DEBUG

FILEFLAGS 0x1L

#else

FILEFLAGS 0x0L

#endif

FILEOS 0x40004L

FILETYPE 0x2L

FILESUBTYPE 0x0L

BEGIN

   BLOCK "StringFileInfo"

   BEGIN

       BLOCK "040904b0"

       BEGIN

           VALUE "CompanyName", "XYZ"

           VALUE "FileDescription", "vpn"

           VALUE "FileVersion", "4.2.0.0"

           VALUE "InternalName", "vpn.dll"

           VALUE "LegalCopyright", "Copyright 2004-2022, XYZ."

           VALUE "OriginalFilename", "vpn.dll"

           VALUE "ProductName", "XYZ VPN"

           VALUE "ProductVersion", "4.2.0.0"

       END

   END

   BLOCK "VarFileInfo"

   BEGIN

       VALUE "Translation", 0x409, 1200

   END

END

 

#endif   // English (United States) resources

/////////////////////////////////////////////////////////////////////////////

 

#ifndef APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 3 resource.

//

 

/////////////////////////////////////////////////////////////////////////////

#endif   // not APSTUDIO_INVOKED

 

The following shows the contents of “resource.h”:

//

// Microsoft Visual C++ generated include file.

// Used by resource.rc

//

#define IDOK                           1

#define IDCANCEL                       2

#define IDD_DIALOG1                   101

#define IDI_ICON1                       103

#define IDB_PNG1                       104

#define IDOK2                           1001

#define IDC_PROGRESS1                   1002

 

#ifndef IDC_STATIC

#define IDC_STATIC (-1)

#endif

 

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE       105

#define _APS_NEXT_COMMAND_VALUE         40001

#define _APS_NEXT_CONTROL_VALUE         1001

#define _APS_NEXT_SYMED_VALUE          101

#endif

#endif

 

 

Creating dialog boxes - Step 2: Functionality

Once satisfied with the appearance of the dialog box, we used it in our code with DialogBox():

int main() {

  auto result = DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);

 return 0;

}

/*

src: <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dialogboxa>

void DialogBoxW(

  [in, optional]  hInstance,

  [in]            lpTemplate,

  [in, optional]  hWndParent,

  [in, optional]  lpDialogFunc

);

*/

 

Next, we created a callback function to respond to the user’s input (e.g. when they click a button):

INT_PTR CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {

switch (message) {

case WM_INITDIALOG: {

   // Set the color of the progress bar to green: 0,255,0. The default is blue.

   HWND hProgress = GetDlgItem(hDlg, IDC_PROGRESS1);

   SendMessage(hProgress, PBM_SETBARCOLOR, 0, RGB(0, 255, 0));

 

   ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS1), SW_HIDE); // Hide progress bar. User will see it after they press the 'Install' button

   ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE); // Hide finish button

   ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW);

   ShowWindow(GetDlgItem(hDlg, IDOK2), SW_SHOW);

   ShowWindow(GetDlgItem(hDlg, IDC_STATIC), SW_SHOW);

 

}

return (INT_PTR) TRUE;

 

case WM_COMMAND:

   switch (LOWORD(wParam)) { // LOWORD contains the resource ID, HIWORD contains the actual event

   case IDOK2: // Install button

     ShowWindow(GetDlgItem(hDlg, IDOK2), SW_HIDE);

     ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);

     ShowWindow(GetDlgItem(hDlg, IDC_STATIC), SW_HIDE);

     ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS1), SW_SHOW);

 

     // Start fake installation process and update progress bar

     for (int i = 0; i <= 100; i++) {

       SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETPOS, i, 0);

       Sleep(40);

     }

 

     // When installation is complete, hide the progress bar and show the finish button

     ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS1), SW_HIDE);

     ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW);

     break;

 

   case IDOK: // Finish button

     EndDialog(hDlg, LOWORD(wParam));

     break;

 

   case IDCANCEL: // Cancel button

     EndDialog(hDlg, LOWORD(wParam));

     break;

   }

   break;

 

default:

   return (INT_PTR) FALSE;

}

return (INT_PTR) TRUE;

}

 

Here are some key points to understand the DialogProc function shown above:

  • DialogProc is a callback function that responds to messages sent by the OS. The OS sends messages when the user performs events such as mouse clicks, keystrokes, and touch-screen gestures.
  • We are interested in the messages WM_INITDIALOG and WM_COMMAND
  • WM_INITDIALOG to initialise our dialog box. We initialise our progress bar to be green and show/hide components of the dialog box. For instance, the following line can be thought of as a selector to get the progress bar (IDC_PROGRESS1) and hide it (SW_HIDE): ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS1), SW_HIDE);
    • Instead of creating multiple dialog boxes to represent steps in a typical software installation, we created a single dialog box and displayed/hid elements selectively. Since our fake installer only had two steps, it was easier to place them within a single dialog box and display/hide their components. For instance, this is how the Dialog Box is initialised (i.e. what the user sees at the first step):

k

 

However, there is also a progress bar that is hidden at this stage. Once the user clicks “install”, the progress bar is then shown, and the “install” and “cancel” buttons are hidden.

l

 

As mentioned earlier, this selective showing and hiding of specific components is achieved with: ShowWindow(GetDlgItem(hDlg, <RESOURCE_ID>), SW_HIDE);

The RESOURCE_ID can be obtained from the resource editor (e.g. we know the progress bar has the resource ID IDC_PROGRESS1

m

 

  • WM_COMMAND to process the messages that the OS sends to our callback function. The WM_COMMAND message contains the resource ID that the user interacted with. E.g., if the user clicks the “Install” button, we get the resource ID IDOK2 (which represents that button), and we respond to it with our logic in case IDOK2

 

Conclusion

The primary benefit of dialog boxes or other types of user prompts is that they can make the phishing pretext more convincing. Secondary benefits include evading some EDRs and sandboxes (e.g., some sandboxes may not be able to simulate user input if the loader is designed to only execute the malware after receiving such input).

Gaining initial access via phishing involves multiple steps, each with the potential to raise suspicion among users. While incorporating dialog boxes can be effective once the user has downloaded the malicious file, the preceding steps of the phishing attack must be equally convincing and stealthy. For example, this could involve crafting a believable phishing pretext, sending a well-formatted email, ensuring that the antivirus (AV)/endpoint detection and response (EDR) systems do not flag the downloaded file, and avoiding triggers for Defender Smart Screen alerts. Successful initial access requires meticulous attention to detail at each step. While this article focused on the utility of dialog boxes in the later stage, it acknowledges the critical need for a cohesive and undetectable approach throughout the entire phishing operation.

Additionally, it should be noted that creating dialog boxes in this manner will leave IOCs in the resource section of the final loader, as seen in the following screenshot. However, resources may also have the effect of lowering the risk score for the file in certain EDRs:

n

 

In summary, this article has demonstrated how SpiderLabs created a fake installer using dialog boxes in Visual Studio and provided an example scenario in which it was used during a red team engagement. The method of creating dialog boxes demonstrated in this article may not be the correct or conventional way to create dialog boxes. However, it proved effective for SpiderLabs' specific needs.


 

Latest SpiderLabs Blogs

Important Security Defenses to Help Your CISO Sleep at Night

This is Part 13 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here.

Read More

2024 Public Sector Threat Landscape: Trustwave Threat Intelligence Briefing and Mitigation Strategies

Trustwave SpiderLabs’ 2024 Public Sector Threat Landscape: Trustwave Threat Intelligence Briefing and Mitigation Strategies report details the security issues facing public sector security teams as...

Read More

How to Create the Asset Inventory You Probably Don't Have

This is Part 12 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here.

Read More