[SHEHZADE//ABDULLAH ANSARI]
Red Team Consultant @ Google | MS in Cybersecurity @ NYU
● Notice //GitHub (@shehzade) is temporarily suspended pending an automated false-positive review. All tools are hosted on this Code Mirror and available on request (contact); GitHub links will return once reinstated.
PUBLIC MIRRORGo v1.0
Multi-protocol network egress assessment and DLP verification framework featuring automated L4 sweeps, corporate proxy traversal, and covert protocol smuggling across 20+ channels.
$
git clone https://shehzade.io/repos/contraband.git
Copy
Source ZIP (1.93 MB)
82 lines · 2.4 KB
| 1 | package multiplexer |
| 2 | |
| 3 | import ( |
| 4 | "bytes" |
| 5 | "encoding/binary" |
| 6 | "io" |
| 7 | "net" |
| 8 | "time" |
| 9 | |
| 10 | "github.com/shehzade/contraband/pkg/common" |
| 11 | ) |
| 12 | |
| 13 | // HeaderDemuxer inspects incoming connection bytes within a tight deadline. |
| 14 | type HeaderDemuxer struct { |
| 15 | peekTimeout time.Duration |
| 16 | } |
| 17 | |
| 18 | // NewHeaderDemuxer constructs a HeaderDemuxer with configured peek timeout. |
| 19 | func NewHeaderDemuxer(peekTimeout time.Duration) *HeaderDemuxer { |
| 20 | if peekTimeout <= 0 { |
| 21 | peekTimeout = 100 * time.Millisecond |
| 22 | } |
| 23 | return &HeaderDemuxer{peekTimeout: peekTimeout} |
| 24 | } |
| 25 | |
| 26 | // Demux reads initial bytes from conn. If bytes arrive immediately and match |
| 27 | // MagicHeader or HTTP/TLS signatures, it classifies as ProbeTypeSmuggling. |
| 28 | // If read times out with 0 bytes or client sends sweep ping, it classifies as ProbeTypeSweep. |
| 29 | func (d *HeaderDemuxer) Demux(conn net.Conn) (ProbeType, []byte, error) { |
| 30 | _ = conn.SetReadDeadline(time.Now().Add(d.peekTimeout)) |
| 31 | buf := make([]byte, 32) |
| 32 | n, err := conn.Read(buf) |
| 33 | _ = conn.SetReadDeadline(time.Time{}) // Clear read deadline |
| 34 | |
| 35 | if err != nil { |
| 36 | if netErr, ok := err.(net.Error); ok && netErr.Timeout() { |
| 37 | // Timeout reached with 0 bytes read -> Client is a sweep probe waiting for reflection banner! |
| 38 | return ProbeTypeSweep, nil, nil |
| 39 | } |
| 40 | if err == io.EOF && n == 0 { |
| 41 | return ProbeTypeSweep, nil, nil |
| 42 | } |
| 43 | if n == 0 { |
| 44 | return ProbeTypeUnknown, nil, err |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | peeked := buf[:n] |
| 49 | |
| 50 | // Check 0: Generic UDP probe token or newline -> Sweep |
| 51 | if bytes.HasPrefix(peeked, []byte("CTRB_UDP_PROBE")) || |
| 52 | bytes.Equal(peeked, []byte("\n")) || |
| 53 | bytes.Equal(peeked, []byte("\r\n")) { |
| 54 | return ProbeTypeSweep, peeked, nil |
| 55 | } |
| 56 | |
| 57 | // Check 1: 4-byte MagicHeader "CTRB" (0x43545242) |
| 58 | if n >= 4 { |
| 59 | magic := binary.BigEndian.Uint32(peeked[0:4]) |
| 60 | if magic == common.MagicHeader { |
| 61 | return ProbeTypeSmuggling, peeked, nil |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | // Check 2: TLS ClientHello (0x16 0x03 ...) |
| 66 | if n >= 3 && peeked[0] == 0x16 && peeked[1] == 0x03 { |
| 67 | return ProbeTypeSmuggling, peeked, nil |
| 68 | } |
| 69 | |
| 70 | // Check 3: HTTP Request Method (POST / GET / PUT / HEAD / OPTIONS / CONNECT) |
| 71 | if bytes.HasPrefix(peeked, []byte("POST ")) || |
| 72 | bytes.HasPrefix(peeked, []byte("GET ")) || |
| 73 | bytes.HasPrefix(peeked, []byte("PUT ")) || |
| 74 | bytes.HasPrefix(peeked, []byte("HEAD ")) || |
| 75 | bytes.HasPrefix(peeked, []byte("OPTIONS ")) || |
| 76 | bytes.HasPrefix(peeked, []byte("CONNECT ")) { |
| 77 | return ProbeTypeSmuggling, peeked, nil |
| 78 | } |
| 79 | |
| 80 | // Check 4: Generic UDP probe token or newline/whitespace -> Sweep |
| 81 | return ProbeTypeSweep, peeked, nil |
| 82 | } |