Back to reports
highPhishing

CobaltStrike Beacon Behind a Fake "Vulnerability Repair Toolkit": Live C2 on Tencent Cloud With Open Directories Exposing the Entire Kill Chain

PublishedMarch 12, 2026
Threat Actors:ProfileAssessment
phishingsocial-engineeringc2exploitspearphishing

TL;DR: A 9KB custom stager disguised as a Chinese-language "Vulnerability Repair Toolkit" downloads a 926-byte CobaltStrike x64 HTTP reverse shellcode from an open directory on a Tencent Cloud server at 118.25.10.65:8088, which beacons back to port 65011 on the same host for full C2. The operator left Python SimpleHTTPServer directory listings wide open on two ports, exposing the exploit archive, shellcode payload, and the social engineering lure -- a 7-zip file instructing victims to disable antivirus and run as administrator. The infrastructure is live and actively serving payloads as of 2026-03-09, with NPS tunneling, a Beego admin panel, and two staging servers all co-located on a single IP. ThreatFox had this flagged as Meterpreter -- it is CobaltStrike, confirmed via ROR13 API hash analysis.


One IP, Seven Services, Zero OPSEC

This investigation started with a single ThreatFox entry: 118.25.10.65:65011, tagged as a Meterpreter C2 since March 6. What ThreatFox missed -- and what open directory enumeration revealed -- is that this IP is not a single-purpose C2 server. It is a fully operational attack platform running seven distinct services on a Tencent Cloud instance in Beijing.

PortServicePurposeStatus
80NPS ProxyNAT traversal tunnelLIVE
81UnknownUnknownLIVE
443TLS (no cert served)UnknownLIVE
8088Python SimpleHTTPServerCobaltStrike shellcode stagingLIVE
8099Python SimpleHTTPServerExploit archive hostingLIVE
9991Beego 1.12.0Web application / admin panelLIVE
65011CobaltStrike BeaconC2 listenerLIVE

The NPS proxy on port 80 is particularly telling. NPS is a Go-based reverse proxy for NAT traversal that is almost exclusively used by Chinese offensive operators. Its error page (404 not found, power by nps) is a signature. Combined with the Beego web framework on port 9991 -- a Go framework predominantly used in Chinese web development -- and the Tencent Cloud hosting on AS45090, the infrastructure profile points clearly to a Chinese-origin operator.

But the real gift is the open directories.

The Open Directories: Everything on Display

Port 8088 serves a Python SimpleHTTPServer with directory listing enabled:

Directory listing for /
  http/           -- subdirectory (contains loudong.7z)
  xcc1.bin        -- CobaltStrike x64 reverse HTTP shellcode (926 bytes)

Port 8099 hosts a second open directory:

Directory listing for /
  loudong.7z      -- "Vulnerability" exploit archive (3,991 bytes)

The filename loudong is the Pinyin romanization of the Chinese word for "vulnerability." The archive contains two files: the stager executable and a Chinese-language instruction manual telling victims exactly how to infect themselves.

The Social Engineering Lure

The delivery package is loudong.7z -- a 3,991-byte 7-zip archive containing:

  1. The stager: 漏洞修复工具包.exe ("Vulnerability Repair Toolkit")
  2. The instructions: 使用说明书.txt ("User Manual")

The instruction manual, translated from Chinese:

  1. First close all running office software on your computer (such as Office, browser, chat tools, antivirus software, etc.)
  2. Double-click to run the patch installer, wait for the pop-up to complete the installation (installation takes about 3-5 minutes, do not close the computer during the pop-up) Note: If the installation reports an error or cannot run, please right-click and select "Run as Administrator".

The operator explicitly tells victims to disable security software, run the payload with elevated privileges, and wait patiently while the multi-stage infection chain completes. This is social engineering tailored for non-technical users in Chinese-speaking organizations who trust internal IT communications about vulnerability patching.

Attack Chain: Lure to Beacon in Three Stages

[DELIVERY]                    [EXECUTION]                  [STAGING]                    [C2]
loudong.7z                    漏洞修复工具包.exe           xcc1.bin (shellcode)         Full Beacon
(7-zip archive)    ------>    (9KB stager EXE)  ------->  (926 bytes, x64)   ------->  Port 65011
                              URLDownloadToFileW           VirtualAlloc + Execute       HTTP /vIGW
                              -> C:\Windows\Temp\                                       WinInet API
                                 update.dat
                              Port 8088                    Port 8088
                              http://118.25.10.65          http://118.25.10.65

