typeanalysisfamilymeshcentral-agent-dropperconfidencehighcreated2026-08-18updated2026-08-18pegolangdownloaderinstallerpersistencec2defense-evasionanti-debug
SHA-256: d65f14e5652a4330354826925dc56937334163656f24dd10f112c15bc7559de1

meshcentral-agent-dropper: d65f14e5 — Go 1.26.2 MeshCentral installer with anti-debug hardening

Executive Summary

A Go 1.26.2 PE64+ distributed via the gcleaner pipeline (OpenCTI label uniq.file). Near-identical to sibling 90989061 but adds a harden_windows.go anti-debug module: debugger detection via IsDebuggerPresent, CheckRemoteDebuggerPresent, PEB.BeingDebugged, debug-port enumeration, and parent-process name checks against RE tools. Same azurenetfiles.net C2 and MeshCentral agent payload. Static-only — no CAPE detonation available.

What It Is

  • File: PE32+ executable (GUI) x86-64, 8 sections, 6,115,328 bytes ^[file.txt]
  • Compiler / Linker: Go 1.26.2, CGO_ENABLED=0, -trimpath=true ^[strings.txt:6404]
  • Go build ID: 0uj9SmzzVpuARzN9Ycd_/3T_FrFCvyrm61RfiJlX7/KCKCZl87HlwAX-MDEjKg/xuPWLgZek611TvGhl4NY ^[strings.txt:9]
  • Module path: meshdrop (devel) ^[strings.txt:6401]
  • Source files recovered: meshdrop/main.go, meshdrop/exec_windows.go, meshdrop/install_windows.go, meshdrop/harden_windows.go ^[strings.txt:15666]
  • TimeDateStamp: 0x0 (stripped / reproducible build) ^[pefile.txt:34]
  • Signed: No — IMAGE_DIRECTORY_ENTRY_SECURITY empty ^[rabin2-info.txt:27]
  • No VS_VERSIONINFO / resource directory ^[pefile.txt:246]
  • IAT: Minimal — only kernel32.dll imports (48 entries), no wininet/winhttp IAT entries; all networking via Go stdlib ^[pefile.txt:288]
  • OpenCTI labels: uniq.file, dropped-by-gcleaner, exe, u, malware-bazaar ^[triage.json]

How It Works

1. Build / RE

Toolchain: Go 1.26.2 with -trimpath=true and CGO_ENABLED=0. Standard Go cross-compile for Windows AMD64 — no packing, no obfuscation, no UPX. The binary is ~2.7 MB .text (Go runtime) plus standard library HTTP/TLS/crypto code.

Anti-analysis — the delta from sibling 90989061:

This sample adds a full anti-debug / anti-RE hardening module (meshdrop/harden_windows.go) absent from the first sibling:

Function Technique Evidence
main.detectDebugger Composite debugger detection main.detectDebugger symbol ^[strings.txt:14272]
main.isDebuggerPresent IsDebuggerPresent API IsDebuggerPresent in runtime strings + function symbol ^[strings.txt:6141]
main.isRemoteDebuggerPresent CheckRemoteDebuggerPresent API main.isRemoteDebuggerPresent symbol ^[strings.txt:14274]
main.pebDebugged PEB.BeingDebugged byte read main.pebDebugged, main.readPEBByte symbols ^[strings.txt:14277]
main.hasDebugPort Debug port enumeration main.hasDebugPort symbol ^[strings.txt:14275]
main.debugFlagsUnset NtGlobalFlag / heap flag checks main.debugFlagsUnset symbol ^[strings.txt:14276]
main.readPEBUint32 PEB dword reads for field parsing main.readPEBUint32 symbol ^[strings.txt:14279]
main.suspiciousParent Parent process name check main.suspiciousParent, main.parentProcessName symbols ^[strings.txt:14280]
main.hardenPostInstall Post-install hardening main.hardenPostInstall symbol ^[strings.txt:14283]
main.installWatchdog Watchdog / respawn main.installWatchdog symbol ^[strings.txt:14288]

RE tool blacklist (checked by main.suspiciousParent or main.detectDebugger): x64dbg.exe, x32dbg.exe, windbg.exe, idaq.exe, idaq64.exe, dnspy-x86.exe, dnspy.exe, ghidrarun.exe, wireshark.exe, procmon.exe, procmon64.exe, procexp.exe, procexp64.exe, devenv.exe ^[strings.txt:6136]

