# Twice around the dance floor - Elastic discovers the PIPEDANCE backdoor

PIPEDANCE, a named-pipe Windows backdoor, was used in an intrusion against a Vietnamese organization to run commands, enumerate files/processes, inject implants, and deploy Cobalt Strike.

- Payout: Real-world hack
- Program: Vietnamese organization
- Analysis by: Daniel Stepanic
- Disclosed: 2023-02-27
- Write-up quality: 7/10
- Original: https://www.elastic.co/security-labs/threat-command/twice-around-the-dance-floor-with-pipedance
- Library page: https://bugbountylibrary.com/r/blog%3Aelastic-co-security-labs-threat-command-twice-around-the-dance-floor-with-pipedance
- Tags: area:devices domain:network impact:internal-access impact:rce kind:incident platform:threat-intel tech:windows technique:chained vuln:privilege-escalation vuln:rce

**Target:** Windows endpoints (named pipes, makecab.exe/typeperf.exe/openfiles.exe)
**Root cause:** A custom backdoor communicates entirely over Windows named pipes (hardcoded pipe name u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe, also used as an RC4 key), dispatching 20+ command IDs to a pipe server on newly infected hosts.
**Steps:**
1. `DbgView.exe` loads PIPEDANCE into `makecab.exe` (via locally-mounted Administrator share per cited research)
2. PIPEDANCE creates named pipe `\\.\pipe\u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe` with `CreateNamedPipeA`/`ConnectNamedPipe` and waits for client
3. On first connection it sends PID, CWD, domain\username, plus an 8-byte structure with IsWow64Process flag and buffer size, RC4-encrypted with the pipe-name key
4. Operator sends 8-byte structure (command ID + arg size); argument decrypted with RC4 key
5. Command IDs 0x1-0x64 execute: kill PID, `cmd.exe` command, interactive shell, file enum, file write, process enum, injection, HTTP/DNS/ICMP/TCP checks, disconnect/exit
6. Large outputs spawn a new pipe named `<hardcoded>.<PID>`
7. Injection picks random target from `makecab.exe`, `typeperf.exe`, `w32tm.exe`, `bootcfg.exe`, `diskperf.exe`, `esentutl.exe`; thread hijacking on x86, Heaven's Gate (`NtGetContextThread`/`NtWriteVirtualMemory`/`RtlCreateUserThread`) on x64
8. `typeperf.exe` was injected into and spawned `openfiles.exe` where Cobalt Strike (`invokeassembly.x64.dll`) was loaded
**How found:** Elastic Defend's Suspicious Windows Service Execution rule fired on a monitored environment; analysts traced DbgView.exe loading makecab.exe, then typeperf.exe spawning openfiles.exe, and extracted memory regions from the Kibana alert to confirm Cobalt Strike.
**Exploitation:** Operator on an already-compromised host acts as pipe client to a PIPEDANCE server on a new victim, issuing commands over named pipes to run a reverse shell, enumerate, inject shellcode into random signed Windows binaries, and stage Cobalt Strike for further C2.
**Escalation:** PIPEDANCE used as internal proxy/lateral-movement layer, then pivots to Cobalt Strike beacon for full post-exploitation.
**Insight:** Named pipes are a viable fileless C2 channel: hunt for non-standard pipe names and for signed Windows utilities (makecab, typeperf, w32tm, bootcfg, diskperf, esentutl) making unexpected network connections or spawning children, since random selection from a small hardcoded list is a detectable signature.

## Proof of concept (copied exactly from the original report)

**YARA rule identifying PIPEDANCE**

```
rule Windows_Trojan_PipeDance {
 meta:
 author = "Elastic Security"
 creation_date = "2023-02-02"
 last_modified = "2023-02-02"
 os = "Windows"
 arch = "x86"
 category_type = "Trojan"
 family = "PipeDance"
 threat_name = "Windows.Trojan.PipeDance"
 license = "Elastic License v2"
 strings:
 $str1 = "%-5d %-30s %-4s %-7d %s" wide fullword
 $str2 = "PID Name Arch Session User" wide fullword
 $str3 = "%s %7.2f B" wide fullword
 $str4 = "\\\\.\\pipe\\%s.%d" ascii fullword
 $seq_rc4 = { 8D 46 ?? 0F B6 F0 8A 14 3E 0F B6 C2 03 C1 0F B6 C8 89 4D ?? 8A 04 0F 88 04 3E 88 14 0F 0F B6 0C 3E 0F B6 C2 03 C8 0F B6 C1 8B 4D ?? 8A 04 38 30 04 0B 43 8B 4D ?? 3B 5D ?? 72 ?? }
 $seq_srv_resp = { 8B CE 50 6A 04 5A E8 ?? ?? ?? ?? B8 00 04 00 00 8D 4E ?? 50 53 8B D0 E8 ?? ?? ?? ?? B8 08 02 00 00 8D 8E ?? ?? ?? ?? 50 57 8B D0 E8 ?? ?? ?? ?? }
 $seq_cmd_dispatch = { 83 FE 29 0F 87 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 83 FE 06 0F 87 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 8B C6 33 D2 2B C2 0F 84 ?? ?? ?? ?? 83 E8 01 }
 $seq_icmp = { 59 6A 61 5E 89 45 ?? 8B D0 89 5D ?? 2B F0 8D 04 16 8D 4B ?? 88 0A 83 F8 77 7E ?? 80 E9 17 88 0A 43 42 83 FB 20 }
 condition:
 4 of ($str*) or 2 of ($seq*)
}
```

**KQL query for injection target network connections**

```
process.name:("makecab.exe" or "typeperf.exe" or "w32tm.exe" or "bootcfg.exe" or "diskperf.exe" or "esentutl.exe") and event.dataset: endpoint.events.network
```