Stage 1: The 9KB Stager

At only 9,216 bytes, the stager is unusually compact. It imports a single function from KERNEL32.dll -- GetLastError -- and resolves everything else at runtime.

PropertyValue
SHA-256a557d96f80d3cbe663dff79421902b556dff2cec54d7307a7f879cb20268b15e
MD5705d1e80956b88b75a4f1944a0d48436
File TypePE32+ executable (GUI) x86-64
Size9,216 bytes
PE Timestamp0xCF14DEDF (2080-02-04 -- tampered, future date)
Imphash6008cbc2d3173aad79fed4f6ab66248b
CompilerVisual Studio 2022 (MSVC 14.40+, Build 35217)

XOR-Obfuscated API Resolution

The stager uses three different XOR keys to decode API names at runtime:

XOR KeyDecoded APIPurpose
0x1ANtCreateTimerQueue / QueueTimerTimer-based deferred execution
0x12GetFileSizeValidate downloaded payload
0x15URLDownloadToFileWDownload second stage

The remaining APIs -- CloseHandle, CreateFileW, CreateTimerQueueTimer, LoadLibraryW, ReadFile, Sleep, VirtualAlloc, VirtualProtect -- are assembled as plaintext on the stack.

Fragmented C2 URL Construction

Rather than storing the C2 URL as a single string, the stager assembles it from 21 wide-character (UTF-16LE) fragments stored in .rdata, referenced through a pointer array built on the stack:

Fragment Array (stack order):
[RBP-112] = "ht"      [RBP-104] = "tp"     [RBP-96] = "://"
[RBP-88]  = "118"     [RBP-80]  = "."      [RBP-72] = "25"
[RBP-64]  = "."       [RBP-56]  = "10"     [RBP-48] = "."
[RBP-40]  = "65"      [RBP-32]  = ":"      [RBP-24] = "80"
[RBP-16]  = "88"      [RBP-8]   = "/"      [RBP+0]  = "x"
[RBP+8]   = "c"       [RBP+16]  = "c"      [RBP+24] = "1"
[RBP+32]  = "."       [RBP+40]  = "bi"     [RBP+48] = "n"

Assembled: http://118.25.10.65:8088/xcc1.bin

The . fragment is loaded once into RBX and reused at three positions for IP octet separators, and c at VA 0x2068 is stored twice via back-to-back MOV instructions. This is not sophisticated obfuscation -- any decent sandbox will reconstruct the URL -- but it defeats simple static string extraction.

Drop Path and Execution Flow

The payload drops to a path similarly constructed from fragments:

C:\Windows\Temp\update.dat

The complete execution flow:

  1. Loads urlmon.dll via LoadLibraryW
  2. Downloads shellcode via URLDownloadToFileW to C:\Windows\Temp\update.dat
  3. Opens the file with CreateFileW, reads contents with ReadFile
  4. Allocates RWX memory via VirtualAlloc
  5. Copies shellcode into allocated memory
  6. Uses CreateTimerQueueTimer for deferred execution (evasion technique -- delays shellcode launch to avoid sandbox time-based detection)
  7. Shellcode executes in memory

Stage 2: CobaltStrike Shellcode

The downloaded xcc1.bin is a 926-byte x64 position-independent CobaltStrike HTTP reverse stager.

PropertyValue
SHA-256ade8e79703b16a9daf29a3cae9fad8ab2fcbe9d4fa521d448e7654d1f648c4d4
MD5e970044acf42d124ffbc6a33d0cb0e18
Size926 bytes
C2 Server118[.]25[.]10[.]65
C2 Port65011 (0xFDF3)
Beacon URI/vIGW
User-AgentMozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)

ROR13 API Hash Resolution

The shellcode resolves APIs via the standard CobaltStrike ROR13 hash technique:

OffsetHashResolved API
0x00E70x0726774Ckernel32.dll!LoadLibraryA
0x00FF0xA779563Awininet.dll!InternetOpenA
0x01210xC69F8957wininet.dll!InternetConnectA
0x01400x3B2E55EBwininet.dll!HttpOpenRequestA
0x01840x7B18062Dwininet.dll!HttpSendRequestA
0x03450xE553A458kernel32.dll!VirtualAlloc
0x03630xE2899612kernel32.dll!VirtualProtect

This is what confirmed the family classification. ThreatFox tagged this infrastructure as Meterpreter, but the API hash values (0xA779563A for InternetOpenA, 0xC69F8957 for InternetConnectA) are from the CobaltStrike ROR13 hash table, not Meterpreter's. The shellcode prologue (fc 48 83 e4 f0 e8 c8 00 00 00) is the standard CobaltStrike x64 entry point.

