[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)
242 lines · 9.9 KB
| 1 | package dryrun |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "net" |
| 6 | "os" |
| 7 | "strings" |
| 8 | "time" |
| 9 | |
| 10 | "github.com/shehzade/contraband/pkg/client" |
| 11 | "github.com/shehzade/contraband/pkg/common" |
| 12 | "github.com/shehzade/contraband/pkg/server" |
| 13 | ) |
| 14 | |
| 15 | // RunSweepDryRun executes a non-intrusive pre-flight check for the egress sweep. |
| 16 | // It performs local configuration and environment validation without transmitting |
| 17 | // any network packets or opening outbound sockets to the target host. |
| 18 | func RunSweepDryRun(target string, ports []int, protocol string, rate int, concurrency int, timeout time.Duration) error { |
| 19 | fmt.Printf("\n[+] PRE-FLIGHT DRY-RUN EXECUTION PLAN (Egress Sweep)\n") |
| 20 | fmt.Printf("====================================================\n") |
| 21 | fmt.Printf("Target Host: %s\n", target) |
| 22 | fmt.Printf("Target Port Count: %d ports\n", len(ports)) |
| 23 | fmt.Printf("Transport Protocol: %s\n", protocol) |
| 24 | fmt.Printf("Packet Rate Limit: %d pps\n", rate) |
| 25 | fmt.Printf("Worker Concurrency: %d workers\n", concurrency) |
| 26 | fmt.Printf("Socket Timeout: %s\n", timeout) |
| 27 | |
| 28 | // 1. Target Specification & DNS Resolution Validation (Local Resolver Query) |
| 29 | fmt.Printf("\n[*] Step 1: Validating Target DNS Resolution...\n") |
| 30 | lookupHost := strings.TrimSpace(target) |
| 31 | if lookupHost == "" { |
| 32 | return fmt.Errorf("target host specification cannot be empty") |
| 33 | } |
| 34 | if h, _, err := net.SplitHostPort(lookupHost); err == nil { |
| 35 | lookupHost = h |
| 36 | } |
| 37 | ips, err := net.LookupIP(lookupHost) |
| 38 | if err != nil { |
| 39 | fmt.Printf(" [-] DNS resolution note for %s: %v\n", lookupHost, err) |
| 40 | } else { |
| 41 | fmt.Printf(" [+] Successfully resolved %s -> %v\n", lookupHost, ips) |
| 42 | } |
| 43 | |
| 44 | // 2. Configuration & Local Socket Capability Validation (Target Probes Strictly Bypassed) |
| 45 | fmt.Printf("[*] Step 2: Validating Target Matrix & Local Socket Capabilities...\n") |
| 46 | if len(ports) == 0 { |
| 47 | return fmt.Errorf("no target ports specified for sweep") |
| 48 | } |
| 49 | invalidPorts := 0 |
| 50 | for _, p := range ports { |
| 51 | if p < common.PortMin || p > common.PortMax { |
| 52 | invalidPorts++ |
| 53 | } |
| 54 | } |
| 55 | if invalidPorts > 0 { |
| 56 | return fmt.Errorf("invalid port specification: found %d ports outside valid range [1-65535]", invalidPorts) |
| 57 | } |
| 58 | fmt.Printf(" [+] Target port matrix validated: %d port(s) in valid range [%d-%d]\n", len(ports), common.PortMin, common.PortMax) |
| 59 | |
| 60 | // Validate transport protocol mode |
| 61 | protoLower := strings.ToLower(protocol) |
| 62 | if protoLower != "tcp" && protoLower != "udp" && protoLower != "both" { |
| 63 | return fmt.Errorf("unsupported transport protocol %q (must be 'tcp', 'udp', or 'both')", protocol) |
| 64 | } |
| 65 | fmt.Printf(" [+] Transport protocol mode verified: %s\n", strings.ToUpper(protocol)) |
| 66 | |
| 67 | // Verify local network interface and socket capability without contacting target |
| 68 | if ifaces, err := net.Interfaces(); err == nil { |
| 69 | activeCount := 0 |
| 70 | for _, iface := range ifaces { |
| 71 | if iface.Flags&net.FlagUp != 0 { |
| 72 | activeCount++ |
| 73 | } |
| 74 | } |
| 75 | fmt.Printf(" [+] Local network interfaces detected: %d active\n", activeCount) |
| 76 | } |
| 77 | |
| 78 | // Non-destructive local loopback socket creation permission check |
| 79 | if testLn, err := net.Listen("tcp", "127.0.0.1:0"); err == nil { |
| 80 | testLn.Close() |
| 81 | fmt.Printf(" [+] Local socket creation capability verified (clean loopback release)\n") |
| 82 | } |
| 83 | |
| 84 | // Explicit operational safety indicator |
| 85 | fmt.Printf(" [*] Outbound Target Probes: STRICTLY BYPASSED (Dry-Run Mode: zero network packets/sockets sent to target)\n") |
| 86 | |
| 87 | // 3. Timing and Capacity Estimate |
| 88 | estimatedDuration := time.Second |
| 89 | if rate > 0 && len(ports) > 0 { |
| 90 | secs := len(ports) / rate |
| 91 | if secs > 0 { |
| 92 | estimatedDuration = time.Duration(secs) * time.Second |
| 93 | } |
| 94 | } |
| 95 | fmt.Printf("\n[*] Step 3: Performance Projections\n") |
| 96 | fmt.Printf(" Estimated Duration: ~%s (under %d pps rate limiter)\n", estimatedDuration, rate) |
| 97 | fmt.Printf(" Safety Status: STRICT NON-INTERFERENCE COMPLIANT\n") |
| 98 | fmt.Printf(" Payload Exfiltration: DISABLED (Dry-Run Mode Active)\n") |
| 99 | fmt.Printf("\n[+] Dry-Run Completed Successfully. Exiting cleanly.\n") |
| 100 | |
| 101 | return nil |
| 102 | } |
| 103 | |
| 104 | // RunListenDryRun executes a non-intrusive pre-flight check for the reflection listener. |
| 105 | func RunListenDryRun(bindIP string, ports []int, enableTCP bool, enableUDP bool) error { |
| 106 | fmt.Printf("\n[+] PRE-FLIGHT DRY-RUN EXECUTION PLAN (Reflection Listener)\n") |
| 107 | fmt.Printf("===========================================================\n") |
| 108 | fmt.Printf("Bind Address: %s\n", bindIP) |
| 109 | fmt.Printf("Requested Ports: %d ports\n", len(ports)) |
| 110 | fmt.Printf("TCP Reflection: %t\n", enableTCP) |
| 111 | fmt.Printf("UDP Reflection: %t\n", enableUDP) |
| 112 | |
| 113 | fmt.Printf("\n[*] Probing Local Port Availability (Strict Non-Interference Check)...\n") |
| 114 | occupied := 0 |
| 115 | available := 0 |
| 116 | |
| 117 | checkSample := ports |
| 118 | if len(checkSample) > 20 { |
| 119 | checkSample = checkSample[:20] |
| 120 | } |
| 121 | |
| 122 | for _, pt := range checkSample { |
| 123 | addr := fmt.Sprintf("%s:%d", bindIP, pt) |
| 124 | l, err := net.Listen("tcp", addr) |
| 125 | if err != nil { |
| 126 | fmt.Printf(" [!] Port %d occupied or restricted: %v (will be gracefully skipped)\n", pt, err) |
| 127 | occupied++ |
| 128 | } else { |
| 129 | l.Close() |
| 130 | available++ |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | fmt.Printf("\n[*] Port Probe Summary:\n") |
| 135 | fmt.Printf(" Sample Available: %d\n", available) |
| 136 | fmt.Printf(" Sample Occupied: %d (Protected by non-interference policy)\n", occupied) |
| 137 | fmt.Printf("\n[+] Dry-Run Completed Successfully. Exiting cleanly.\n") |
| 138 | return nil |
| 139 | } |
| 140 | |
| 141 | // RunGenerateDryRun executes a non-intrusive pre-flight check for the procedural generator. |
| 142 | func RunGenerateDryRun(dlpType string, size int64, carrier string, outputPath string, compress string, encrypt string) error { |
| 143 | fmt.Printf("\n[+] PRE-FLIGHT DRY-RUN EXECUTION PLAN (Procedural Generator)\n") |
| 144 | fmt.Printf("============================================================\n") |
| 145 | fmt.Printf("DLP Data Type: %s\n", dlpType) |
| 146 | fmt.Printf("Target Data Volume: %s (%d bytes)\n", common.FormatBytes(size), size) |
| 147 | fmt.Printf("Carrier Format: %s\n", carrier) |
| 148 | fmt.Printf("Compression: %s\n", compress) |
| 149 | fmt.Printf("Encryption: %s\n", encrypt) |
| 150 | fmt.Printf("Output Destination: %s\n", outputPath) |
| 151 | |
| 152 | if outputPath != "" { |
| 153 | if _, err := os.Stat(outputPath); err == nil { |
| 154 | return fmt.Errorf("ABSOLUTE ZERO DELETION VIOLATION: Output file %s already exists", outputPath) |
| 155 | } |
| 156 | fmt.Printf(" [+] Verified output path %s does not conflict with existing files\n", outputPath) |
| 157 | } |
| 158 | |
| 159 | fmt.Printf(" [+] Memory bound projection: <32MB heap RAM enforced\n") |
| 160 | fmt.Printf("\n[+] Dry-Run Completed Successfully. Exiting cleanly.\n") |
| 161 | return nil |
| 162 | } |
| 163 | |
| 164 | // RunClientDryRun executes a non-intrusive pre-flight check for the full egress client assessment. |
| 165 | // It strictly guarantees ZERO outbound socket packets sent to the target host. |
| 166 | func RunClientDryRun(cfg client.ClientConfig) error { |
| 167 | fmt.Printf("\n[+] PRE-FLIGHT DRY-RUN EXECUTION PLAN (Client Assessment)\n") |
| 168 | fmt.Printf("=========================================================\n") |
| 169 | fmt.Printf("Target Server: %s\n", cfg.Server) |
| 170 | fmt.Printf("Port Specification: %s\n", cfg.Ports) |
| 171 | fmt.Printf("Protocols: %s\n", cfg.Protocols) |
| 172 | fmt.Printf("DLP Payload Types: %s\n", cfg.DLPPayloads) |
| 173 | fmt.Printf("Carrier Type: %s\n", cfg.CarrierType) |
| 174 | fmt.Printf("Data Volume: %s\n", cfg.Size) |
| 175 | fmt.Printf("Chunk Size: %s\n", cfg.ChunkSize) |
| 176 | fmt.Printf("Worker Threads: %d\n", cfg.Threads) |
| 177 | fmt.Printf("Traffic Cadence: %s\n", cfg.Cadence) |
| 178 | fmt.Printf("Throughput: %s\n", cfg.Throughput) |
| 179 | fmt.Printf("Evasion Transforms: %s\n", cfg.Transforms) |
| 180 | fmt.Printf("Steganography: %s\n", cfg.Stego) |
| 181 | fmt.Printf("TLS Fingerprint: %s\n", cfg.TLSFingerprint) |
| 182 | fmt.Printf("Proxy Traversal: %s\n", cfg.Proxy) |
| 183 | |
| 184 | // Step 1: DNS Validation |
| 185 | fmt.Printf("\n[*] Step 1: Validating Target DNS Resolution...\n") |
| 186 | lookupHost := strings.TrimSpace(cfg.Server) |
| 187 | if lookupHost == "" { |
| 188 | return fmt.Errorf("target server specification cannot be empty") |
| 189 | } |
| 190 | if h, _, err := net.SplitHostPort(lookupHost); err == nil { |
| 191 | lookupHost = h |
| 192 | } |
| 193 | ips, err := net.LookupIP(lookupHost) |
| 194 | if err != nil { |
| 195 | fmt.Printf(" [-] DNS resolution note for %s: %v\n", lookupHost, err) |
| 196 | } else { |
| 197 | fmt.Printf(" [+] Resolved %s -> %v\n", lookupHost, ips) |
| 198 | } |
| 199 | |
| 200 | // Step 2: Ports & Protocols Validation |
| 201 | fmt.Printf("[*] Step 2: Validating Port Matrix & Protocols...\n") |
| 202 | ports, err := common.ParsePortsField(cfg.Ports) |
| 203 | if err != nil { |
| 204 | return fmt.Errorf("invalid ports specification %q: %w", cfg.Ports, err) |
| 205 | } |
| 206 | fmt.Printf(" [+] Target port count: %d ports validated\n", len(ports)) |
| 207 | protocols := client.ResolveProtocols(cfg.Protocols) |
| 208 | fmt.Printf(" [+] Target protocol matrix: %d protocols resolved (%s)\n", len(protocols), strings.Join(protocols, ", ")) |
| 209 | |
| 210 | // Step 3: Local Environment & Interface Validation |
| 211 | fmt.Printf("[*] Step 3: Validating Local Capabilities & Safety...\n") |
| 212 | if testLn, err := net.Listen("tcp", "127.0.0.1:0"); err == nil { |
| 213 | testLn.Close() |
| 214 | fmt.Printf(" [+] Local socket creation verified\n") |
| 215 | } |
| 216 | |
| 217 | // Invariant check |
| 218 | fmt.Printf(" [*] Outbound Target Sockets: STRICTLY ZERO - CONFIRMED\n") |
| 219 | fmt.Printf(" [*] Memory Bound Projection: <32MB Heap Resident\n") |
| 220 | fmt.Printf("\n[+] Client Assessment Dry-Run Completed Successfully.\n") |
| 221 | return nil |
| 222 | } |
| 223 | |
| 224 | // RunServerDryRun executes a non-intrusive pre-flight check for the reflection and listener server. |
| 225 | func RunServerDryRun(cfg server.ServerConfig) error { |
| 226 | fmt.Printf("\n[+] PRE-FLIGHT DRY-RUN EXECUTION PLAN (Server Lifecycle)\n") |
| 227 | fmt.Printf("========================================================\n") |
| 228 | fmt.Printf("Bind Address: %s\n", cfg.BindIP) |
| 229 | fmt.Printf("Domain: %s\n", cfg.Domain) |
| 230 | fmt.Printf("Ports: %s\n", cfg.Ports) |
| 231 | fmt.Printf("Protocols: %s\n", cfg.Protocols) |
| 232 | fmt.Printf("SMB Mode: %s\n", cfg.SMBMode) |
| 233 | fmt.Printf("Database Path: %s\n", cfg.DBPath) |
| 234 | fmt.Printf("Evidence Retention: %t (Dir: %s)\n", cfg.SavePayload, cfg.EvidenceDir) |
| 235 | |
| 236 | ports, err := common.ParsePortsField(cfg.Ports) |
| 237 | if err != nil { |
| 238 | return fmt.Errorf("invalid ports specification %q: %w", cfg.Ports, err) |
| 239 | } |
| 240 | |
| 241 | return RunListenDryRun(cfg.BindIP, ports, cfg.EnableTCP, cfg.EnableUDP) |
| 242 | } |