FortiGuard Labs Threat Research Report
Affected Platforms: Windows, Linux, MacOS
Impacted Users: Any organization
Threat Severity: Critical
On the 12th of February, FortiGuard Labs received a request via email from a person representing a company called Packity Networks asking to whitelist their software. The sender claimed it to be a false-positive that inflicts a significant impact on their business.
At the time, the file at the link was classified as malicious only by Fortinet and Dr.Web sandbox.
Even though, at first glance, the request seemed innocent, and almost no other security vendor had flagged the file, we always investigate such requests thoroughly before complying. Our investigation led to the discovery of a new group we called “Netbounce” and it exposed their malware delivery infrastructure. What made this stand out among others is their unique set of tools and techniques. We were able to find several variants developed in-house by this group, each serving a different purpose.
In this blog post, we’ll present the measures taken by the Netbounce group to make the campaign look as legitimate as possible, and the actions FortiGuard Labs took to discover the real intentions of this threat actor.
The Cover Story
Before starting to analyze the sample, the first thing to notice is that the link from the email (hxxps://packity.com/setup.exe) had no reference on the company’s website, including no visible hyperlinks, no mentions of the file or similar names, etc. Moreover, an “official” installer can be found via another URL on the site: hxxps://www.packity.com/pub/desktop/Packity-latest.exe.
As can be seen in the following table, these installers are entirely different.
NSIS installer, deploys NodeJS application
No user interaction
Installer with UI
Table 1: Key differences between the official installer and setup.exe from the link.
However, this alone is not a very solid indicator as there may be legitimate reasons for the discrepancy, such as the installed application downloading and using that setup.exe file later on. Also, the two executables didn’t exhibit any obvious malicious behavior, and both were validly signed with the same certificate issued to “Secured Network Stack”.
But the background checks we conducted on Secured Network Stack and Packity Networks Inc. yielded no results; there were no registered companies or official reference to these entities, nor we could find any employee profiles online. However, based on a twitter account, Packity seems to have had some online presence besides their website for at least two years, and we found reviews for the software.
Suspicious Code Signature
Even though the executables were signed with the same certificate, we noticed that the certificate was issued with an unrelated email address, email@example.com. The certificate was issued on September 2nd 2020, so we searched for older certificates used by Packity and found an older installer. Comparing the older signature confirmed that the contact information is indeed unrelated to the company.
The “@me.com” domain only belongs to Apple mail accounts created before September 19th, 2012, as can be seen on the Apple support website:
Although it may seem odd that a different email was used, the new certificate was issued exactly when the previous certificate expired, on September 3rd 2020, which may hint it’s not malicious.
A keen reader may also have noticed that the signature with the new certificate doesn’t have a timestamp countersignature. This is highly uncommon when signing code, and the “official” setup file from the website does have a timestamp. Because of this, our suspicions were still not resolved.
Diving into the Binary
As mentioned earlier, executing setup.exe did not provide any clear-cut malicious indicators. However, we did observe the following actions:
- Copied itself to “C:\Windows\Net Helper\net-helper.exe”.
- Created a service called “Net Helper” with the copied file.
- Started the service and exited the process.
- The new service process then attempted to connect to hxxps://update.netbounce.net/check every 5 minutes.
This behavior is abnormal for an installer, since a) no user interaction occurs, b) new folders are normally not created in C:\Windows and c) no actual files of the program are unpacked and the installer just copies itself.
Looking at the code, we could see it is written in the Go programming language and has a function named equinoxUpdate. According to its website, Equinox “helps you build, package and distribute self-updating Go apps to your customers” offers paid hosting plans, and provides an open-source client SDK.
In fact, aside from setting persistency, most of the functionality of the executable is basically the Equinox client using a hardcoded AppId “test”. There were no other references to the equinox namespace, meaning it was used with source code and not just as an imported package, so we checked for any changes made to it. And we found that in addition to the updated URL listed above, the HTTP User-Agent header was set to “Netbounce/1.0”.
Changing the URL effectively means the public Equinox servers won’t be used but that by using the same protocol the update mechanism might still appear legitimate.
At the time of our analysis, the update mechanism did not download anything. However, it’s possible the threat actor simply reserved the option to use it and deliver malicious payloads in the future.
At this stage, we hit a roadblock. There were many weird looking indicators: sketchy company, executables which lack references on the company’s website, digital signatures with shady attributes, and an application without any substantial functionality. But as suspicious as it appeared to be, we didn’t have any concrete proof it was indeed malicious. At this point, we decided to try to find other files that were signed using the same certificate, hoping to get a new lead.
Revealing the Real Story
We were able to track down additional samples that shared similar properties to the one we received in the email. Among them, we identified samples compiled for Linux and MacOS, as well as actual malicious capabilities.
A sample found in the wild under the name “Net Helper GUI.exe” was nearly identical in all properties:
- File size: 7MB
- Programming language: Go
- Execution path: %windir%\Net Helper\ net-helper.exe
- First seen: 2/14/2021
Bindiffing the executable confirmed that both samples have the same author; moreover, it revealed that it has additional functionality:
- Exact function matches: 5074.
- Partial function matches: 29.
- Net Helper GUI.exe only functions: 164 (new functionality).
- Setup.exe only functions: 34 (none contain real functionality).
Analyzing the differences, we observed that the function main_run has additional code on the branch that runs when the service has not yet been installed. Prior to installing the service, the function “main_setupNetUpdater” is called to download and execute a next-stage payload via an HTTP GET request to boostfever.com. With the URL path and domain are hardcoded, the subdomain is either:
- A randomly generated UUID – hxxp://0857a813-72ca-4a70-883a-3b555f6bf3c1.boostfever.com/progwrapper.exe
- The hardcoded “cdn” string – hxxp://cdn.boostfever.com/progwrapper.exe
We’ll elaborate on progwrapper.exe in a later section.
Before running the payload, it is also made persistent on the machine via Registry for each time the current user logs on with a new session: HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\net-helper.
We found such downloaders were contained inside archives and MSI installers. Placing this functionality right after verifying that the service isn’t installed makes sense with this possible infection vector as that’s the case when the sample executes on the system for the very first time.
The Equinox client was used as an imported package, so the namespace is found intact, along with the default URL (https://update.equinox.io/check) and User-Agent (EquinoxSDK/1.0). A hardcoded AppId (app_6EE4wBvjBhS) was used across all the samples we detected. After the 5 minutes timer elapses in the service, an update is pulled from the Equinox servers.
The updated file is another variant of “Net Helper”. It has the modified Equinox client, like in setup.exe, but the AppId is generated using the machine’s serial number. We will refer to these samples as post-update variants.
Another functionality incorporated in various samples, pre and post update, is reverse proxy, which effectively grants its operator a foothold inside compromised networks while bypassing perimeter firewall policies. Potentially, its purpose may also be to use infected machines as hop points when conducting operations against targets in other organizations.
This capability was implemented using the open-source Tunnel package. When the service runs, an HTTP GET request is sent to an external server, for instance, hxxp://connect.netbounce.net/manage.json, to obtain the address of the proxy server for inbound communication. Once the sample connects to the specified server, the operator can start proxying HTTP/TCP connections through the compromised machine.
The name of the package in the compiled binaries is “netbounce” or “proxy”. Off the shelf, the package supports redirecting traffic only on the local host; in our case, the victim’s machine. The malware authors changed the code to allow them to connect to other machines, per specification.
MacOS and Linux Variants
Using the Go programming language allows the threat actor to easily extend their operations to MacOS and Linux, as it is simple to compile the source code to a different operating system.
For MacOS, we found an application package with a post-install script that downloads a pre-update variant with the same hardcoded Equinox AppId (app_6EE4wBvjBhS). It also includes the reverse proxy functionality with the same management URL (hxxp://connect.netbounce.net/manage.json).
For post-update samples we observed, there were no additional updates pulled from the netbounce.net domain. Leveraging the fact that the Equinox client was used to communicate with this server, we figured out the URLs that serve files in response to valid update requests. Through that, we issued requests on our own and were able to obtain an ELF sample we classified as a post-update variant.
Circling back to the progwrapper.exe executable, we identified it was also developed in Go. It sends an HTTP GET request to a hardcoded URL (hxxp://cdn.boostfever.com/ex.json), which returned the following JSON object in response:
Depending on the “type” field, it checks if a file or a registry key does not exist in the provided path and proceeds to download and execute the file from the “download_url”. The function main_downloadAnotherExecutable also exists in “Net Helper GUI.exe”. The code is shared and has just one small difference that is not related to the functionality itself.
In this case, output40.exe is the final payload. It’s packed with a multistage packer. Following unpacking, we discovered different stealers being delivered from this infrastructure, such as Vidar and FickerStealer. We observed different variants of the packer, and so we estimate it is a part of this delivery infrastructure as well. After unpacking, the payload is executed in memory using reflective loading or Process Hollowing.
It is interesting to note that FickerStealer’s first action is to create the file “Trackingfolder084\start.txt”. The string is hardcoded in the binary, which hints at an intimate relationship between it and the Netbounce infrastructure.
A newer version of progwrapper.exe added a basic remote command execution capability, which can be used instead of the download and execute. This variant also uses a different hardcoded domain, t1.xofinity.com, over HTTPS, and the responses are encrypted with the AES algorithm. Oddly enough, the HTTP User-Agent header is set to “Netbounce/1.0”.
Connecting the Dots
“Netbounce” is used as a domain name, as a User-Agent, and for custom packages in the source code. Its possible source code is shared by different actors; however, overlaps in the network infrastructure makes it possible to cluster all the activity together to one entity.
WHOIS records for installcdn-aws.com, boostfever.com, jumpernode.com, and uptime66.com show they were all registered by the same entity.
They have the same active subdomains, like cdn, download, update, and proxy. Other subdomains have a similar pattern, where they are formatted as “<single char>1”: c1.boostfever.com, u1.boostfever.com, t1.xofinity.com, m1.uptime66.com.
All IPs for the domains resolve to the same subnet – 184.108.40.206/20. Some servers are also hosted by different domains:
- 220.127.116.11: dl.installcdn-aws.com, u1.boostfever.com, t1.xofinity.com.
- 18.104.22.168: cdn.boostfever.com, cdn.netbounce.net, proxy.netbounce.net, connect.netbounce.net, proxy.jumpernode.com, connect.jumpernode.com.
Looking at passive DNS records, we get some idea for the progression of the campaign over the few last weeks. The following table shows the resolution history of domains that pointed to 22.214.171.124, providing another indication that all the domains are operated by the same entity.
Table 2: DNS resolution history to 126.96.36.199.
We generated a heat map of infections across the world using FortiGuard threat intelligence data:
This new campaign was detected almost immediately after it started, even though the threat actor took a lot of measures to appear as legitimate as possible to evade detection:
- Used a real, even though shady, company to masquerade the activity.
- Used valid certificates that looked very similar to the original certificates used by the company.
- Employed a legitimate update service, Equinox, as part of the infection chain.
The threat actor was convinced that the cover was good enough to send us an email pointing us directly to their executable in an attempt to trick us to whitelist it.
The initial sample we got is only one part of a rather elaborate, multistage infection mechanism that can be activated at any point in time, with the final payload customized according to the attacker’s discretion.
The rich and versatile open-source ecosystem of the Go programming language, along with its cross-platform support, surely cut down heavily on the threat actor’s work time and costs.
After we proved this is a part of a malicious campaign, we kept digging and found many additional related samples, and some of the samples were signed with certificates issued to other shady companies.
We’ll dive into technical details of FickerStealer in a follow up blog.
FortiEDR detects and blocks payloads delivery from this infrastructure out-of-the-box without any prior knowledge or special configuration. It uses both its AI-based AV and post-execution prevention engines, as can be seen in Figure 12:
FortiGuard Web Filtering
FortiGuard’s Web Filtering blocks all known domains and URLs (listed in Appendix B), and all malware samples listed are detected as:
In addition, as part of our membership in the Cyber Threat Alliance, details of this threat were shared in real time with other Alliance members to help create better protections for customers.
Appendix A: MITRE ATT&CK Techniques
Subvert Trust Controls: Code Signing
Create or Modify System Process: Windows Service
Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder
Application Layer Protocol: Web Protocols
Encrypted Channel: Symmetric Cryptography
Encrypted Channel: Asymmetric Cryptography
Obfuscated Files or Information: Software Packing
Process Injection: Process Hollowing
Appendix B: IOCs
Payload hosting domains:
File Hashes (SHA256)