Shellcode Execution Flow

  1. PEB walk to resolve kernel32.dll base address
  2. ROR13 hash loop resolves LoadLibraryA
  3. Loads wininet.dll
  4. InternetOpenA (no proxy)
  5. InternetConnectA to 118.25.10.65 on port 65011
  6. HttpOpenRequestA for GET /vIGW
  7. Sets the MSIE 8.0 User-Agent header
  8. HttpSendRequestA fetches the full beacon
  9. VirtualAlloc for 0x400000 bytes of RWX memory
  10. Full beacon loaded into allocated memory
  11. VirtualProtect marks region executable
  12. Execution transfers to the downloaded beacon

The MSIE 8.0 / Windows NT 5.1 User-Agent is the well-known CobaltStrike default. It targets legacy Windows environments still common in Chinese enterprise networks, but it is also a strong detection signal -- no legitimate software in 2026 should be sending Internet Explorer 8 user-agent strings.

Correcting the Record: CobaltStrike, Not Meterpreter

ThreatFox flagged 118.25.10.65:65011 as a Meterpreter C2 on March 6. Our analysis corrects this classification and significantly expands what is known about the infrastructure:

AspectPrior Reporting (ThreatFox)Our Findings
ClassificationMeterpreterCobaltStrike (confirmed via API hash analysis)
C2 Port65011 only8088 (staging) + 65011 (beacon C2)
InfrastructureSingle IP:portFull multi-service platform (7 services)
Delivery MethodUnknownSocial engineering via fake "Vulnerability Repair Toolkit"
Lure LanguageUnknownChinese (Mandarin)
HostingUnknown detailTencent Cloud Beijing, AS45090
Open DirectoriesUnknownTwo open dirs with payloads and exploit archives
Operator OPSECUnknownPoor -- open dirs, default Python server, exposed exploit archive
Kill ChainUnknownFull chain: lure to stager to shellcode to beacon

Threat Actor Profile

Attribution Assessment

  • Confidence: MEDIUM
  • Country/Region: China (MEDIUM-HIGH confidence)
  • Motivation: Unknown -- likely cybercrime (IAB/initial access broker) or targeted espionage
  • Sophistication: LOW-MEDIUM -- functional but sloppy OPSEC

Evidence for Chinese Origin

EvidenceWeightNotes
Tencent Cloud hosting (Beijing)MEDIUMChinese cloud, but anyone can rent
NPS proxy (Chinese tunneling tool)HIGHAlmost exclusively used by Chinese operators
Beego framework (Chinese Go framework)MEDIUMPopular in China, rare elsewhere
Chinese-language lure textHIGHNative Mandarin, proper grammar
"loudong" namingHIGHChinese word for "vulnerability" used in file naming
MSIE 8.0 / Windows NT 5.1 User-AgentMEDIUMTargets legacy Windows environments common in Chinese enterprises

OPSEC Failures

This operator made every mistake in the book:

  1. Open directory listing -- Python SimpleHTTPServer left with directory listing enabled, exposing all payloads to anyone who browses to the port
  2. Exploit archive co-located -- loudong.7z stored on the same server as the C2, linking the social engineering campaign directly to the infrastructure
  3. Default Python server -- SimpleHTTPServer instead of a proper web server reveals the staging method and screams "operator convenience over security"
  4. Everything on one IP -- NPS, Beego, two staging servers, and the CobaltStrike listener all co-located, creating a single point of discovery and takedown
  5. No domain fronting -- Direct IP communication with no CDN hiding or domain fronting
  6. Plaintext C2 IP in shellcode -- The IP address sits in cleartext at the tail of xcc1.bin
  7. Default CobaltStrike User-Agent -- The MSIE 8.0 string is one of the most signatured indicators in the industry

MITRE ATT&CK Mapping

