● 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)
Code 174 Commits 1
contraband / pkg / common / evidence.go
← Back to directory
137 lines · 3.8 KB
Raw
1package common
2
3import (
4 "fmt"
5 "path/filepath"
6 "strings"
7)
8
9// SanitizeProtocolName cleans an untrusted protocol string ensuring it only contains
10// safe alphanumeric characters, dashes, and underscores, preventing path traversal attacks.
11func SanitizeProtocolName(proto string) string {
12 cleaned := filepath.Base(filepath.Clean(proto))
13 var b strings.Builder
14 for _, r := range cleaned {
15 if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_' || r == '-' {
16 b.WriteRune(r)
17 }
18 }
19 res := b.String()
20 if res == "" || res == "." {
21 return "unknown"
22 }
23 return res
24}
25
26// DumpWithOffset formats data into canonical hex/ASCII dump format matching hexdump -C,
27// using baseOffset as the starting offset printed in the leftmost column.
28func DumpWithOffset(data []byte, baseOffset int) string {
29 if len(data) == 0 {
30 return ""
31 }
32 var b strings.Builder
33 for i := 0; i < len(data); i += 16 {
34 chunk := data[i:]
35 if len(chunk) > 16 {
36 chunk = chunk[:16]
37 }
38 // 8-digit hexadecimal offset + 2 spaces
39 b.WriteString(fmt.Sprintf("%08x ", baseOffset+i))
40
41 // 16 hex byte fields with space separator; extra space between byte 7 and 8
42 for j := 0; j < 16; j++ {
43 if j == 8 {
44 b.WriteByte(' ')
45 }
46 if j < len(chunk) {
47 b.WriteString(fmt.Sprintf("%02x ", chunk[j]))
48 } else {
49 b.WriteString(" ")
50 }
51 }
52
53 // ASCII representation enclosed in pipe delimiters
54 b.WriteString(" |")
55 for _, c := range chunk {
56 if c >= 0x20 && c <= 0x7e {
57 b.WriteByte(c)
58 } else {
59 b.WriteByte('.')
60 }
61 }
62 b.WriteString("|\n")
63 }
64 return b.String()
65}
66
67// FormatBoundedRawEvidence generates a bounded forensic hex/ASCII preview
68// (first 512 bytes header and last 256 bytes footer) for ProbeResult.RawEvidence
69// for evidence retention.
70//
71// Behavior:
72// 1. If len(data) == 0, returns an empty string.
73// 2. If len(data) <= 768 (512 header + 256 footer), formats the entire payload
74// using standard canonical hex/ASCII dump format (matching hexdump -C).
75// 3. If len(data) > 768, formats the first 512 bytes header, followed by a
76// separator line "\n... [snip %d bytes] ...\n\n", followed by the last 256 bytes
77// footer formatted with its true byte offset (len(data) - 256).
78func FormatBoundedRawEvidence(data []byte) string {
79 if len(data) == 0 {
80 return ""
81 }
82 const (
83 headerLimit = 512
84 footerLimit = 256
85 threshold = headerLimit + footerLimit // 768
86 )
87
88 if len(data) <= threshold {
89 return DumpWithOffset(data, 0)
90 }
91
92 header := data[:headerLimit]
93 footer := data[len(data)-footerLimit:]
94 snipBytes := len(data) - threshold
95
96 var b strings.Builder
97 b.WriteString(DumpWithOffset(header, 0))
98 b.WriteString(fmt.Sprintf("\n... [snip %d bytes] ...\n\n", snipBytes))
99 b.WriteString(DumpWithOffset(footer, len(data)-footerLimit))
100 return b.String()
101}
102
103// FormatBoundedRawEvidenceStream generates a bounded forensic hex/ASCII preview
104// from streaming head (up to 512B) and tail (up to 256B) buffers along with totalBytes.
105// This allows streaming exfiltrators to produce byte-identical evidence
106// previews without buffering large (50MB - 1GB+) payloads in memory.
107func FormatBoundedRawEvidenceStream(head []byte, tail []byte, totalBytes int64) string {
108 if totalBytes <= 0 {
109 return ""
110 }
111 const (
112 headerLimit = 512
113 footerLimit = 256
114 threshold = headerLimit + footerLimit // 768
115 )
116
117 if totalBytes <= threshold {
118 if int64(len(head)) > totalBytes {
119 head = head[:totalBytes]
120 }
121 return DumpWithOffset(head, 0)
122 }
123
124 if len(head) > headerLimit {
125 head = head[:headerLimit]
126 }
127 if len(tail) > footerLimit {
128 tail = tail[len(tail)-footerLimit:]
129 }
130 snipBytes := totalBytes - threshold
131
132 var b strings.Builder
133 b.WriteString(DumpWithOffset(head, 0))
134 b.WriteString(fmt.Sprintf("\n... [snip %d bytes] ...\n\n", snipBytes))
135 b.WriteString(DumpWithOffset(tail, int(totalBytes)-footerLimit))
136 return b.String()
137}