Bellingcat Malware Investigation
Update 17 April 2024: Mandiant Intelligence analysts published an awesome report on the threat actor group tracked as SANDWORM, which was graduated to APT44. In that report, Mandiant analysts connect this campaign to APT44.
Summary
On 22 December, 2023 the journalist group Bellingcat tweeted that they had been the target of a malicious email message which spoofed USAID, and eventually led to the download of a "malicious file". During the course of my analysis I was able to replicate the infection chain, and build detection rules as a result.
The sequence of events results in deploying an HTTP reverse shell based on an open-source offensive security tool which enabled the threat actors to harvest and exfiltrate a potential victim's sensitive data. Based on current reporting, it is not known how impactful this campaign was.
Analysis
Initial Intake & Stage 1: Malicious Zip Archive
Stage 1 Sample
- File name:
USAID-Partners_Report_2023.zip
- sha256:
506A64C619580BC91A51BDE3A3C3F5ACED3ED1106413AC11A721C56817B04573
In the tweet linked above, Bellingcat included a very general description of the infection chain for the malicious message they received, as well as the domain the email originated from (and hosted malicious content): usaid[.]pm
.
Unfortunately, Bellingcat did not share the hash of the malicious file, which means we have to acquire the sample ourselves. Of course the easiest way to acquire the sample is to just see if any other researchers have already posted. Researcher Gi7w0rm quote-tweeted the initial Bellingcat tweet with an infection chain, C2, a link to the hash on Malwarebazaar and Triage.
This blog is being written a few months after Bellingcat's initial tweet, so it is not at all surprising usaid[.]pm
is no longer active. But this sample hasn't been spread to many other online sandboxes and we don't have access to an enterprise VirusTotal license, I will just use the sample already provided.
Stage 2: .Lnk Masquerading as a PDF
Stage 2 Sample
- File Name:
2023_Annual_Report.pdf.lnk
- SHA256:
86F504DEA07FD952253904C468D83D9014A290E1FF5F2D103059638E07D14B09
The next stage in the infection chain is a .lnk file (basically a shortcut to a different file or commands )pretending to be a pdf to entice victims to click on it, thinking they are about to read a USAID annual report. The .lnk extension may not be visible depending on computer settings, further adding to the ruse.
Right clicking and inspecting the file properties of the .lnk file shows the "target" of the file. Normally you can just copy and paste the target into a text editor for easy analysis, but for some reason the entire target path was being truncated. I ended up using LnkParser3 to carve out the path. In the screenshot below, we can see the path copied from the file (top) vs the LnkParser3 result (bottom).
A victim executing the .lnk file would essentially be executing the following commands based on the target path:
- runs
cmd.exe
in the background to execute thefindstr
command. - instructs
findstr
to use a regex search for the string "CiRFcnJvckFjdGlvbl" - The results of this search are redirected to a file named
Temp.jpg
in the temporary directory - It will then launch a hidden powershell session and run a command to read the content of
Temp.jpg
, interpret it as a Base64 string, convert that string to UTF8, and subsequently execute the string using powershell.
Stage 3: Reverse Shell & Decoy PDF
Reverse Shell Sample (Decoded powershell script):
- File name: N/A
- SHA256 (dumped to ps1 file):
615F7677613534FCD5E6548B4FEE48FBFC85AF0C5ECDAD5B2046495869D1A668
Decoy PDF Sample:
- File name:
Important.pdf
- SHA256:
84F026998C5A547C8CC3BA8D86D3425097C501AE85A207C121288F6C1CF72710
In the previous stage, we saw that the target of the .lnk file includes the command findstr /R "CiRFcnJvckFjdGlvbl" 2023_Annual_Report.pdf.lnk
which dumps the output to a .jpg, decodes the content, and executes in with powershell. But the content of the data executed by powershell can be extracted by simply running the findstr
command above. After base64 decoding the content ourselves via Cyberchef, we are left with a reverse shell. Analysis of this campaign by the Cluster25 team indicates the reverse shell is an open-source pentesting tool called "HTTP-Shell". Although it should be noted the shell is based off the project instead of a direct copy and paste.
Inspecting the shell shows some obviously malicious functionality and configuration details the threat actors hard-coded into the script.
- Executes
findstr
searching for the string "JVBERi0xLjcNJeLjz9" against the .lnk file, which creates the decoy PDFImportant.pdf
. This pdf doesn't have any functionality other than acting as a decoy (so a victim will think they clicked on a legit pdf), and in this case creates a document containing interview instructions for USAID given to media contacts. - Hard-codes the domain
pdf-online[.]top
as the C2 for the shell.- The following endpoints are used in requests to the C2:
api/v1/Client/Info
api/v1/Client/Token
api/v1/Client/Debug
- The following endpoints are used in requests to the C2:
- Sends victim computer info to the C2.
- Encodes data that is uploaded and downloaded from the victim's device.
Attribution and Conclusion
I agree with the assessment made by the Cluster25 (and other threat researchers) that this campaign is attributable to an undefined Russia-nexus threat actor. The assessment is made with medium confidence based on the consistent and precise targeting of organizations which have spoken out against Russia or regularly report on malicious Russian activity.
This campaign was enabled by the open source offensive security tool HTTP Shell. While the threat actors behind this campaign may very well possess the technical resources to develop similar software, even nation-state level actors will frequently turn to tools available on GitHub to make attribution harder or simply to save time / resources.
IOCs
IOCs can also be downloaded from:
Network
IOC | Type | Notes |
---|---|---|
usaid[.]pm | domain | domain seen in URL in malicious email, which drops a malicious zip file. |
pdf-online[.]top | domain | C2 domain contacted by Reverse Shell. |
nasa[.]network | domain | [Cluster25] Domain which drops the malicious zip file, delivered via email. |
zdg[.]re | domain | [Cluster25] Domain which drops the malicious zip file, delivered via email. |
news4you[.]top | domain | [Cluster25] Domain which drops the malicious zip file, delivered via email. |
api-gate[.]xyz | domain | [Cluster25] Domain which drops the malicious zip file, delivered via email. |
80.78.26[.]183 | IPv4 | [Cluster25] IP address used in Bellingcat campaign infrastructure that previously hosted a SilverC2 beacon |
File
IOC | Type | Notes |
---|---|---|
506a64c619580bc91a51bde3a3c3f5aced3ed1106413ac11a721c56817b04573 | sha256 | zip file downloaded from usaid[.]pm called "USAID_Partners_Report_2023.zip" |
86f504dea07fd952253904c468d83d9014a290e1ff5f2d103059638e07d14b09| | sha256 | LNK file masquerading as a PDF, called "2023_Annual_Report.pdf.lnk" |
615f7677613534fcd5e6548b4fee48fbfc85af0c5ecdad5b2046495869d1a668 | sha256 | Reverse Shell written in Powershell. |
84f026998c5a547c8cc3ba8d86d3425097c501ae85a207c121288f6c1cf72710 | sha256 | Decoy PDF called "Important.pdf" |
e058bc966a436982aef3b2cbc78a380be324e80fd0789716d0c069dd441d9a48 | sha256 | [Cluster25] ZIP file dropping malicious LNK |
c3faaa3a6b0831f1d3974fcee80588812ca7afeb53cc173e0b83bcb6787fa13e | sha256 | [Cluster25] ZIP file dropping malicious LNK |
9341cd36d012f03d8829234a12b9ff4e0045cb233e86127ef322dc1c2bb0b585 | sha256 | [Cluster25] ZIP file dropping malicious LNK |
61edbae96a0e64d68f457fdc0fc4f4a66df61436a383b8e4ea2a30d9c9c2adde | sha256 | [Cluster25] ZIP file dropping malicious LNK |
36c7b7eb073a72ca37bab88b242cdadfc3cd5da7b4f714004bc63cdcee331970 | sha256 | [Cluster25] ZIP file dropping malicious LNK |
f080eec275f07aec6b7a617e215d034e67e011184e1de5b2e71e441a6dd8027f | sha256 | [Cluster25] Malicious LNK file masquerading as a PDF which will lead to an HTTP reverse shell. |
114935488cc5f5d1664dbc4c305d97a7d356b0f6d823e282978792045f1c7ddb | sha256 | [Cluster25] Malicious LNK file masquerading as a PDF which will lead to an HTTP reverse shell. |
5fa3d13366348e7c999cca9a06e4d2f5ec7f518aca3b36f0366ecedba5f2b057 | sha256 | [Cluster25] Malicious LNK file masquerading as a PDF which will lead to an HTTP reverse shell. |
a5270b4e69f042fd7232b2bfc529c72416a8867b282b197f4aea1045fd327921 | sha256 | [Cluster25] Malicious LNK file masquerading as a PDF which will lead to an HTTP reverse shell. |
975c708b22b084d4b0d503b4c8129d1ffee057a0636b1beed59c448dd76bbad1 | sha256 | [Cluster25] Malicious LNK file masquerading as a PDF which will lead to an HTTP reverse shell. |
Detection Opportunities
Detections can be found at this supplementary Github repository.
Configuration Extractor
hile not a configuration extractor in the strictest sense of the term, I put together a little python script to analyze the other LNK files mentioned in the Cluster25 article, to expand the coverage for any YARA rules.
import os
import sys
import hashlib
import LnkParse3
def extract_data_from_lnk(lnk_path):
with open(lnk_path, 'rb') as lnk_file:
lnk = LnkParse3.lnk_file(lnk_file)
print("File Hash:", hashlib.sha256(lnk_path.encode()).hexdigest())
lnk.print_json()
print("=========================================")
def main(target_dir):
if not os.path.isdir(target_dir):
print("Invalid target directory.")
return
lnk_files = [f for f in os.listdir(target_dir) if f.endswith('.lnk')]
if not lnk_files:
print("No LNK files found in the target directory.")
return
for lnk_file in lnk_files:
lnk_path = os.path.join(target_dir, lnk_file)
extract_data_from_lnk(lnk_path)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3-parser-analysis.py <<target dir>>")
else:
target_dir = sys.argv[1]
main(target_dir)
YARA
rule POTENTIAL_RU_APT_LNK_DEC23 {
meta:
author = "Ryan <@IntelCorgi>"
date = "2024-03-20"
description = "Decoy LNK drops HTTP shell and fake PDF. Attributed to unknown RU-nexus threat actor."
source = "https://blog.cluster25.duskrise.com/2024/01/30/russian-apt-opposition"
strings:
$s0 = "CiRFcnJvckFjdGlvbl" ascii
$s1 = "gci $env:tmp -Name Rar*" ascii wide
condition:
uint16(0) == 0x004c and
filesize < 2MB and
any of them
}
rule POTENIAL_RU_APT_HTTP_SHELL_DEC23 {
meta:
author = "Ryan <@IntelCorgi>"
date = "2024-03-20"
description = "HTTP shell used in RU-nexus threat actor campaign."
source = "https://blog.cluster25.duskrise.com/2024/01/30/russian-apt-opposition"
strings:
$s0 = "server/api/v1/Client/" ascii
$s1 = "HTTPShellNull" ascii
$s2 = "Mozilla/6.4 (Windows NT 11.1) Gecko/2010102 Firefox/99.0" ascii
$s3 = "6>&1 5>&1 4>&1 3>&1" ascii
condition:
filesize < 2MB and
all of them
}