TacticTechniqueIDImplementation
Initial AccessPhishing: Spearphishing AttachmentT1566.001Distribution via loudong.7z archive
ExecutionUser Execution: Malicious FileT1204.002Victim runs "Vulnerability Repair Toolkit"
ExecutionNative APIT1106URLDownloadToFileW, VirtualAlloc, CreateTimerQueueTimer
Defense EvasionObfuscated Files or InformationT1027XOR-encoded API strings (keys 0x1A, 0x12, 0x15)
Defense EvasionIndicator Removal: TimestompT1070.006PE timestamp set to 2080 (future date)
Defense EvasionProcess InjectionT1055.012Shellcode injection via VirtualAlloc + execute
Defense EvasionDeobfuscate/Decode FilesT1140Runtime string assembly from 21 UTF-16LE fragments
Defense EvasionMasqueradingT1036Disguised as vulnerability repair utility
Command and ControlApplication Layer Protocol: HTTPT1071.001HTTP beacon via WinInet to /vIGW
Command and ControlNon-Standard PortT1571Beacon on port 65011, staging on port 8088
Command and ControlIngress Tool TransferT1105Stager downloads shellcode to update.dat
Command and ControlProxy: External ProxyT1090.002NPS reverse proxy on port 80
PersistenceScheduled Task/JobT1053CreateTimerQueueTimer for deferred execution

Indicators of Compromise

Network Indicators

118[.]25[.]10[.]65          -- C2 server (Tencent Cloud, AS45090, Beijing)
hxxp://118[.]25[.]10[.]65:8088/xcc1.bin    -- Stage 2 shellcode download
hxxp://118[.]25[.]10[.]65:8088/            -- Open directory (staging)
hxxp://118[.]25[.]10[.]65:8099/loudong.7z  -- Exploit archive download
TypeValueContext
IP118[.]25[.]10[.]65C2 server (all ports)
URI/vIGWCobaltStrike beacon path
Port8088/tcpShellcode staging (Python SimpleHTTP)
Port8099/tcpExploit archive hosting
Port65011/tcpCobaltStrike beacon listener
Port80/tcpNPS proxy
Port9991/tcpBeego web application
User-AgentMozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)Beacon UA

File Indicators

FileSHA-256
Stage 1 stager (漏洞修复工具包.exe)a557d96f80d3cbe663dff79421902b556dff2cec54d7307a7f879cb20268b15e
Stage 2 shellcode (xcc1.bin)ade8e79703b16a9daf29a3cae9fad8ab2fcbe9d4fa521d448e7654d1f648c4d4
Exploit archive (loudong.7z)80391eeb679c47223dae4a8f9917bc6c866f45c93d04ca9a7e2b81418e1659fa
Lure text (使用说明书.txt)dec3fd326c7ab1e2449442a1ae9e182250e219bf563d3064f50cbc3b3ee7edfd
Hash TypeValueFile
MD5705d1e80956b88b75a4f1944a0d48436Stage 1 stager
SHA-1ca7ab0373730c9ac645ec60585c4e2f8f4f5edabStage 1 stager
Imphash6008cbc2d3173aad79fed4f6ab66248bStage 1 stager
MD5e970044acf42d124ffbc6a33d0cb0e18Stage 2 shellcode
SHA-1699e09d93b738417a843533151f87a5ce2144777Stage 2 shellcode

Behavioral Indicators

TypeValue
Drop pathC:\Windows\Temp\update.dat
PE timestamp0xCF14DEDF (tampered -- 2080-02-04)
XOR keys0x1A, 0x12, 0x15

Detection Opportunities

YARA Rules

rule CobaltStrike_Stager_URLDownload_XOR {
    meta:
        author = "GHOST - Breakglass Intelligence"
        date = "2026-03-09"
        description = "Detects CobaltStrike stager with XOR-encoded URLDownloadToFileW"
        hash = "a557d96f80d3cbe663dff79421902b556dff2cec54d7307a7f879cb20268b15e"
        tlp = "WHITE"

    strings:
        // XOR 0x15 encoded "URLDownloadToFileW" fragments
        $xor15_RL = { 47 59 }
        $xor15_Down = { 51 7A 62 7B }
        $xor15_load = { 79 7A 74 71 }
        $xor15_File = { 53 7C 79 70 }

        // XOR 0x1A encoded "Timer" and "Queue"
        $xor1a_Timer = { 4E 73 77 7F 68 }
        $xor1a_Queue = { 4B 6F 7F 6F 7F }

        // Wide-char URL fragments
        $w_http = { 68 00 74 00 [0-4] 74 00 70 00 [0-4] 3A 00 2F 00 2F 00 }

        // update.dat drop path
        $w_update = { 75 00 70 00 64 00 [0-4] 61 00 74 00 65 00 }

        // Single import pattern
        $import = "GetLastError" ascii
        $kernel = "KERNEL32.dll" ascii

    condition:
        uint16(0) == 0x5A4D and
        filesize < 15000 and
        (2 of ($xor15_*)) and
        (1 of ($xor1a_*)) and
        $w_http and
        $import and $kernel
}

