Welcome to Goot Camp: Tracking the Evolution of GOOTLOADER Operations
Mandiant
Written by: Govand Sinjari, Andy Morales
Since January 2021, Mandiant Managed Defense has consistently responded to GOOTLOADER infections. Threat actors cast a widespread net when spreading GOOTLOADER and impact a wide range of industry verticals and geographic regions. We currently only attribute GOOTLOADER malware and infrastructure to a group we track as UNC2565, and we believe it to be exclusive to this group.
Beginning in 2022, UNC2565 began incorporating notable changes to the tactics, techniques, and procedures (TTPs) used in its operations. These changes include the use of multiple variations of the FONELAUNCH launcher, the distribution of new follow-on payloads, and changes to the GOOTLOADER downloader and infection chain, including the introduction of GOOTLOADER.POWERSHELL. These changes are illustrative of UNC2565’s active development and growth in capabilities.
Mandiant’s observation of post-compromise GOOTLOADER activity has largely been limited to internal reconnaissance, as these intrusions have been quickly detected and mitigated.
This blog post will also cover the various methods used by the malware to obscure its code, as well as provide scripts that can automate the deobfuscation process.
Infection Chain
GOOTLOADER infections begin with the user searching for business-related documents online, like templates, agreements, or contracts. The victim is lured into visiting a compromised website and downloading a malicious archive that contains a JavaScript file known as GOOTLOADER.
Successful execution of the GOOTLOADER file will download additional payloads, FONELAUNCH and Cobalt Strike BEACON or SNOWCONE that will be stored in the registry. These payloads are executed via PowerShell in the later stages.
Since late 2020, GOOTLOADER campaigns have implemented relatively consistent infection chains. However, the infection chain incorporated notable shifts starting in mid-November 2022. Prior to November 2022, the typical GOOTLOADER infection chain consisted of the following:
- The user visits an UNC2565-compromised site (usually related to business documents) and downloads a malicious ZIP archive.
- The malicious ZIP file is saved to the user's Downloads folder.
- The user opens the ZIP file and clicks the .JS file inside.
- The JS file is launched using WScript.exe.
- The WScript.exe process reaches out to three hard coded domains and downloads two payloads that are saved to the registry.
- WScript.exe stores the first registry payload (FONELAUNCH) as a value in the path HKCU\SOFTWARE\Microsoft\<STRING>\%USERNAME%0.
- WScript.exe stores the second registry payload (usually BEACON) as a value in the path HKCU\SOFTWARE\Microsoft\<STRING>\%USERNAME%.
- WScript.exe executes a PowerShell script that decodes and executes the first payload. This payload is a .NET-based launcher that Mandiant tracks as FONELAUNCH.
- WScript.exe executes a PowerShell command that creates a scheduled task which executes the same PowerShell script mentioned in the previous step. The current account username will be used for the task name, and the task will be set to run when the user logs in.
- The first registry payload (FONELAUNCH) decodes and executes the second registry payload, which contains Cobalt Strike BEACON or SNOWCONE malware.
Figure 1: GOOTLOADER attack chain
In November 2022, Managed Defense observed a new variant of GOOTLOADER, tracked as GOOTLOADER.POWERSHELL, leveraging a new infection chain. This new variant writes a second .JS file to disk and creates a scheduled task to execute it. The script reaches out to 10 hard coded URLs. The URL request contains encoded data about the host such as running processes and local drives. Follow up activity is similar to previous GOOTLOADER versions where payloads are written to the registry. The attack chain of this new variant is listed as follows:
- The user visits an UNC2565-compromised site (usually related to business documents) and downloads a malicious ZIP archive.
- The malicious ZIP file is saved to the user's Downloads folder.
- The user opens the ZIP file and clicks the .JS file inside. This is a trojanized JavaScript library containing an obfuscated JScript file, which will ultimately execute GOOTLOADER.POWERSHELL. Recently observed trojanized JavaScript libraries include jQuery, Chroma.js, and Underscore.js.
- The JS file is launched using WScript.exe.
- The WScript.exe process creates an inflated file with a .LOG extension to C:\Users\%USERNAME%\AppData\Roaming\<RANDOM_DIRECTORY>\<HARD_CODED_FILE_NAME>. The dropper writes more obfuscated JScript code followed by a padding of random characters to increase the file size.
- The .LOG file is renamed with a .JS file extension.
- The dropper creates a scheduled task that executes the new JScript file. The scheduled task is executed immediately after creation but also serves as a persistence mechanism to run the second JScript file at the next logon.
- WScript.exe and CScript.exe launch a PowerShell process that reaches out to 10 hard coded domains.
- Victim information collected includes environment variables, Windows OS version, filenames, and running processes. This information is Gzip compressed, Base64 encoded, and sent to the command and control (C2) server in the Cookie header.
- The C2 returns a payload, which is executed using the Invoke-Expression PowerShell cmdlet. This leads to the download of two payloads into registry keys: FONELAUNCH and a secondary payload to be executed by FONELAUNCH (mirroring steps 6 through 10 of the previous infection chain).
Figure 2: GOOTLOADER.POWERSHELL attack chain
The Evolution of GOOTLOADER Obfuscation
In addition to observing GOOTLOADER.POWERSHELL, several variants of FONELAUNCH, and a new infection chain, Mandiant has also observed an evolution in the methods used to obfuscate GOOTLOADER. Mandiant currently tracks three obfuscation variants that have been leveraged. Beginning in early 2021, GOOTLOADER was distributed as a small JS file with one obfuscated block of code (MD5: ab1171752af289e9f85a918845859848). These samples have been tracked as obfuscation variant 1 (Figure 3).
Figure 3: GOOTLOADER obfuscation variant 1 in February 2021
Around October 2021, Managed Defense observed GOOTLOADER embedded within trojanized jQuery libraries instead of being on its own, likely in attempt to evade detection and hinder analysis (MD5: 82607b68e061abb1d94f33a2e06b0d20). These samples have been tracked as obfuscation variant 2 (Figure 4).
Figure 4: GOOTLOADER obfuscation variant 2 in October 2021
In August 2022, Managed Defense observed new samples with slight variations in the obfuscation code. These new samples spread the obfuscated string variables throughout the file rather than having them all on the same line (MD5: d3787939a5681cb6d6ac7c42cd9250b5). These GOOTLOADER samples trojanized jit.js file rather than jQuery (Figure 5).
Figure 5: GOOTLOADER obfuscation variant 2 in August 2022
Beginning in November 2022, Managed Defense observed a new obfuscation variant, tracked as variant 3, with modified infection that is more complex than the previous variants. This new variant contains additional string variables that are used in a second deobfuscation stage. This new variant has been observed trojanizing several legitimate JavaScript libraries, including jQuery, Chroma.js, and Underscore.js (MD5: ea2271179e75b652cafd8648b698c6f9).
Figure 6: GOOTLOADER obfuscation variant 3 in November 2022
GOOTLOADER Obfuscation Variant Comparison
Table 1 compares different obfuscation variants of the GOOTLOADER JavaScript files based on samples observed by Mandiant.
Fileless Registry Payloads
The successful execution of GOOTLOADER will result in the download of two additional payloads, FONELAUNCH and an in-memory dropper that typically delivers BEACON, to the registry paths in Figure 7. These are registry resident malware samples stored in the Windows registry to remain persistent and evade detection. GOOTLOADER subsequently launches these payloads in memory.
HKCU\SOFTWARE\Microsoft\Phone\%USERNAME%0 (FONELAUNCH)
HKCU\SOFTWARE\Microsoft\Phone\%USERNAME% (Secondary registry payload)
HKCU\SOFTWARE\Microsoft\Personalization\%USERNAME%0 (FONELAUNCH)
HKCU\SOFTWARE\Microsoft\Personalization\%USERNAME% (Secondary registry payload)
HKCU\SOFTWARE\Microsoft\Fax\%USERNAME%0 (FONELAUNCH)
HKCU\SOFTWARE\Microsoft\Fax\%USERNAME% (Secondary registry payload)
HKCU\SOFTWARE \Microsoft\Personalization\<RANDOM_STRING> (FONELAUNCH & The secondary registry payload)
The second stage PowerShell script attempts to create a scheduled task (Figure 8) that launches the malicious payloads that were saved to the registry (Figure 9).
Figure 8: Second stage PowerShell script that creates a scheduled task for malware persistence
Figure 9: The Base64 data from Figure 8 is a PowerShell script that reconstructs and executes the first registry payload.
The PowerShell script performs the following steps to execute the FONELAUNCH malware in memory:
- Query the HKCU\SOFTWARE\Microsoft\Phone\%USERNAME%0 registry key
- Merge all the registry values together (usually 7 entries)
- Replace the "#" character with the string "1000"
- Convert the data from hex to bytes
- Load the payload (FONELAUNCH) into memory and execute it
FONELAUNCH
FONELAUNCH is one of the payloads written into the registry by GOOTLOADER. It is a .NET-based loader that loads an encoded payload from the registry into memory.
Since May 2021 Mandiant has observed UNC2565 use three different variants of FONELAUNCH, distinguished by their loading mechanism (Table 2). The evolution of FONELAUNCH variants over time has allowed UNC2565 to distribute and execute a wider variety of payloads, including DLLs, .NET binaries, and PE files.
- FONELAUNCH.FAX reads and decodes data from the HKCU\SOFTWARE\Microsoft\Fax\%USERNAME% registry key. The returned content is expected to be a .NET assembly, which is loaded at runtime into memory.
- FONELAUNCH.FAX establishes its persistence by creating a registry key in the current user registry hive (Figure 10) (MD5: d6220ca85c44e2012f76193b38881185).
- FONELAUNCH.PHONE mainly reads and decodes data placed in a specific registry key. The returned data is expected to be a DLL, which is loaded via a publicly available DynamicDllLoader project.
- Initial samples of FONELAUNCH.PHONE read and decoded data from the HKCU\SOFTWARE\Microsoft\Phone\%USERNAME% registry key (MD5: 35238d2a4626e7a1b89b13042f9390e9).
- Starting in October 2022 a subset of FONELAUNCH.PHONE samples read and decoded data from the HKCU\SOFTWARE\Microsoft\Personalization\%USERNAME% registry key.
- FONELAUNCH.DIALTONE reads and decodes data from the HKCU\SOFTWARE\Microsoft\%USERNAME% registry key. The returned content is expected to be a PE file, which is injected into a separate process and executed (MD5: aef6d31b3249218d24a7f3682a00aa10). Notably, all incidents in which FONELAUNCH.DIALTONE was deployed have led to the execution of SNOWCONE.GZIPLOADER.
Figure 10: FONELAUNCH.FAX persistence mechanism
Opening FONELAUNCH with dnSpy reveals a substitution cipher key that can be used to decode the second registry payload located in the HKCU\SOFTWARE\Microsoft\Phone\%USERNAME% registry key.
Figure 11: The dnSpy screenshot shows the substitution table and loading function
The Secondary Registry Payload
The secondary registry payload written into the registry by GOOTLOADER is a memory-only dropper written in .NET or C++ that decodes an embedded payload located in a randomly named function and executes it. Opening the .NET secondary registry payload with dnSpy reveals that it will be decoded and eventually launched in memory (Figure 12). Mandiant has observed that in most cases, this is a Cobalt Strike BEACON payload.
Figure 12: dnSpy screenshot showing the payload that will be launched in memory
Deobfuscating GOOTLOADER
You can download all scripts mentioned in this blog post from the Gootloader repository on GitHub.
GOOTLOADER Obfuscation Variant 1
As mentioned previously, deobfuscation of GOOTLOADER obfuscation variant 1 is straight-forward. Two iterations of the Python function in Figure 13 deobfuscate the contents of the JavaScript file.
Figure 13: deobfuscation function
The function in the red box contains the relevant code from GOOTLOADER 1 that must be deobfuscated (Figure 14).
Figure 14: GOOTLOADER obfuscation variant 1 JS sample
The result of the first deobfuscation iteration is shown in Figure 15.
Figure 15: First GOOTLOADER deobfuscation iteration
Deobfuscating the code in single quotes again results in the decoded script. Figure 16 shows the result after using the CyberChef “Generic Code Beautify” recipe.
Figure 16: Using CyberChef to beautify the code
GOOTLOADER Obfuscation Variant 2
Despite ultimately using the same decoding function, the updated variant of GOOTLOADER hides itself within over 10,000 lines of code for additional obfuscation.
The regex expression “.*\+.*\+.*\+.*\+.*\+.*\+.*\+.*\+.*(\n.*\=.*\+.*)*” can be used to find the relevant code block.
Figure 17: Malicious code in the GOOTLOADER obfuscation variant 2 JS file sample
As shown in Figure 17, the code populates several variables and then concatenates them together. Using the GOOTLOADER 1 script would not work here since there is no “single” string in the obfuscated code.
Truncated sample of the formula:
wabjrw = siyiqs+ektlkoi+nknhti+idkbqxaw+pqxyicj+vzphnjxnkwqcf+yycsvqac+udazlru+rnoyxn+pdolnhb+oznmgnee;
The following code block shows a different GOOTLOADER variant that uses multiple equals statements to further obfuscate the code:
Sdcsd= sdcdscs+sdcsdc; wabjrw =ujmlmdcd+sdcsd
Later samples spread the relevant code throughout the file rather than having it on a single line. However, the variables are still being set in the same order (from the top of the file down) so it is possible to automate the deobfuscation of the script.
Another distinction between samples is the comment block at the top of the file. Early samples contain “jQuery JavaScript Library” (MD5: 82607b68e061abb1d94f33a2e06b0d20) whereas later samples contain “Copyright © 2011 Sencha In–. - Author: Nicolas Garcia Belmonte” (MD5: d3787939a5681cb6d6ac7c42cd9250b5) (Figure 18 and Figure 19).
Figure 18: Early GOOTLOADER obfuscation variant 2 JS file header
Figure 19: Later GOOTLOADER obfuscation variant 2 JS file header
Manually calculating the result of the concatenated variable would be time consuming since there are many variables, and they are declared out of order. A better approach is to have a script run the string concatenation code and deobfuscate the result.
The manual deobfuscation script requires manually finding the relevant code block in the JavaScript file and entering it into the script. This is useful since minor changes in the GOOTLOADER script could break a fully automated script. Detailed deobfuscation instructions can be found in the Gootloader GitHub page.
Automated Deobfuscation of GOOTLOADER Obfuscation Variant 2 JS
Rather than manually finding the relevant code, the "GootLoaderAutoJsDecode.py" script can be used to automate the entire process. The script uses the file headers to differentiate between samples and adjust the regex search accordingly. Passing the JavaScript file as a parameter to the script will return a list of all malicious domains, and the deobfuscated code will be written to the file "DecodedJsPayload.js_". The script can be found in the Gootloader GitHub page.
Figure 20: Result of the decoding script
GOOTLOADER Obfuscation Variant 3
Unlike previous variants, GOOTLOADER obfuscation variant 3 leverages two obfuscated JavaScript files during its execution. These samples use a similar method of deobfuscation where multiple string variables are concatenated and decoded. However, an additional decoding routine is used to decode the second file that is dropped (Figure 21). Manually decoding these samples is possible but too cumbersome, using an automated script is preferred.
Figure 21: Python version of the decoding routine
Automated Deobfuscation of GOOTLOADER Obfuscation Variant 3 JS
The “GootLoaderAutoJsDecode.py” script can also be used to decode GOOTLOADER obfuscation variant 3 samples. The script uses the new decoding routine to deobfuscate the first file and saves all the relevant output to “GootLoader3Stage2.js_” which is passed back into the script for decoding. Once the script completes, the output is saved to “DecodedJsPayload.js_”, which will resemble Figure 22. The script can be found in the Gootloader GitHub page.
Figure 22: Decoded output showing the C2 domains
Reconstructing the Registry Payloads
It is possible to reconstruct the registry payloads depending on where their data resides.
Off Host — Python Script + CSV
The script “GootloaderRegDecode.py”, combined with a CSV registry export, can be used to automatically reconstruct the payloads. The script provides details on how the CSV file must be formatted, one or both registry payloads can be processed at the same time.
GootloaderRegDecode.py Payload-1-and-2-Reg-Export.csv
GootloaderRegDecode.py Payload-1-Reg-Export.csv
GootloaderRegDecode.py Payload-2-Reg-Export.csv
Both payloads will be saved to the current directory and an MD5 hash for each payload will be provided.
This script was tested using a registry export from Redline and Trellix HX triage packages. The script should work with other EDRs directly or with slight modification.
Off Host — CyberChef + Reg Export
CyberChef can be used to extract the payloads from a registry export.
- Create separate .reg exports of the HKCU\SOFTWARE\Microsoft\Phone\%USERNAME%0 and HKCU\SOFTWARE\Microsoft\Phone\%USERNAME% registry keys. The following commands can be used:
reg export HKCU\SOFTWARE\Microsoft\Phone\%USERNAME%0\ reg_stage1.reg reg export HKCU\SOFTWARE\Microsoft\Phone\%USERNAME%\ reg_stage2.reg
- Import the file into CyberChef.
- Load the appropriate CyberChef recipe (GootloaderCyberChef-Stage1.recipie) (GootloaderCyberChef-Stage2.recipie).
- Save the output.
On Host — PowerShell Script
The script “GootloaderWindowsRegDecode.ps1” can be run on a host that currently has the registry keys present. The script can be executed against the current user, or another user that exists on the system.
#Run against the current user account
GootloaderWindowsRegDecode.ps1
#Run against the JSmith user account
GootloaderWindowsRegDecode.ps1 -User JSmith
Both payloads will be saved to the current directory and an MD5 hash for each payload will be provided.
Technical Indicators
GOOTLOADER ZIP file
- 1011b2cbe016d86c7849592a76b72853
- 80a79d0c9cbc3c5188b7a247907e7264
- bee08c4481babb4c0ac6b6bb1d03658e
GOOTLOADER JS file
- 82607b68e061abb1d94f33a2e06b0d20
- 961cd55b17485bfc8b17881d4a643ad8
- af9b021a1e339841cfdf65596408862d
- d3787939a5681cb6d6ac7c42cd9250b5
- ea2271179e75b652cafd8648b698c6f9
- ab1171752af289e9f85a918845859848
Registry Payload 1 (FONELAUNCH)
- FONELAUNCH.FAX
- d6220ca85c44e2012f76193b38881185
- FONELAUNCH.PHONE
- 35238d2a4626e7a1b89b13042f9390e9
- 53c213b090784a0d413cb00c27af6100
- 7352c70b2f427ef4ff58128a428871d3
- a0b7da124962b334f6c788c27beb46e3
- a4ee41bd81dc3b842ddb2952d01f14ed
- d401dc350aff1e3fd4cc483238208b43
- ec17564ac3e10530f11a455a475f9763
- f9365bf8d4b021a873eb206ec98453d9
- aec78c1ef489f3f4b621037113cbdf81
- FONELAUNCH.DIALTONE
- 08fa99c70e90282d6bead3bb25c358dc
- aef6d31b3249218d24a7f3682a00aa10
Registry Payload 2
- Cobalt Strike BEACON
- 04746416d5767197f6ce02e894affcc7
- 2eede45eb1fe65a95aefa45811904824
- 3d768691d5cb4ae8943d8e57ea83cac1
- 84f313426047112bce498aad97778d38
- 92a271eb76a0db06c94688940bc4442b
- SNOWCONE
- 328b032c5b1d8ad5cf57538a04fb02f2
- 7a1369922cfb6d00df5f8dd33ffb9991
Network Indicators
- jonathanbartz[.]com
- jp[.]imonitorsoft[.]com
- junk-bros[.]com
- kakiosk[.]adsparkdev[.]com
- kepw[.]org
- kristinee[.]com
- lakeside-fishandchips[.]com
Cobalt Strike Beacon Backdoor
- hxxps://108.61.242[.]65/dot.gif
- hxxps://108.61.242[.]65/submit.php
- hxxps://146.70.78[.]43/fwlink
- hxxps://146.70.78[.]43/submit.php
- hxxps://87.120.254[.]39/ga.js
- hxxps://87.120.254[.]39/submit.php
- hxxps://45.150.108[.]213/ptj
- hxxps://45.150.108[.]213/submit.php
- hxxps://92.204.160[.]240/load
- hxxps://92.204.160[.]240/submit.php
More atomic indicators may be found in our Mandiant Advantage portal.
YARA Rules
The following YARA rules are not intended to be used on production systems or to inform blocking rules without first being validated through an organization's own internal testing processes to ensure appropriate performance and limit the risk of false positives. These rules are intended to serve as a starting point for hunting efforts to identify FONELAUNCH and GOOTLOADER.POWERSHELL samples; however, they may need adjustment over time if the malware family changes.
rule M_Launcher_FONELAUNCH_1
{
meta:
author = "Mandiant”
description = "Hunting rule looking for FONELAUNCH.FAX samples.”
md5 = "d6220ca85c44e2012f76193b38881185"
strings:
$str_method_a = "OpenSubKey" ascii
$str_namespace = "System.Reflection" ascii
$str_method_b = "[Environment]::GetEnvironmentVariable(" wide
$ilasmx86_sequence_encoding_a = { 0A 06 02 7D [3] 04 00 16 06 }
$ilasmx86_sequence_encoding_b = { 72 [3] 70 72 [3] 70 6F ?? 00 00 0A }
condition:
uint16(0) == 0x5A4D and all of ($str_*) and
(
$ilasmx86_sequence_encoding_a and #ilasmx86_sequence_encoding_b >= 16
)
}
rule M_Launcher_FONELAUNCH_2
{
meta:
author = "Mandiant"
description = "Hunting rule looking for FONELAUNCH.DIALTONE samples."
md5 = "aef6d31b3249218d24a7f3682a00aa10"
strings:
$ilasmx86_sequence_fprototype_a = { 1F 30 20 1B 00 10 00 28 }
$ilasmx86_sequence_fprototype_b = { 26 11 ?? 11 ?? 07 6A 20 ?? 30 00 00 1F 40 28 }
$ilasmx86_sequence_encoding_a = { 0A 06 02 7D [3] 04 00 16 06 }
$ilasmx86_sequence_encoding_b = { 72 [3] 70 72 [3] 70 6F ?? 00 00 0A }
condition:
uint16(0) == 0x5A4D and all of ($ilasmx86_sequence_fprototype_*) and
(
$ilasmx86_sequence_encoding_a and #ilasmx86_sequence_encoding_b >= 16
)
}
Detection Techniques
Malware Definitions
BEACON
BEACON is a backdoor written in C/C++ that is part of the Cobalt Strike framework. Supported backdoor commands include shell command execution, file transfer, file execution, and file management. BEACON can also capture keystrokes and screenshots as well as act as a proxy server. BEACON may also be tasked with harvesting system credentials, port scanning, and enumerating systems on a network. BEACON communicates with a C2 server via HTTP or DNS.
FONELAUNCH
FONELAUNCH is a .NET-based loader that loads an encoded payload from registry into memory.
GOOTLOADER
GOOTLOADER is a JavaScript downloader that comes in an obfuscated form. It downloads another JavaScript file which drops and executes the intended payload.
GOOTLOADER.POWERSHELL
GOOTLOADER.POWERSHELL is a variant of the GOOTLOADER downloader that was rewritten in PowerShell and retrieves payloads via HTTP. Prior to obtaining the payload, the downloader collects specific victim host information, including current Windows OS version, environment variables, list of files and running processes, and sends this information to one of ten hard-coded C2 URLs. We have observed instances where several decoy URLs were distributed amongst the list of hard-coded C2s.
SNOWCONE
SNOWCONE is a family of downloaders that retrieve their next stage payloads via HTTP and have historically been observed to download ICEDID.
Acknowledgements
Ng Choon Kiat, David Lindquist, Yash Gupta, Jonathan Lepore, Tufail Ahmed and Moritz Raabe