Code quality: Idiomatic Go — defer wrappers, error returns, context propagation. Function names are not randomized (unlike acrstealer / lummastealer clusters), making static analysis trivial once recognized as Go. The hardening module appears to be a clean Go syscall/unsafe implementation rather than copied from a public snippet.

2. Deploy / ATT&CK

Entry-point flow (inferred from recovered Go symbol names):

  1. main.main → checks admin rights (main.requireAdmin), hides console window (main.hideWindow), runs anti-debug checks (main.detectDebugger) ^[strings.txt:14239]
  2. main.download → HTTPS GET to https://azurenetfiles.net/meshagents?id=4&meshid=9Y7M9CsyteFGxSZPNyUB%4027EFbzf0wS%40r8bsW77uObPaWIigg2EiEGfpoYF%24W8Bb ^[strings.txt:6398]
  3. main.validatePE → checks the downloaded blob is a valid PE before writing to disk ^[strings.txt:14306]
  4. main.runInstall → stages the agent to a temp path (main.tempAgentPath), installs it as a Windows service (main.waitForService, main.serviceRunning, main.scRunning), and starts it ^[strings.txt:14297]
  5. main.runAgent → executes the installed agent binary ^[strings.txt:14296]
  6. main.hardenPostInstall → post-installation hardening (registry or file permission tweaks) ^[strings.txt:14283]
  7. main.installWatchdog → installs a watchdog with restart/60000 interval ^[strings.txt:14288]

ATT&CK mapping:

Behavior Technique Evidence
Service installation T1543.003 — Create or Modify System Process: Windows Service main.waitForService, main.serviceRunning, main.scRunning, OpenSCManagerW ^[strings.txt:6136]
Admin privilege check T1088 — Bypass User Account Control (inferred) main.requireAdmin ^[strings.txt:14292]
Window hiding T1564.010 — Hide Artifacts: VBScript (analogous) main.hideWindow ^[strings.txt:14291]
HTTPS payload download T1105 — Ingress Tool Transfer Hardcoded azurenetfiles.net URL ^[strings.txt:6398]
PE validation before execution T1027.002 — Obfuscated Files or Information: Software Packing (analogous) main.validatePE ^[strings.txt:14306]
Masquerade as legitimate software T1036.005 — Masquerading: Match Legitimate Name or Location Installs to C:\Program Files\Mesh Agent\MeshAgent.exe ^[strings.txt:6186]
Debugger detection T1622 — Debugger Evasion main.detectDebugger, IsDebuggerPresent, CheckRemoteDebuggerPresent, PEB.BeingDebugged ^[strings.txt:14272]
Anti-RE parent check T1497.001 — Virtualization/Sandbox Evasion: System Checks main.suspiciousParent checking against x64dbg.exe, idaq.exe, etc. ^[strings.txt:14280]
Watchdog persistence T1543.003 / T1547.001 — respawn monitor main.installWatchdog with restart/60000 ^[strings.txt:14288]

C2 Infrastructure:

  • URL: https://azurenetfiles.net/meshagents?id=4&meshid=9Y7M9CsyteFGxSZPNyUB%4027EFbzf0wS%40r8bsW77uObPaWIigg2EiEGfpoYF%24W8Bb ^[strings.txt:6398]
  • Domain: azurenetfiles.net
  • Mesh ID: Embedded in URL query parameter (URL-encoded @ as %40)
  • Protocol: HTTPS over TLS 1.2/1.3 via Go crypto/tls and net/http ^[strings.txt:460]

Attribution:

  • Distributed via gcleaner dropper pipeline per OpenCTI label dropped-by-gcleaner ^[triage.json]
  • The uniq.file label is a distribution classification, not a technical family. Actual payload is a MeshCentral agent installer.
  • azurenetfiles.net domain masquerades as Azure cloud infrastructure — brand-typosquatting pattern.
  • Builder iteration: sibling 90989061 had no anti-debug; this sample adds harden_windows.go. Indicates active development / A/B testing of hardening features.

Decompiled Behavior

