Overview
Active since 2016, TrickBot is one of the most prevalent modular banking trojans. The botnet’s modules carry out objectives such as credential harvesting, propagating via the network, web injection and others. Being an actively developed botnet, we often come across updated modules and in some cases new tools that are added as part of its arsenal.
Recently we have discovered a relatively new module that goes by the name masrv
. The module is a network scanner that incorporates the Masscan open-source tool. Additionally, the module contains an unreferenced Anchor C2 communication function and a list of hardcoded IPs which have previously been associated with Anchor and Bazar 12.
We believe this module is used as one of TrickBot’s network reconnaissance tools to gather more information about the victim’s network.
The masrv module
The module arrives as either a 32-bit or 64-bit DLL, depending on the Windows OS version of the victim machine the bot is running on. Both DLLs we observed are debug builds and log their execution into standard output.
As with other TrickBot modules, the module is executed via its export functions Start
and Control
3.
Commands for the Module’s C2
The module makes requests to the C2 to receive information that it requires to pass as parameters to Masscan.
Command | HTTP Method | Description |
---|---|---|
81 | POST | send results |
freq | GET | Get frequency for running Masscan |
domains | GET | Get a List of IP address ranges followed by port range |
over | GET | Signal to the C2 that scan is complete |
rate | GET | Get rate value for transmitting packets |
npcap.exe | GET | Get Nmap’s packet sniffing library installer |
The URI construction for the GET requests follows this format:
http://<c2>:<port>/<gtag>/<botID>/mass/<command_string>
gtag
- The Campaign ID that is seen in the config4 present in the main bot.botID
- The Bot ID created in the victim machine by the main bot.command_string
- One of the string commands from the above table.
At the time of researching this module, we were unable to pull down the config associated with masrv
. So, in order to observe a dynamic run, we have implemented a mock server on localhost
at port 8080
, to be able to feed responses back to the module. Below is an example of one of the GET request being made for the command freq
.
Information Gathering
At first, the module makes GET requests for information from the commands freq
, domains
and rate
. If successful, the module executes Masscan’s main function routine which is compiled within the DLL. Below we can see the execution result of the log from standard output. The date mentioned in the logs is that of when the module was compiled.
SendEvent(VERS, MASS scanner build Dec 4 2020 13:19:27 started)
Execute Control(masrv) CtlArg=127.0.0.1:8080
Send cmd to server: freq
Response buf: 1
HTTP message success: URI=127.0.0.1:8080/mor2/JOHN-PC_W617601.CC081DEDCA3EE2CECFA265AF5C904BF3/mass/freq DATA=1
SendEvent(DBG, Successfully executed command: freq)
Send cmd to server: domains
Response buf: 127.0.0.0/16
80-81,53
HTTP message success: URI=127.0.0.1:8080/mor2/JOHN-PC_W617601.CC081DEDCA3EE2CECFA265AF5C904BF3/mass/domains DATA=127.0.0.0/16
80-81,53
SendEvent(DBG, Successfully executed command: domains)
Send cmd to server: rate
Response buf: 1000
HTTP message success: URI=127.0.0.1:8080/mor2/JOHN-PC_W617601.CC081DEDCA3EE2CECFA265AF5C904BF3/mass/rate DATA=1000
SendEvent(DBG, Successfully executed command: rate)
The Masscan tool has its own network stack and doesn’t rely on that of the OS. In order for it to be able to retrieve the results, Masscan requires a low-level packet filter and on a Windows OS it attempts to load NPcap\Packet.dll
. If Packet.dll
doesn’t exist, then the module makes a request to download the NPcap
executable from the C2. NPcap
is silently installed on the machine by passing the parameter /S
. It gets executed by invoking CreateProcessA
or ShellExecuteExA
(if the first API is unsuccessful).
The Masscan tool also attempts to initialize the network adapter. If the tool fails to detect any interface, a module-specific function is called that tries to get a MAC address from the ARP table, to pass to Masscan as --router-mac <mac>
. For each ARP entry in the MIB_IPNETTABLE
5, the module finds the corresponding index of the IPv4 entry in the MIB_IPADDRTABLE
6. It leverages the APIs GetIpNetTable
and GetIpAddrTable
respectively to retrieve this information. If successful, it gets the dotted-decimal format of the IPv4 address and logs the results of the ping
command that is run on the target 8.8.8.8
from that IPv4 address. If the ping ran successfully, the module gathers the ARP type information and logs the ARP entry of the IPv4 address. Then it queries for the MAC address from the MIB_IPNETROW
entry. Below is an example of the ping
command.
ping 8.8.8.8 -S 127.0.0.1
The module sends results from the Masscan run if it has discovered open ports on any of the IP ranges that were provided. Results are aggregated by calling a module-specific function from the Masscan function output_report_status
which adds discovered ports to a global string. These results are posted back (via the 81
message) regularly, with the frequency, in seconds, determined by the freq
value queried at the beginning.
Anchor/Bazar reference
Both the 32-bit and 64-bit DLLs have an unreferenced function that share similarities to Anchor’s C2 communication subroutine. It is not uncommon for this actor to be seen sharing code between its toolset. Additionally, this function references a list of hardcoded IPs from the binary which have previously been associated with both Anchor and Bazar.
51[.]254[.]25[.]115
193[.]183[.]98[.]66
91[.]217[.]137[.]37
87[.]98[.]175[.]85
185[.]121[.]177[.]177
169[.]239[.]202[.]202
198[.]251[.]90[.]143
5[.]132[.]191[.]104
111[.]67[.]20[.]8
163[.]53[.]248[.]170
142[.]4[.]204[.]111
142[.]4[.]205[.]47
158[.]69[.]239[.]167
104[.]37[.]195[.]178
192[.]99[.]85[.]244
158[.]69[.]160[.]164
46[.]28[.]207[.]199
31[.]171[.]251[.]118
81[.]2[.]241[.]148
51[.]254[.]25[.]115
82[.]141[.]39[.]32
50[.]3[.]82[.]215
46[.]101[.]70[.]183
5[.]45[.]97[.]127
130[.]255[.]78[.]223
144[.]76[.]133[.]38
139[.]59[.]208[.]246
172[.]104[.]136[.]243
45[.]71[.]112[.]70
163[.]172[.]185[.]51
87[.]98[.]175[.]85
5[.]135[.]183[.]146
Conclusion
This new module is an indication of the actor’s continued investment in improving their network reconnaissance toolkit, even after recent disruption efforts7. We provide some IOCs and a YARA rule related to this module below.
IOCs
PDB paths:
D:\Project\masrv\build-masrv\debug\Desktop_msvc_15_0_32bit\masrv.pdb
D:\Project\masrv\build-masrv\debug\Desktop_msvc_15_0_64bit\masrv.pdb
Module Name | SHA256 | Description |
---|---|---|
masrvDll32 | 2c29de91a5be3bffafb521e04b88819d23c6f71843c8f2d54516ec2afefd24c6 | 32-bit DLL |
masrvDll64 | e1c5a377450d04372bfe9d943d322fbdd53c274c3772836eb044fd2a4b08a870 | 64-bit DLL |
YARA
rule TrickBot__masrvDll
{
meta:
id = "4kWjG0InTDyHiur8cCzPeG"
fingerprint = "3e91c19602340a43e026ffdb23b1d6a0c4e186d67f743e962c75aa51ea0c4d1c"
version = "1.0"
first_imported = "2021-01-29"
last_modified = "2021-01-29"
status = "RELEASED"
sharing = "TLP:WHITE"
source = "KRYPTOS LOGIC"
description = "Detects TrickBot masrvDll module"
category = "MALWARE"
malware = "BOT"
strings:
$a = "http://127.0.0.1:8080/gid/uid/pcap.exe"
$b = "c:\\\\temp\\\\maserv.txt"
$c = "Send cmd to server: %s\\r\\n"
$d = "HTTP message success: URI=%s DATA=%.*s\\r\\n"
condition:
all of them
}
References
https://www.cybereason.com/blog/dropping-anchor-from-a-trickbot-infection-to-the-discovery-of-the-anchor-malware ↩︎
https://www.virustotal.com/gui/file/7a3753bbf4c0ae8b1ff34faf999347c04fd6793a0bf510cb84f1b00ce14baf65/behavior/VirusTotal%20Jujubox ↩︎
https://www.bitdefender.com/files/News/CaseStudies/study/316/Bitdefender-Whitepaper-TrickBot-en-EN-interactive.pdf ↩︎
https://blog.malwarebytes.com/threat-analysis/2016/10/trick-bot-dyrezas-successor/ ↩︎
https://docs.microsoft.com/en-us/windows/win32/api/ipmib/ns-ipmib-mib_ipnettable ↩︎
https://docs.microsoft.com/en-us/windows/win32/api/ipmib/ns-ipmib-mib_ipaddrtable ↩︎
https://www.microsoft.com/security/blog/2020/10/12/trickbot-disrupted ↩︎