[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)
246 lines · 6.3 KB
| 1 | package common |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "fmt" |
| 6 | "io" |
| 7 | "os" |
| 8 | "sync" |
| 9 | "time" |
| 10 | ) |
| 11 | |
| 12 | type LogLevel int |
| 13 | |
| 14 | const ( |
| 15 | LogLevelDebug LogLevel = iota |
| 16 | LogLevelInfo |
| 17 | LogLevelSuccess |
| 18 | LogLevelWarn |
| 19 | LogLevelError |
| 20 | LogLevelFatal |
| 21 | ) |
| 22 | |
| 23 | func (l LogLevel) String() string { |
| 24 | switch l { |
| 25 | case LogLevelDebug: |
| 26 | return "DEBUG" |
| 27 | case LogLevelInfo: |
| 28 | return "INFO" |
| 29 | case LogLevelSuccess: |
| 30 | return "SUCCESS" |
| 31 | case LogLevelWarn: |
| 32 | return "WARN" |
| 33 | case LogLevelError: |
| 34 | return "ERROR" |
| 35 | case LogLevelFatal: |
| 36 | return "FATAL" |
| 37 | default: |
| 38 | return "UNKNOWN" |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | type LogMode int |
| 43 | |
| 44 | const ( |
| 45 | LogModeTerminal LogMode = iota |
| 46 | LogModeJSON |
| 47 | ) |
| 48 | |
| 49 | // ANSI Color Codes |
| 50 | const ( |
| 51 | ansiReset = "\033[0m" |
| 52 | ansiBold = "\033[1m" |
| 53 | ansiRed = "\033[1;31m" |
| 54 | ansiGreen = "\033[1;32m" |
| 55 | ansiYellow = "\033[1;33m" |
| 56 | ansiCyan = "\033[1;36m" |
| 57 | ansiMagenta = "\033[1;35m" |
| 58 | ansiDim = "\033[2m" |
| 59 | ) |
| 60 | |
| 61 | // Logger is the core logging interface for Contraband |
| 62 | type Logger interface { |
| 63 | Debug(msg string) |
| 64 | Debugf(format string, args ...any) |
| 65 | Info(msg string) |
| 66 | Infof(format string, args ...any) |
| 67 | Success(msg string) |
| 68 | Successf(format string, args ...any) |
| 69 | Warn(msg string) |
| 70 | Warnf(format string, args ...any) |
| 71 | Error(msg string) |
| 72 | Errorf(format string, args ...any) |
| 73 | Fatal(msg string) |
| 74 | Fatalf(format string, args ...any) |
| 75 | WithField(key string, val any) Logger |
| 76 | WithFields(fields map[string]any) Logger |
| 77 | SetLevel(level LogLevel) |
| 78 | SetMode(mode LogMode) |
| 79 | SetOutput(w io.Writer) |
| 80 | SetNoColor(noColor bool) |
| 81 | } |
| 82 | |
| 83 | // JSONLogEntry represents a serialized JSON log line |
| 84 | type JSONLogEntry struct { |
| 85 | Timestamp time.Time `json:"timestamp"` |
| 86 | Level string `json:"level"` |
| 87 | Indicator string `json:"indicator"` |
| 88 | Message string `json:"message"` |
| 89 | Fields map[string]any `json:"fields,omitempty"` |
| 90 | } |
| 91 | |
| 92 | type appLogger struct { |
| 93 | mu sync.Mutex |
| 94 | out io.Writer |
| 95 | level LogLevel |
| 96 | mode LogMode |
| 97 | noColor bool |
| 98 | fields map[string]any |
| 99 | // exitFunc allows mocking os.Exit in tests if needed |
| 100 | exitFunc func(code int) |
| 101 | } |
| 102 | |
| 103 | // NewLogger creates a new configured Logger instance |
| 104 | func NewLogger(out io.Writer, level LogLevel, mode LogMode) Logger { |
| 105 | if out == nil { |
| 106 | out = os.Stdout |
| 107 | } |
| 108 | noColor := os.Getenv("NO_COLOR") != "" |
| 109 | return &appLogger{ |
| 110 | out: out, |
| 111 | level: level, |
| 112 | mode: mode, |
| 113 | noColor: noColor, |
| 114 | fields: make(map[string]any), |
| 115 | exitFunc: os.Exit, |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | var ( |
| 120 | defaultLoggerMu sync.RWMutex |
| 121 | defaultLogger = NewLogger(os.Stdout, LogLevelInfo, LogModeTerminal) |
| 122 | ) |
| 123 | |
| 124 | // Global helper accessors |
| 125 | func GetLogger() Logger { |
| 126 | defaultLoggerMu.RLock() |
| 127 | defer defaultLoggerMu.RUnlock() |
| 128 | return defaultLogger |
| 129 | } |
| 130 | func SetGlobalLogger(l Logger) { defaultLoggerMu.Lock(); defaultLogger = l; defaultLoggerMu.Unlock() } |
| 131 | func Debugf(format string, args ...any) { defaultLogger.Debugf(format, args...) } |
| 132 | func Infof(format string, args ...any) { defaultLogger.Infof(format, args...) } |
| 133 | func Successf(format string, args ...any) { defaultLogger.Successf(format, args...) } |
| 134 | func Warnf(format string, args ...any) { defaultLogger.Warnf(format, args...) } |
| 135 | func Errorf(format string, args ...any) { defaultLogger.Errorf(format, args...) } |
| 136 | func Fatalf(format string, args ...any) { defaultLogger.Fatalf(format, args...) } |
| 137 | |
| 138 | func (l *appLogger) SetLevel(level LogLevel) { l.mu.Lock(); l.level = level; l.mu.Unlock() } |
| 139 | func (l *appLogger) SetMode(mode LogMode) { l.mu.Lock(); l.mode = mode; l.mu.Unlock() } |
| 140 | func (l *appLogger) SetOutput(w io.Writer) { l.mu.Lock(); l.out = w; l.mu.Unlock() } |
| 141 | func (l *appLogger) SetNoColor(noColor bool) { l.mu.Lock(); l.noColor = noColor; l.mu.Unlock() } |
| 142 | |
| 143 | func (l *appLogger) WithField(key string, val any) Logger { |
| 144 | return l.WithFields(map[string]any{key: val}) |
| 145 | } |
| 146 | |
| 147 | func (l *appLogger) WithFields(fields map[string]any) Logger { |
| 148 | l.mu.Lock() |
| 149 | defer l.mu.Unlock() |
| 150 | newFields := make(map[string]any, len(l.fields)+len(fields)) |
| 151 | for k, v := range l.fields { |
| 152 | newFields[k] = v |
| 153 | } |
| 154 | for k, v := range fields { |
| 155 | newFields[k] = v |
| 156 | } |
| 157 | return &appLogger{ |
| 158 | out: l.out, |
| 159 | level: l.level, |
| 160 | mode: l.mode, |
| 161 | noColor: l.noColor, |
| 162 | fields: newFields, |
| 163 | exitFunc: l.exitFunc, |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | func (l *appLogger) log(level LogLevel, msg string) { |
| 168 | l.mu.Lock() |
| 169 | defer l.mu.Unlock() |
| 170 | |
| 171 | if level < l.level { |
| 172 | return |
| 173 | } |
| 174 | |
| 175 | now := time.Now().UTC() |
| 176 | |
| 177 | var indicator, colorCode string |
| 178 | switch level { |
| 179 | case LogLevelDebug: |
| 180 | indicator = "[?]" |
| 181 | colorCode = ansiMagenta |
| 182 | case LogLevelInfo: |
| 183 | indicator = "[*]" |
| 184 | colorCode = ansiCyan |
| 185 | case LogLevelSuccess: |
| 186 | indicator = "[+]" |
| 187 | colorCode = ansiGreen |
| 188 | case LogLevelWarn: |
| 189 | indicator = "[!]" |
| 190 | colorCode = ansiYellow |
| 191 | case LogLevelError: |
| 192 | indicator = "[-]" |
| 193 | colorCode = ansiRed |
| 194 | case LogLevelFatal: |
| 195 | indicator = "[-]" |
| 196 | colorCode = ansiRed |
| 197 | default: |
| 198 | indicator = "[*]" |
| 199 | colorCode = ansiCyan |
| 200 | } |
| 201 | |
| 202 | if l.mode == LogModeJSON { |
| 203 | entry := JSONLogEntry{ |
| 204 | Timestamp: now, |
| 205 | Level: level.String(), |
| 206 | Indicator: indicator, |
| 207 | Message: msg, |
| 208 | Fields: l.fields, |
| 209 | } |
| 210 | data, _ := json.Marshal(entry) |
| 211 | fmt.Fprintln(l.out, string(data)) |
| 212 | } else { |
| 213 | prefix := indicator |
| 214 | if !l.noColor { |
| 215 | prefix = fmt.Sprintf("%s%s%s", colorCode, indicator, ansiReset) |
| 216 | } |
| 217 | timeStr := now.Format("15:04:05") |
| 218 | if !l.noColor { |
| 219 | timeStr = fmt.Sprintf("%s%s%s", ansiDim, timeStr, ansiReset) |
| 220 | } |
| 221 | fmt.Fprintf(l.out, "%s %s %s\n", timeStr, prefix, msg) |
| 222 | } |
| 223 | |
| 224 | if level == LogLevelFatal && l.exitFunc != nil { |
| 225 | l.exitFunc(1) |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | func (l *appLogger) Debug(msg string) { l.log(LogLevelDebug, msg) } |
| 230 | func (l *appLogger) Debugf(format string, a ...any) { l.log(LogLevelDebug, fmt.Sprintf(format, a...)) } |
| 231 | func (l *appLogger) Info(msg string) { l.log(LogLevelInfo, msg) } |
| 232 | func (l *appLogger) Infof(format string, a ...any) { l.log(LogLevelInfo, fmt.Sprintf(format, a...)) } |
| 233 | func (l *appLogger) Success(msg string) { l.log(LogLevelSuccess, msg) } |
| 234 | func (l *appLogger) Successf(format string, a ...any) { |
| 235 | l.log(LogLevelSuccess, fmt.Sprintf(format, a...)) |
| 236 | } |
| 237 | func (l *appLogger) Warn(msg string) { l.log(LogLevelWarn, msg) } |
| 238 | func (l *appLogger) Warnf(format string, a ...any) { l.log(LogLevelWarn, fmt.Sprintf(format, a...)) } |
| 239 | func (l *appLogger) Error(msg string) { l.log(LogLevelError, msg) } |
| 240 | func (l *appLogger) Errorf(format string, a ...any) { |
| 241 | l.log(LogLevelError, fmt.Sprintf(format, a...)) |
| 242 | } |
| 243 | func (l *appLogger) Fatal(msg string) { l.log(LogLevelFatal, msg) } |
| 244 | func (l *appLogger) Fatalf(format string, a ...any) { |
| 245 | l.log(LogLevelFatal, fmt.Sprintf(format, a...)) |
| 246 | } |