Go symbol table is intact — no Ghidra decompilation required. Key functions:

  • main.detectDebugger — composite check: calls main.isDebuggerPresent (API), main.isRemoteDebuggerPresent (API), main.pebDebugged (PEB byte read at offset 0x02), main.hasDebugPort (debug object port enumeration), and main.debugFlagsUnset (NtGlobalFlag / heap flags). Returns boolean; if true, likely exits or sleeps.
  • main.suspiciousParent — walks the process tree via CreateToolhelp32Snapshot / Process32FirstW / Process32NextW (implied by processEntry32W type) and compares parent executable name against a blacklist of 13 RE/debugger tools. ^[strings.txt:4827]
  • main.download — wraps net/http.Client.Do with HTTPS transport. No custom TLS pinning; uses system CA store.
  • main.validatePE — parses DOS/NT headers, checks e_magic / Signature fields. Error string validate pe: not a PE file confirms behavior. ^[strings.txt:6170]
  • main.runInstall — uses Windows SCM APIs (OpenSCManagerW, CreateServiceW, StartServiceW) via syscall package.
  • main.installWatchdog — creates a watchdog process or scheduled task with restart/60000 interval (60-second respawn). ^[strings.txt:14288]
  • main.hardenPostInstall — likely adjusts file permissions or registry values to protect the installed agent from removal.

C2 Infrastructure

Indicator Value Type
C2 URL https://azurenetfiles.net/meshagents?id=4&meshid=9Y7M9CsyteFGxSZPNyUB%4027EFbzf0wS%40r8bsW77uObPaWIigg2EiEGfpoYF%24W8Bb hardcoded HTTPS download
Domain azurenetfiles.net brand-typosquatting
Install path C:\Program Files\Mesh Agent\MeshAgent.exe hardcoded service binary path
Service name Mesh Agent (inferred from path and sc query string) Windows service
Watchdog interval restart/60000 60-second respawn

