SMB Named Pipe Listeners¶
SMB named pipes provide peer-to-peer (P2P) C2 communication over internal Windows networks. Use SMB listeners when target hosts lack direct internet egress and must relay traffic through a parent beacon that does.
P2P Topology¶
SMB transport creates a parent-child beacon relationship where internal hosts chain through beacons with internet connectivity.
graph LR
subgraph Internet
Relay["Relay<br/>(Kali)"]
end
subgraph Internal Network
A["Parent Beacon<br/>10.10.10.10<br/>(Internet Egress)"]
B["Child Beacon<br/>10.10.10.50<br/>(No Egress)"]
C["Deep Child<br/>10.10.10.80<br/>(Isolated Subnet)"]
end
Relay <-->|HTTPS| A
A <-->|"SMB Pipe<br/>\\.\pipe\msagent_a1"| B
B <-->|"SMB Pipe<br/>\\.\pipe\msagent_b2"| C - Parent beacon: Has internet egress, connects to the relay over HTTPS (or any other transport). Runs an SMB pipe server that child beacons connect to.
- Child beacon: Connects to the parent's named pipe. All C2 traffic (checkin, tasks, results) is relayed through the parent to the relay.
- Chain depth: Multiple hops are supported. Beacon A can relay for B, and B can relay for C, creating deep pivot chains through segmented networks.
Bandwidth
SMB pipes carry the full HTTP C2 protocol internally. There is no bandwidth reduction compared to a direct HTTP connection -- the named pipe is simply the transport layer replacing TCP sockets.
Creating an SMB Listener¶
Create an SMB listener using the REST API:
curl -s -X POST https://stentor.app/api/v1/listeners \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "SMB Pivot",
"type": "smb_pipe",
"relay_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"port": 0,
"smb_pipe_name": "msagent_a1"
}'
The response includes the listener ID. Start the listener:
curl -s -X POST "https://stentor.app/api/v1/listeners/$LISTENER_ID/start" \
-H "Authorization: Bearer $TOKEN"
Stop the listener:
curl -s -X POST "https://stentor.app/api/v1/listeners/$LISTENER_ID/stop" \
-H "Authorization: Bearer $TOKEN"
Pipe Naming for OPSEC
Choose pipe names that blend with legitimate Windows services. Defenders monitor named pipes, so names like spoolss, samr, wkssvc, or atsvc are less likely to trigger alerts than obviously custom names.
Configuration Options¶
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Display name for the listener |
type | string | "smb_pipe" | Must be smb_pipe for SMB listeners |
relay_id | UUID | required | Relay that will host the pipe server |
port | int | 0 | Not used for SMB (pipe name is the identifier). Set to 0 or any value. |
smb_pipe_name | string | "msagent_##" | Named pipe identifier without the \\.\pipe\ prefix. ## is replaced with random hex at creation time. |
guardrails | JSON | null | Beacon filtering rules. null means accept all beacons. |
Linking and Unlinking Beacons¶
Link Command¶
The link command connects a parent beacon to a child beacon's SMB pipe server:
Example:
The parent beacon connects to \\10.10.10.50\pipe\msagent_a1 and begins relaying C2 traffic for the child.
sequenceDiagram
participant Operator
participant Parent as Parent Beacon
participant Child as Child Beacon<br/>(10.10.10.50)
Operator->>Parent: link 10.10.10.50 msagent_a1
Parent->>Child: Connect to \\10.10.10.50\pipe\msagent_a1
Child-->>Parent: Pipe connection established
Parent-->>Operator: Link successful
loop C2 Loop
Child->>Parent: Checkin / Task Results
Parent->>Operator: Relayed via HTTPS
Operator->>Parent: Tasks
Parent->>Child: Relayed via SMB pipe
end Unlink Command¶
The unlink command disconnects a child beacon from its parent:
Example:
The child beacon goes offline but is not killed. It can be re-linked later by running link again from any beacon that can reach the host.
Pipe Naming Conventions¶
| Source | Pipe Name | Description |
|---|---|---|
| Default | msagent_## | ## replaced with random hex at pipe creation |
| Malleable profile | Custom | Set via smb-beacon { set pipename "custom_name"; } |
| API request | Custom | Set via smb_pipe_name field on listener creation |
Common Legitimate Pipe Names¶
These pipe names appear on standard Windows installations and can serve as references for blending:
| Pipe Name | Service |
|---|---|
spoolss | Print Spooler |
samr | SAM Remote |
lsarpc | LSA RPC |
wkssvc | Workstation Service |
srvsvc | Server Service |
atsvc | Task Scheduler |
browser | Computer Browser |
netlogon | Netlogon |
epmapper | Endpoint Mapper |
Avoid Conflicts
Do not use the exact name of a pipe that is already running on the target. Windows does not allow duplicate pipe names. Append a suffix or variation (e.g., spoolss_01) to avoid collisions.
Encryption¶
SMB P2P connections support AES-256-GCM encryption:
- Enable: Set
encrypted: trueon the SMB client configuration. - Key exchange: Uses RSA OAEP with SHA-256 and a dedicated P2P label (
stentor-p2p-keyx), distinct from the HTTP key exchange label (stentor-keyx). - Per-session: Each link establishes a new AES-256 session key. The key exchange is transparent to the operator.
The encryption flow:
- Child requests parent's RSA public key (Phase 1)
- Child generates a 32-byte AES-256 session key
- Child encrypts the session key with the parent's RSA public key using OAEP-SHA256
- Parent decrypts and confirms by sending an encrypted "OK" response
- All subsequent messages use
session.Encrypt()/session.Decrypt()
Internal Architecture¶
The SMB pipe server uses the same HTTP C2 mux as HTTP/HTTPS listeners. From the handler's perspective, the transport is invisible -- the same beacon checkin, task queue, and result submission endpoints are served over the pipe.
| Component | Detail |
|---|---|
| Pipe path | \\.\pipe\{smb_pipe_name} |
| I/O buffer size | 64 KB (input and output) |
| Read timeout | 30 seconds |
| Write timeout | 30 seconds |
| Idle timeout | 60 seconds |
| Message mode | Stream (not message-mode) |
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
link fails: "pipe not found" | Wrong pipe name or target firewall blocking SMB (TCP 445) | Verify the pipe name matches the listener config. Ensure TCP 445 is open between parent and child. |
link fails: "access denied" | Insufficient permissions to connect to the pipe | The default security descriptor allows creator and SYSTEM. Run the parent beacon as a user with access. |
| Link drops unexpectedly | Parent beacon died or network disruption | Check parent beacon status. Re-link after parent recovers. |
| Slow throughput | Multiple hops or high-latency network | SMB pipes have 64 KB I/O buffers. Deep chains (3+ hops) accumulate latency. Consider restructuring the chain. |
| Child beacon shows "offline" after unlink | Expected behavior | The child is not killed, just disconnected. Re-link to bring it back online. |