rule CobaltStrike_Shellcode_HTTP_Reverse_vIGW {
    meta:
        author = "GHOST - Breakglass Intelligence"
        date = "2026-03-09"
        description = "Detects CobaltStrike HTTP reverse shellcode with /vIGW URI"
        hash = "ade8e79703b16a9daf29a3cae9fad8ab2fcbe9d4fa521d448e7654d1f648c4d4"
        tlp = "WHITE"

    strings:
        // CS shellcode prologue
        $prologue = { FC 48 83 E4 F0 E8 }

        // wininet string
        $wininet = "wininet" ascii

        // Beacon URI
        $uri = "/vIGW" ascii

        // User-Agent
        $ua = "MSIE 8.0; Windows NT 5.1" ascii

        // C2 IP
        $ip = "118.25.10.65" ascii

        // API hashes
        $hash_InternetOpen = { A7 79 56 3A }
        $hash_InternetConnect = { C6 9F 89 57 }
        $hash_VirtualAlloc = { E5 53 A4 58 }

    condition:
        $prologue at 0 and
        $wininet and
        $uri and
        3 of ($hash_*)
}

Suricata Rules

# CobaltStrike Beacon - /vIGW URI with MSIE 8.0 User-Agent
alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"BREAKGLASS CobaltStrike Beacon HTTP GET /vIGW";
    flow:established,to_server;
    http.method; content:"GET";
    http.uri; content:"/vIGW";
    http.user_agent; content:"MSIE 8.0; Windows NT 5.1";
    reference:url,intel.breakglass.tech;
    classtype:trojan-activity;
    sid:2026030901; rev:1;
)

# CobaltStrike Stager Download - xcc1.bin
alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"BREAKGLASS CobaltStrike Stager Download xcc1.bin";
    flow:established,to_server;
    http.method; content:"GET";
    http.uri; content:"/xcc1.bin";
    reference:url,intel.breakglass.tech;
    classtype:trojan-activity;
    sid:2026030902; rev:1;
)

# CobaltStrike C2 Communication to 118.25.10.65:65011
alert tcp $HOME_NET any -> 118.25.10.65 65011 (
    msg:"BREAKGLASS CobaltStrike C2 118.25.10.65:65011";
    flow:established,to_server;
    reference:url,intel.breakglass.tech;
    classtype:trojan-activity;
    sid:2026030903; rev:1;
)

Hunting Queries

Proxy/HTTP Logs -- Hunt for the MSIE 8.0 User-Agent string. In 2026, no legitimate software sends this. False-positive rate is near zero:

user_agent:"MSIE 8.0; Windows NT 5.1; Trident/4.0"

Endpoint Telemetry -- Search for the stager drop path:

file.path:"C:\\Windows\\Temp\\update.dat"

EDR -- Hunt for URLDownloadToFileW calls to non-standard ports:

api.call:"URLDownloadToFileW" AND destination.port:(8088 OR 8099)

Firewall/NetFlow -- Any connection to 118.25.10.65 on any port should be investigated:

destination.ip:118.25.10.65 AND destination.port:(80 OR 8088 OR 8099 OR 9991 OR 65011)

File Hunting -- Search for Chinese-language filenames associated with the lure:

file.name:("漏洞修复工具包.exe" OR "loudong.7z" OR "使用说明书.txt")

Immediate (24-48 hours):

  • Block 118[.]25[.]10[.]65 at the perimeter on all ports
  • Search proxy and DNS logs for any historical connections to this IP on ports 8088, 8099, or 65011
  • Search endpoint telemetry for C:\Windows\Temp\update.dat
  • Deploy the YARA and Suricata rules above

Short-term (1-2 weeks):

  • Hunt for the MSIE 8.0 / Windows NT 5.1 User-Agent string across all HTTP logs
  • Review any Tencent Cloud IP connections in network flow data
  • Submit IOCs to threat intel sharing platforms (MISP, OTX, ThreatFox)

Medium-term (1-3 months):

  • Report to Tencent Cloud abuse (abuse@tencent.com) for infrastructure takedown
  • Monitor for infrastructure migration -- same XOR keys, same URI patterns, same User-Agent on new IPs
  • Track the operator's tooling evolution

Published by Breakglass Intelligence. Investigation conducted 2026-03-09. C2 infrastructure confirmed LIVE at time of publication. ThreatFox classification corrected from Meterpreter to CobaltStrike. Classification: TLP:WHITE

Share