Interesting Tidbits

  • Builder evolution: Sibling 90989061 had zero anti-debug. This sample adds harden_windows.go with 10 new anti-analysis functions. The builder is actively iterating — first deploy bare installer, then add hardening. ^[/intel/analyses/9098906159e0e4c845eb918886fadc2723f2a321281b8003e471f09140321f91.html]
  • FIPS 140 mode: Build flags include FIPS 140-3 references (crypto/internal/fips140/*) — unusual for crimeware, likely inherited from Go 1.26 toolchain defaults. ^[strings.txt:822]
  • No .rsrc section: No icons, no version info, no manifest. Despite Subsystem: Windows GUI, this is a bare command-line Go binary — anti-triage by appearing unfinished.
  • cmd /c sc query: The binary contains the literal batch command cmd /c sc query "Mesh Agent" | find "RUNNING" >nul || ( confirming service-status polling before installation. ^[strings.txt:6189]
  • MeshCentral abuse: Repurposes the legitimate open-source remote-management platform for unauthorized access — textbook legitimate-remote-access-tool-abuse.

How To Mess With It (Homelab Replication)

Toolchain: Go 1.26.2 for Windows AMD64 Build flags: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-s -w"

Anti-debug module sketch:

package main
import (
    "syscall"
    "unsafe"
)
func isDebuggerPresent() bool {
    var b bool
    syscall.NewLazyDLL("kernel32.dll").NewProc("IsDebuggerPresent").Call(uintptr(unsafe.Pointer(&b)))
    return b
}
func pebDebugged() bool {
    // read PEB at offset 0x02 via NtQueryInformationProcess or direct TEB access
}

Verification: Build a minimal HTTPS downloader + service installer in Go using net/http + golang.org/x/sys/windows/svc. Add the above anti-debug checks. Compare string density and section entropy to this sample.

What you'll learn: How Go's buildinfo leaks module paths even with -trimpath, and how trivial it is to add anti-debug checks that are instantly visible in the symbol table.

Deployable Signatures

YARA rule

rule MESHDROP_Go126_MeshCentral_Hardened {
    meta:
        description = "Go 1.26.2 MeshCentral agent dropper with anti-debug hardening (meshdrop)"
        author = "PacketPursuit"
        date = "2026-08-18"
        hash1 = "d65f14e5652a4330354826925dc56937334163656f24dd10f112c15bc7559de1"
        hash2 = "9098906159e0e4c845eb918886fadc2723f2a321281b8003e471f09140321f91"
    strings:
        $go_build = "go1.26.2" ascii
        $mod_path = "path\tmeshdrop" ascii
        $c2_url = "https://azurenetfiles.net/meshagents" ascii
        $func1 = "main.detectDebugger" ascii
        $func2 = "main.isDebuggerPresent" ascii
        $func3 = "main.isRemoteDebuggerPresent" ascii
        $func4 = "main.pebDebugged" ascii
        $func5 = "main.hasDebugPort" ascii
        $func6 = "main.suspiciousParent" ascii
        $func7 = "main.hardenPostInstall" ascii
        $func8 = "main.installWatchdog" ascii
        $install_path = "C:\\Program Files\\Mesh Agent\\MeshAgent.exe" ascii
        $tool1 = "x64dbg.exe" ascii
        $tool2 = "idaq.exe" ascii
        $tool3 = "dnspy.exe" ascii
        $svc1 = "OpenSCManagerW" ascii
        $svc2 = "QueryServiceStatus" ascii
    condition:
        uint16(0) == 0x5A4D and
        $go_build and
        $mod_path and
        ($c2_url or $install_path) and
        3 of ($func*) and
        1 of ($tool*) and
        1 of ($svc*)
}

Sigma rule

title: MeshCentral Agent Dropper with Anti-Debug Hardening
status: experimental
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    - Image|endswith: '\\MeshAgent.exe'
    - CommandLine|contains:
        - 'Mesh Agent'
        - 'azurenetfiles'
  anti_debug:
    - CommandLine|contains:
        - 'x64dbg'
        - 'idaq'
        - 'dnspy'
        - 'procmon'
        - 'procexp'
    - ParentImage|endswith:
        - '\\MeshAgent.exe'
  network:
    Initiated: 'true'
    DestinationHostname|contains: 'azurenetfiles.net'
  condition: selection or anti_debug or network
falsepositives:
  - Legitimate MeshCentral agent installation by authorized IT staff
level: high

IOC list

Indicator Type Context
d65f14e5652a4330354826925dc56937334163656f24dd10f112c15bc7559de1 SHA-256 This sample (hardened sibling)
9098906159e0e4c845eb918886fadc2723f2a321281b8003e471f09140321f91 SHA-256 Bare installer sibling
azurenetfiles.net Domain C2 / payload hosting
https://azurenetfiles.net/meshagents?id=4&meshid=... URL Hardcoded download URL
C:\Program Files\Mesh Agent\MeshAgent.exe File path Install target
Mesh Agent Service name Windows service (inferred)
restart/60000 String Watchdog respawn interval

Behavioral fingerprint statement

This binary is a Go 1.26.2 PE64+ with a minimal IAT (kernel32 only) and no .rsrc section. On launch, it performs composite anti-debug checks (IsDebuggerPresent, CheckRemoteDebuggerPresent, PEB.BeingDebugged, debug-port enumeration, and parent-process name blacklist against 13 RE tools). If checks pass, it performs an HTTPS GET to azurenetfiles.net, downloads a PE payload, validates DOS/NT headers, stages to a temp path, and installs it as a Windows service named "Mesh Agent" under C:\Program Files\Mesh Agent\. Post-install hardening and a 60-second watchdog respawn follow. The process tree will show the parent Go binary spawning MeshAgent.exe or service execution via svchost.

Detection Signatures

Capability ATT&CK Source
Ingress Tool Transfer T1105 Hardcoded HTTPS download URL ^[strings.txt:6398]
Create or Modify System Process: Windows Service T1543.003 SCM API strings + main.*Service* functions ^[strings.txt:6136]
Masquerading T1036.005 Installs to Program Files\Mesh Agent\ ^[strings.txt:6186]
Debugger Evasion T1622 main.detectDebugger, IsDebuggerPresent, PEB.BeingDebugged ^[strings.txt:14272]
Virtualization/Sandbox Evasion: System Checks T1497.001 Parent process name check against RE tools ^[strings.txt:14280]
Abuse Legitimate Remote Access Software T1219 MeshCentral agent abuse ^[strings.txt:6401]

References

  • Sample: d65f14e5652a4330354826925dc56937334163656f24dd10f112c15bc7559de1
  • Sibling: 9098906159e0e4c845eb918886fadc2723f2a321281b8003e471f09140321f91
  • OpenCTI labels: uniq.file, dropped-by-gcleaner, bb5.file
  • MeshCentral project: https://github.com/Ylianst/MeshCentral (legitimate open-source tool)
  • Related wiki pages: meshcentral-agent-dropper, gcleaner, legitimate-remote-access-tool-abuse

Provenance

Analysis derived from static artefacts in raw/analyses/d65f14e5652a4330354826925dc56937334163656f24dd10f112c15bc7559de1/:

  • file.txt — file type identification
  • pefile.txt — PE header and import table inspection
  • strings.txt — string extraction (Go symbols, URLs, API names, anti-debug functions)
  • rabin2-info.txt — radare2 binary summary
  • triage.json — OpenCTI labels and family classification
  • binwalk.txt — embedded artefact scan
  • metadata.json — artifact metadata Tools: strings, pefile, rabin2 (radare2 5.9.8). No Ghidra decompilation required — Go symbol table was intact.