Bellingcat Malware Investigation

Bellingcat Malware Investigation
This article was originally published on 24 March 2024 before I migrated my blog to Ghost.

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.


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.

Bellingcat's initial tweet disclosing the incident.

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.


Initial Intake & Stage 1: Malicious Zip Archive

Stage 1 Sample

  • File name:
  • 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.

Gi7tW0rm's tweet

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.

.lnk file dropped by lure.

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 the findstr 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.

shell functionality
  • Executes findstr searching for the string "JVBERi0xLjcNJeLjz9" against the .lnk file, which creates the decoy PDF Important.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
  • 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 can also be downloaded from:


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


IOC Type Notes
506a64c619580bc91a51bde3a3c3f5aced3ed1106413ac11a721c56817b04573 sha256 zip file downloaded from usaid[.]pm called ""
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())

def main(target_dir):
    if not os.path.isdir(target_dir):
        print("Invalid target directory.")

    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.")

    for lnk_file in lnk_files:
        lnk_path = os.path.join(target_dir, lnk_file)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: <<target dir>>")
        target_dir = sys.argv[1]


        author = "Ryan <@IntelCorgi>"
        date = "2024-03-20"
        description = "Decoy LNK drops HTTP shell and fake PDF. Attributed to unknown RU-nexus threat actor."
        source = ""
        $s0 = "CiRFcnJvckFjdGlvbl" ascii
        $s1 = "gci $env:tmp -Name Rar*" ascii wide
        uint16(0) == 0x004c and
        filesize < 2MB and
        any of them

        author = "Ryan <@IntelCorgi>"
        date = "2024-03-20"
        description = "HTTP shell used in RU-nexus threat actor campaign."
        source = ""
        $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
        filesize < 2MB and
        all of them