mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 06:04:56 +03:00
feat: add 5 new cybersecurity skills - yara hunting, devsecops scanning, amcache, LOtL, privileged session monitoring
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Mahipal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: implementing-devsecops-security-scanning
|
||||
description: >
|
||||
Integrate security scanning into CI/CD pipelines using tools like Semgrep,
|
||||
Trivy, and Gitleaks. Covers SAST, SCA, container scanning, and secret
|
||||
detection with structured JSON output for pipeline gates.
|
||||
domain: cybersecurity
|
||||
subdomain: application-security
|
||||
tags: [devsecops, sast, sca, container-security, ci-cd]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: Apache-2.0
|
||||
---
|
||||
|
||||
# Implementing DevSecOps Security Scanning
|
||||
|
||||
Automate SAST, SCA, container image, and secret scanning in CI/CD
|
||||
pipelines with fail/pass gates based on severity thresholds.
|
||||
@@ -0,0 +1,68 @@
|
||||
# API Reference: DevSecOps Security Scanning
|
||||
|
||||
## Semgrep CLI (SAST)
|
||||
```bash
|
||||
# Scan with auto-detected rules
|
||||
semgrep scan --config auto --json /path/to/code
|
||||
|
||||
# Scan with specific ruleset
|
||||
semgrep scan --config p/owasp-top-ten --json /path/to/code
|
||||
|
||||
# Custom rule file
|
||||
semgrep scan --config my_rules.yaml --json /path/to/code
|
||||
|
||||
# SARIF output for GitHub integration
|
||||
semgrep scan --config auto --sarif -o results.sarif /path/to/code
|
||||
```
|
||||
|
||||
## Trivy CLI (SCA / Container)
|
||||
```bash
|
||||
# Scan container image
|
||||
trivy image --format json --quiet nginx:latest
|
||||
|
||||
# Scan filesystem for vulnerabilities
|
||||
trivy fs --format json --scanners vuln,secret /path/to/project
|
||||
|
||||
# Scan with severity filter
|
||||
trivy image --severity CRITICAL,HIGH --format json myapp:latest
|
||||
|
||||
# Scan IaC files
|
||||
trivy config --format json /path/to/terraform/
|
||||
```
|
||||
|
||||
## Gitleaks CLI (Secret Detection)
|
||||
```bash
|
||||
# Detect secrets in git repo
|
||||
gitleaks detect --source /path/to/repo --report-format json --report-path report.json
|
||||
|
||||
# Scan specific commit range
|
||||
gitleaks detect --source . --log-opts="HEAD~10..HEAD" --report-format json
|
||||
|
||||
# Protect mode (pre-commit)
|
||||
gitleaks protect --staged --report-format json
|
||||
```
|
||||
|
||||
## CI/CD Pipeline Gate Logic
|
||||
| Severity | Exit Code | Action |
|
||||
|----------|-----------|--------|
|
||||
| CRITICAL | 1 (fail) | Block merge/deploy |
|
||||
| HIGH | 1 (fail) | Block merge/deploy |
|
||||
| MEDIUM | 0 (warn) | Warning in PR comment |
|
||||
| LOW | 0 (pass) | Informational only |
|
||||
|
||||
## JSON Output Schema (Semgrep)
|
||||
| Field | Description |
|
||||
|-------|------------|
|
||||
| results[].check_id | Rule identifier |
|
||||
| results[].extra.severity | ERROR, WARNING, INFO |
|
||||
| results[].path | Affected file path |
|
||||
| results[].start.line | Line number |
|
||||
| results[].extra.message | Finding description |
|
||||
|
||||
## JSON Output Schema (Trivy)
|
||||
| Field | Description |
|
||||
|-------|------------|
|
||||
| Results[].Target | Scanned target name |
|
||||
| Results[].Vulnerabilities[].VulnerabilityID | CVE identifier |
|
||||
| Results[].Vulnerabilities[].Severity | CRITICAL/HIGH/MEDIUM/LOW |
|
||||
| Results[].Vulnerabilities[].FixedVersion | Version with fix |
|
||||
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""DevSecOps security scanning pipeline agent.
|
||||
|
||||
Orchestrates Semgrep (SAST), Trivy (container/SCA), and Gitleaks (secrets)
|
||||
scans via subprocess, aggregates findings, and enforces severity gates.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
|
||||
SEVERITY_ORDER = {"CRITICAL": 4, "HIGH": 3, "MEDIUM": 2, "LOW": 1, "INFO": 0}
|
||||
|
||||
|
||||
def run_semgrep(target_dir, config="auto"):
|
||||
"""Run Semgrep SAST scan and return findings."""
|
||||
cmd = ["semgrep", "scan", "--config", config, "--json", "--quiet", target_dir]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
|
||||
data = json.loads(result.stdout) if result.stdout.strip() else {}
|
||||
findings = []
|
||||
for r in data.get("results", []):
|
||||
findings.append({
|
||||
"tool": "semgrep",
|
||||
"rule_id": r.get("check_id", ""),
|
||||
"severity": r.get("extra", {}).get("severity", "WARNING").upper(),
|
||||
"message": r.get("extra", {}).get("message", ""),
|
||||
"file": r.get("path", ""),
|
||||
"line": r.get("start", {}).get("line", 0),
|
||||
})
|
||||
return findings
|
||||
except FileNotFoundError:
|
||||
return [{"tool": "semgrep", "error": "semgrep not installed"}]
|
||||
except subprocess.TimeoutExpired:
|
||||
return [{"tool": "semgrep", "error": "scan timed out"}]
|
||||
except json.JSONDecodeError:
|
||||
return [{"tool": "semgrep", "error": "invalid JSON output"}]
|
||||
|
||||
|
||||
def run_trivy(image_or_path, scan_type="image"):
|
||||
"""Run Trivy vulnerability scan on image or filesystem."""
|
||||
cmd = ["trivy", scan_type, "--format", "json", "--quiet", image_or_path]
|
||||
if scan_type == "fs":
|
||||
cmd = ["trivy", "fs", "--format", "json", "--quiet", "--scanners", "vuln,secret", image_or_path]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
|
||||
data = json.loads(result.stdout) if result.stdout.strip() else {}
|
||||
findings = []
|
||||
for res in data.get("Results", []):
|
||||
for vuln in res.get("Vulnerabilities", []):
|
||||
findings.append({
|
||||
"tool": "trivy",
|
||||
"rule_id": vuln.get("VulnerabilityID", ""),
|
||||
"severity": vuln.get("Severity", "UNKNOWN").upper(),
|
||||
"message": vuln.get("Title", ""),
|
||||
"file": res.get("Target", ""),
|
||||
"line": 0,
|
||||
"fixed_version": vuln.get("FixedVersion", ""),
|
||||
})
|
||||
return findings
|
||||
except FileNotFoundError:
|
||||
return [{"tool": "trivy", "error": "trivy not installed"}]
|
||||
except (subprocess.TimeoutExpired, json.JSONDecodeError) as e:
|
||||
return [{"tool": "trivy", "error": str(e)}]
|
||||
|
||||
|
||||
def run_gitleaks(repo_path):
|
||||
"""Run Gitleaks secret detection scan."""
|
||||
cmd = ["gitleaks", "detect", "--source", repo_path, "--report-format", "json",
|
||||
"--report-path", "/dev/stdout", "--no-banner"]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
|
||||
data = json.loads(result.stdout) if result.stdout.strip().startswith("[") else []
|
||||
findings = []
|
||||
for leak in data:
|
||||
findings.append({
|
||||
"tool": "gitleaks",
|
||||
"rule_id": leak.get("RuleID", ""),
|
||||
"severity": "HIGH",
|
||||
"message": leak.get("Description", ""),
|
||||
"file": leak.get("File", ""),
|
||||
"line": leak.get("StartLine", 0),
|
||||
})
|
||||
return findings
|
||||
except FileNotFoundError:
|
||||
return [{"tool": "gitleaks", "error": "gitleaks not installed"}]
|
||||
except (subprocess.TimeoutExpired, json.JSONDecodeError) as e:
|
||||
return [{"tool": "gitleaks", "error": str(e)}]
|
||||
|
||||
|
||||
def enforce_gate(findings, fail_on="HIGH"):
|
||||
"""Enforce security gate based on severity threshold."""
|
||||
threshold = SEVERITY_ORDER.get(fail_on.upper(), 3)
|
||||
blockers = [
|
||||
f for f in findings
|
||||
if not f.get("error") and SEVERITY_ORDER.get(f.get("severity", ""), 0) >= threshold
|
||||
]
|
||||
return {
|
||||
"gate_threshold": fail_on,
|
||||
"blocking_findings": len(blockers),
|
||||
"passed": len(blockers) == 0,
|
||||
}
|
||||
|
||||
|
||||
def aggregate_report(all_findings):
|
||||
"""Aggregate findings from all scanners."""
|
||||
by_severity = {}
|
||||
by_tool = {}
|
||||
for f in all_findings:
|
||||
if f.get("error"):
|
||||
continue
|
||||
sev = f.get("severity", "UNKNOWN")
|
||||
tool = f.get("tool", "unknown")
|
||||
by_severity[sev] = by_severity.get(sev, 0) + 1
|
||||
by_tool[tool] = by_tool.get(tool, 0) + 1
|
||||
return {
|
||||
"total_findings": sum(1 for f in all_findings if not f.get("error")),
|
||||
"by_severity": by_severity,
|
||||
"by_tool": by_tool,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="DevSecOps security scanning pipeline")
|
||||
parser.add_argument("target", nargs="?", help="Directory or container image to scan")
|
||||
parser.add_argument("--semgrep", action="store_true", help="Run Semgrep SAST")
|
||||
parser.add_argument("--trivy", action="store_true", help="Run Trivy vulnerability scan")
|
||||
parser.add_argument("--trivy-type", default="fs", choices=["image", "fs"], help="Trivy scan type")
|
||||
parser.add_argument("--gitleaks", action="store_true", help="Run Gitleaks secret detection")
|
||||
parser.add_argument("--fail-on", default="HIGH", help="Fail gate on severity (default: HIGH)")
|
||||
parser.add_argument("--output", "-o", help="Output JSON report path")
|
||||
args = parser.parse_args()
|
||||
|
||||
print("[*] DevSecOps Security Scanning Pipeline")
|
||||
report = {"timestamp": datetime.datetime.utcnow().isoformat() + "Z", "findings": []}
|
||||
|
||||
if not args.target:
|
||||
print("[DEMO] Usage: python agent.py /path/to/code --semgrep --trivy --gitleaks")
|
||||
print(" Tools: semgrep (SAST), trivy (SCA/container), gitleaks (secrets)")
|
||||
print(json.dumps({"demo": True, "tools": ["semgrep", "trivy", "gitleaks"]}, indent=2))
|
||||
sys.exit(0)
|
||||
|
||||
if args.semgrep:
|
||||
report["findings"].extend(run_semgrep(args.target))
|
||||
if args.trivy:
|
||||
report["findings"].extend(run_trivy(args.target, args.trivy_type))
|
||||
if args.gitleaks:
|
||||
report["findings"].extend(run_gitleaks(args.target))
|
||||
|
||||
summary = aggregate_report(report["findings"])
|
||||
gate = enforce_gate(report["findings"], args.fail_on)
|
||||
report["summary"] = summary
|
||||
report["gate"] = gate
|
||||
|
||||
print(f"[*] Total findings: {summary['total_findings']}")
|
||||
print(f"[*] By severity: {summary['by_severity']}")
|
||||
print(f"[*] Gate ({args.fail_on}): {'PASSED' if gate['passed'] else 'FAILED'}")
|
||||
|
||||
if args.output:
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print(json.dumps({"gate_passed": gate["passed"], "total": summary["total_findings"]}, indent=2))
|
||||
sys.exit(0 if gate["passed"] else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user