| package bundle |
|
|
| import "strings" |
|
|
| |
| |
| |
| |
| |
| |
| |
| type PythonSourceAnalyzer struct{} |
|
|
| func (PythonSourceAnalyzer) Name() string { return "python-source" } |
|
|
| func (PythonSourceAnalyzer) Handles(kind FileKind) bool { return kind == KindPythonSource } |
|
|
| func (PythonSourceAnalyzer) Analyze(f *File, b *Bundle) ([]Finding, error) { |
| if f == nil { |
| return nil, nil |
| } |
| text := string(f.Sniff) |
| out := sharedIndicatorScan(text, f.RelPath, "python-source") |
|
|
| |
| lines := strings.Split(text, "\n") |
| for i, l := range lines { |
| low := strings.ToLower(l) |
| if (strings.Contains(low, "eval(") || strings.Contains(low, "exec(")) && |
| (strings.Contains(low, "b64decode") || strings.Contains(low, "base64") || |
| strings.Contains(low, "decompress") || strings.Contains(low, "fromhex")) { |
| out = append(out, Finding{ |
| Analyzer: "python-source", |
| File: f.RelPath, |
| Signal: "eval-decoded-payload", |
| Severity: SevHigh, |
| Detail: "eval/exec of a decoded/decompressed payload", |
| Line: i + 1, |
| Corroborated: true, |
| }) |
| } |
| } |
|
|
| if pe, ok := paddingEvasionFinding(f, "python-source"); ok { |
| out = append(out, pe) |
| } |
| return dedupeFindings(out), nil |
| } |
|
|