[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)
107 lines · 3.0 KB
| 1 | package exfil |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | "fmt" |
| 7 | "io" |
| 8 | "sync" |
| 9 | "time" |
| 10 | |
| 11 | "github.com/shehzade/contraband/pkg/client/proxy" |
| 12 | "github.com/shehzade/contraband/pkg/client/traffic" |
| 13 | "github.com/shehzade/contraband/pkg/common" |
| 14 | ) |
| 15 | |
| 16 | var ( |
| 17 | ErrProtocolNotFound = errors.New("exfiltrator protocol not registered") |
| 18 | ErrProtocolRegistered = errors.New("exfiltrator protocol already registered") |
| 19 | ErrInvalidOptions = errors.New("invalid exfiltration options") |
| 20 | ErrHashMismatch = errors.New("exfiltrated payload hash mismatch") |
| 21 | ErrExfilFailed = errors.New("exfiltration failed") |
| 22 | ) |
| 23 | |
| 24 | // Exfiltrator defines the standardized client smuggling interface across all transport channels. |
| 25 | type Exfiltrator interface { |
| 26 | Protocol() string |
| 27 | Exfiltrate(ctx context.Context, reader io.Reader, opts ExfilOptions) (*common.ProbeResult, error) |
| 28 | } |
| 29 | |
| 30 | // ExfilOptions configures transport parameters, pacing, evasion profiles, and proxy routing. |
| 31 | type ExfilOptions struct { |
| 32 | TargetHost string |
| 33 | TargetPort int |
| 34 | UseTLS bool |
| 35 | InsecureTLS bool |
| 36 | TLSFingerprint string // "chrome", "edge", "safari", "firefox", "curl", "default" |
| 37 | SessionToken common.SessionToken |
| 38 | ChunkSize int |
| 39 | TotalBytes int64 // Total volume in bytes for bounded streaming chunk calculation |
| 40 | ExpectedHash string |
| 41 | Headers map[string]string |
| 42 | ProxyDialer proxy.Dialer |
| 43 | Shaper traffic.RateLimiter |
| 44 | Cadence *traffic.CadenceEngine |
| 45 | Timeout time.Duration |
| 46 | PayloadType string |
| 47 | CarrierType string |
| 48 | HTTPMode string // "binary", "chunked", "multipart" |
| 49 | } |
| 50 | |
| 51 | // Validate checks essential options and sets sensible defaults. |
| 52 | func (o *ExfilOptions) Validate() error { |
| 53 | if o.TargetHost == "" { |
| 54 | return fmt.Errorf("%w: target host is required", ErrInvalidOptions) |
| 55 | } |
| 56 | if o.TargetPort <= 0 || o.TargetPort > 65535 { |
| 57 | return fmt.Errorf("%w: invalid target port %d", ErrInvalidOptions, o.TargetPort) |
| 58 | } |
| 59 | if o.ChunkSize <= 0 { |
| 60 | o.ChunkSize = common.DefaultChunkSize |
| 61 | } |
| 62 | if o.Timeout <= 0 { |
| 63 | o.Timeout = 30 * time.Second |
| 64 | } |
| 65 | if o.TLSFingerprint == "" { |
| 66 | o.TLSFingerprint = common.TLSFingerprintChrome |
| 67 | } |
| 68 | if o.Headers == nil { |
| 69 | o.Headers = make(map[string]string) |
| 70 | } |
| 71 | return nil |
| 72 | } |
| 73 | |
| 74 | // Global thread-safe Exfiltrator registry |
| 75 | var ( |
| 76 | registryMu sync.RWMutex |
| 77 | registry = make(map[string]Exfiltrator) |
| 78 | ) |
| 79 | |
| 80 | // RegisterExfiltrator registers a protocol exfiltrator into the global registry. |
| 81 | func RegisterExfiltrator(proto string, ex Exfiltrator) { |
| 82 | registryMu.Lock() |
| 83 | defer registryMu.Unlock() |
| 84 | registry[proto] = ex |
| 85 | } |
| 86 | |
| 87 | // GetExfiltrator retrieves an exfiltrator by protocol identifier. |
| 88 | func GetExfiltrator(proto string) (Exfiltrator, error) { |
| 89 | registryMu.RLock() |
| 90 | defer registryMu.RUnlock() |
| 91 | ex, ok := registry[proto] |
| 92 | if !ok { |
| 93 | return nil, fmt.Errorf("%w: %s", ErrProtocolNotFound, proto) |
| 94 | } |
| 95 | return ex, nil |
| 96 | } |
| 97 | |
| 98 | // GetAllExfiltrators returns a snapshot copy of all registered exfiltrators. |
| 99 | func GetAllExfiltrators() map[string]Exfiltrator { |
| 100 | registryMu.RLock() |
| 101 | defer registryMu.RUnlock() |
| 102 | res := make(map[string]Exfiltrator, len(registry)) |
| 103 | for k, v := range registry { |
| 104 | res[k] = v |
| 105 | } |
| 106 | return res |
| 107 | } |