image # AI Agents | DorkEye Project The Agents pipeline runs automatically after a dork search when `--analyze` is active (or when the output file is `.json`). It requires no external AI — every step uses regex, heuristics, and structural analysis only. --- ## Activate ```bash # Automatic (output .json triggers a prompt) python dorkeye.py -d "site:example.com" -o results.json # Explicit python dorkeye.py -d "site:example.com" -o results.json --analyze # With page content download python dorkeye.py -d "site:example.com" -o results.json --analyze --analyze-fetch # Standalone on saved results python dorkeye_agents.py Dump/results.json --analyze-fetch --analyze-fmt html ``` --- ## Pipeline — 13 Steps | Step | Agent | Input | Output | |------|-------|-------|--------| | 1 | **TriageAgent** | All results | `triage_score`, `triage_label`, `triage_reason` per result | | 2 | **PageFetchAgent** | HIGH / CRITICAL results | `page_content`, `response_headers`, `fetch_status` | | 3 | **SecurityAgent** | `page_content` + `response_headers` + URL | `security_verdict` dict with `threat_level`, `threat_score`, `indicators` | | 4 | **HeaderIntelAgent** | `response_headers` | `header_intel` (info leaks, missing headers, outdated versions) | | 5 | **TechFingerprintAgent** | `page_content` + headers + URL | `tech_fingerprint` (techs, versions, CVE dorks) | | 6 | **SecretsAgent** | `page_content` + snippet | `secrets` list with type, value, severity, context | | 7 | **PiiDetectorAgent** | `page_content` + snippet | `pii_found` list with type, censored value, context | | 8 | **EmailHarvesterAgent** | `page_content` + snippet | `emails_found` list, global dedup | | 9 | **SubdomainHarvesterAgent** | All text fields | `subdomains` list per result, global map | | 10 | **LLM Analysis** | All triaged results | `analysis` dict (optional — requires `dorkeye_llm_plugin.py`) | | 11 | **ReportAgent** | Everything above | HTML / MD / JSON / TXT report | | 12 | **DBScanAgent** | Hosts extracted from results | `db_scan` per-host findings, `DBScanReport` | | 13 | **DorkCrawlerAgent** | CVE dorks + subdomain seeds | Follow-up dork results merged into pipeline | --- ## TriageAgent Assigns a score (0–100) and label (CRITICAL / HIGH / MEDIUM / LOW / SKIP) to every result. **Scoring — two phases:** Phase 1 — regex pattern matching (cap: 60 points): | Pattern matched | Points | |----------------|--------| | `.env`, `.git`, `.sql`, backup files | 38 | | Private key (`BEGIN PRIVATE KEY`) | 45 | | AWS key ID (`AKIA...`) | 42 | | JWT token in text | 36 | | phpMyAdmin / Adminer / pgAdmin | 35 | | API key / secret token | 28 | | Config file (`config.php`, `settings.py`) | 28 | | SQLi candidate URL pattern | 26 | | Credentials / password in text | 24 | | DevOps panels (Jenkins, Kibana, Grafana) | 18–22 | | Cloud storage URLs | 18 | | Directory listing | 22 | | Server info exposed | 20 | | Log files | 20 | | Error / debug / traceback | 14 | | ... 8 more rules | varies | Phase 2 — runtime bonuses from existing result data: | Condition | Bonus | |-----------|-------| | SQLi confirmed — confidence `critical` | +30 | | SQLi confirmed — confidence `high` | +22 | | SQLi confirmed — confidence `medium` or `low` | +12 | | `accessible == True` and `status_code == 200` | +8 | | URL has ≥ 5 GET parameters | +10 | | URL has 2–4 GET parameters | +5 | **Labels:** | Score | Label | |-------|-------| | ≥ 90 | CRITICAL | | ≥ 70 | HIGH | | ≥ 50 | MEDIUM | | ≥ 20 | LOW | | < 20 | SKIP | --- ## SecurityAgent Threat-detection middleware that operates in **two modes**: - **passive** (default in `--analyze` pipeline) — analyses and tags every result with a `security_verdict`, no blocking. - **active** — same as passive, plus blocks (`security_blocked = True`) results classified as DANGEROUS or CRITICAL. It also hooks into the **live scanning flow** via `security_scan_hook(url, content, headers)` so threats can be intercepted before results are saved. **Detection categories:** | Category | Description | |----------|-------------| | `phishing` | Brand impersonation, credential harvesting pages, suspicious redirects | | `malware` | JS code execution, obfuscated payloads, file droppers | | `exploit` | Reverse shells, SQLi, XXE, SSTI, deserialization payloads | | `obfuscation` | Hex/Unicode escaping, base64 chains, high-entropy strings | | `suspicious_pattern` | Hidden iframes, missing security headers, executable downloads | **Threat scoring — weighted model:** The final `threat_score` (0–100) is computed as: - **50%** from the single worst indicator - **50%** from the weighted sum of all other indicators (capped) | Score range | Threat level | |-------------|-------------| | ≤ 15 | CLEAN | | 16 – 40 | LOW | | 41 – 70 | SUSPICIOUS | | 71 – 90 | DANGEROUS | | > 90 | CRITICAL | DANGEROUS and CRITICAL results are automatically blocked in `active` mode. **CLI flags:** ```bash --no-security # Disable SecurityAgent entirely --security-mode active # active: block DANGEROUS/CRITICAL | passive: report only (default) --security-quarantine # Save blocked content to dorkeye_quarantine/ ``` **Output per result:** ```json { "security_verdict": { "url": "https://target.com/shell.php", "threat_level": "DANGEROUS", "threat_score": 78, "badge": "🔴 DANGEROUS", "blocked": false, "summary": "Reverse shell pattern detected in page content", "scan_duration_ms": 12.4, "timestamp": "2025-01-01T12:00:00+00:00", "indicators": [ { "category": "exploit", "description": "Reverse shell pattern", "severity": 60, "evidence": "bash -i >& /dev/tcp/..." } ] } } ``` **Pipeline-level output keys** (added to the top-level report): | Key | Content | |-----|---------| | `security_stats` | Counters: `clean`, `low`, `suspicious`, `dangerous`, `critical`, `blocked`, `mode` | | `security_threats` | List of all verdicts with `threat_level` ≥ LOW | **Inline usage (scanning flow):** ```python from dorkeye_agents import security_scan_hook, get_security_agent # Quick hook (uses global singleton) verdict = security_scan_hook(url, response_text, resp_headers) if verdict.blocked: continue # skip malicious result # Fine-grained control agent = get_security_agent(mode="active", quarantine_dir="dorkeye_quarantine") verdict = agent.scan_single(url, content, headers) ``` --- ## PageFetchAgent Downloads the actual HTML content of HIGH and CRITICAL results for deeper analysis. **Features:** - Up to 3 attempts per URL (1 initial + 2 retries with 1.5s / 3s backoff) - UA rotation across 5 browser profiles on each attempt - Saves `response_headers` dict and `fetch_status` code into the result — consumed by HeaderIntelAgent at zero extra HTTP cost **CLI flags:** ```bash --analyze-fetch # enable download --analyze-fetch-max 50 # download up to 50 pages (default: 20) ``` --- ## HeaderIntelAgent Analyzes `response_headers` saved by PageFetchAgent. Zero additional HTTP requests. **Info leak detection** — scans these headers: ``` server · x-powered-by · x-aspnet-version · x-aspnetmvc-version x-generator · x-drupal-cache · x-wordpress-cache x-runtime · x-rack-cache · via · x-debug · x-cache-debug ``` **Outdated version detection** — extracts version strings for: Apache, Nginx, PHP, OpenSSL, IIS, Tomcat, Jetty, Lighttpd. **Missing security headers** — flags absence of: | Header | Risk | |--------|------| | `Strict-Transport-Security` | HSTS absent — MITM risk | | `Content-Security-Policy` | CSP absent — XSS risk | | `X-Frame-Options` | Clickjacking protection absent | | `X-Content-Type-Options` | MIME sniffing protection absent | | `Referrer-Policy` | Referrer-Policy absent | | `Permissions-Policy` | Permissions-Policy absent | **Output per result:** ```json { "header_intel": { "info_leaks": [{"header": "x-powered-by", "value": "PHP/5.6.40", "version": "PHP/5.6"}], "missing_security": [{"header": "content-security-policy", "reason": "CSP absent — XSS risk"}], "outdated": [{"header": "server", "value": "Apache/2.2.34", "version": "Apache/2.2"}] } } ``` --- ## TechFingerprintAgent Identifies technologies from `page_content`, `response_headers`, snippet, URL, and title. Attempts version extraction where possible. **35 signatures in 7 categories:** | Category | Technologies | |----------|-------------| | CMS | WordPress, Joomla, Drupal, Magento, PrestaShop, TYPO3, Shopify, Wix | | Framework | Laravel, Django, Rails, Flask, Express.js, Next.js, Nuxt.js | | JS libraries | jQuery (versioned), React, Vue.js, Angular, Bootstrap (versioned) | | Server | Apache, Nginx, IIS, OpenSSL (all versioned) | | Language | PHP, Python, Node.js (all versioned) | | DevOps | Jenkins, GitLab, Kibana, Grafana, Docker, Kubernetes, Elasticsearch | | DB panels | phpMyAdmin, Adminer, pgAdmin | **CVE dork generation** — for 10 tech families, targeted dorks are generated and fed to DorkCrawlerAgent: ``` site:target.com inurl:wp-login.php site:target.com inurl:xmlrpc.php site:target.com inurl:app/kibana ``` **Output per result:** ```json { "tech_fingerprint": { "techs": [ {"name": "WordPress", "category": "cms"}, {"name": "jQuery", "category": "js_lib", "version": "3.6.0"}, {"name": "PHP", "category": "lang", "version": "7.4"} ], "cve_dorks": ["site:target.com inurl:wp-login.php", "..."] } } ``` --- ## SecretsAgent Scans `page_content` and snippet for 50+ credential and secret patterns. **Secret categories with severity:** | Severity | Types | |----------|-------| | CRITICAL | Private keys, AWS keys, bcrypt hashes, NTLM hashes, Stripe keys | | HIGH | DB connections, JWTs, GCP keys, Azure keys, GitHub PATs, passwords, SendGrid, Twilio, GitLab PAT, Docker PAT, NPM token | | MEDIUM | Generic API keys, tokens, Slack keys, webhooks, SSH credentials, `.env` variables, Mailgun, Heroku | | LOW | MD5 / SHA1 / SHA256 / SHA512 hashes, internal IPs | **Features:** - Dedup by normalized value — same secret found 10 times = 1 finding - `severity` field on every finding - Hash detection: bcrypt `$2y$`, MD5 (32 hex), SHA1 (40 hex), SHA256 (64 hex), SHA512 (128 hex), NTLM pairs **Output per result:** ```json { "secrets": [ { "type": "AWS_KEY", "detection": "REGEX", "value": "AKIA…0A2", "confidence": "HIGH", "severity": "CRITICAL", "context": "...aws_access_key_id = AKIA...", "source": "https://target.com/config.php", "desc": "AWS Access Key ID" } ] } ``` --- ## PiiDetectorAgent Detects personally identifiable information, separated from SecretsAgent by design — PII requires different handling than technical credentials. Patterns are organised by geographic area. **Detected types:** | Type | Coverage | |------|----------| | `EMAIL` | Standard email format — global | | `PHONE_US` | US/Canada — NANP format with optional +1 | | `PHONE_EU` | EU + UK + CH + NO — 22 country codes (+30 to +421) | | `PHONE_ME` | Middle East — EG, TR, AF, IR, LB, JO, SY, IQ, KW, SA, YE, OM, PS, AE, IL, BH, QA | | `PHONE_AS` | Asia-Pacific — MY, AU, ID, PH, NZ, SG, TH, JP, KR, VN, CN, HK, MO, KH, LA, BD, TW, IN, PK, LK, MM | | `IBAN` | Generic IBAN — covers EU, UK, and Middle East banking formats | | `TAX_ID_US` | SSN (`NNN-NN-NNNN`) and EIN (`NN-NNNNNNN`) | | `TAX_ID_EU` | EU VAT number with ISO country prefix (DE, FR, IT, ES, PL, and 18 more) | | `TAX_ID_ME` | Keyword-anchored: SA VAT (15 digits), AE TRN, EG, TR, IR | | `TAX_ID_AS` | IN PAN card, CN USCC (18 chars), JP My Number, KR TRN, SG UEN, AU ABN | | `NIN_EU` | EU national identity numbers — BSN, PESEL, personnummer, SVNR, NIR | | `NID_ME` | Emirates ID (784-format), SA national ID, keyword-anchored | | `NID_AS` | SG NRIC, KR RRN, IN Aadhaar (XXXX XXXX XXXX), keyword-anchored | | `CREDIT_CARD` | Visa, Mastercard, Discover, Amex — **Luhn-validated** | | `SSN_US` | US SSN with exclusion of invalid blocks (000, 666, 9xx) | | `DOB` | Date of birth — keyword-anchored, multilingual labels (EN/ES/DE/AR/ZH/KO) | | `PASSPORT` | Generic machine-readable passport format — global | | `PUBLIC_IP` | Non-RFC-1918, non-loopback IPv4 — global | Credit card numbers are validated with the Luhn algorithm — false positives from random numeric strings are eliminated. Values are censored to 4 visible characters per end. --- ## EmailHarvesterAgent Collects email addresses from snippet and page content, deduplicates globally across all results, and categorizes by prefix. | Category | Prefix patterns | |----------|----------------| | `admin` | admin, administrator, root, sysadmin, webmaster, hostmaster, postmaster | | `security` | security, abuse, vuln, pentest, csirt, cert, soc, noc, infosec | | `info` | info, contact, hello, support, help, service, sales, marketing | | `noreply` | noreply, no-reply, donotreply, mailer-daemon, bounce | | `personal` | everything else | Global dedup: same address found in 10 pages = counted once. Results sorted by category priority (admin first, noreply last). --- ## SubdomainHarvesterAgent Extracts subdomains from all text fields (URL, snippet, page_content, title). Deduplicates globally per base domain. **Base domain extraction:** takes the last two labels — `api.v2.target.com` → `target.com`. **Follow-up dork generation** — 3 dork variants per subdomain: ``` site:api.target.com site:api.target.com inurl:admin site:api.target.com inurl:.env OR inurl:.git ``` These are merged with TechFingerprintAgent's CVE dorks and passed to DorkCrawlerAgent as seeds for the next round. --- ## DBScanAgent Scans exposed database ports on all unique hosts extracted from dork results. Runs after the main analysis pipeline and produces a dedicated `DBScanReport` saved alongside the main output file. **Location:** `DorkEye/Tools/db_portscan.py` **Detection coverage:** | Service | Port(s) | Probe type | |---------|---------|-----------| | MySQL | 3306 | TCP banner | | PostgreSQL | 5432 | TCP banner | | MongoDB | 27017, 27018\*, 27019\* | OP_MSG isMaster handshake | | Redis | 6379 | `PING` → `+PONG` | | Elasticsearch | 9200, 9300 | HTTP GET `/` — checks `cluster_name`, `version` | | CouchDB | 5984 | HTTP GET `/` — checks `couchdb`, `Welcome` | | InfluxDB | 8086 | HTTP GET `/ping` (204 = alive) | | Neo4j | 7474 | HTTP GET `/` — checks `neo4j`, `bolt` | | Memcached | 11211 | `stats\r\n` → `STAT` | | MSSQL | 1433 | TCP banner | | Oracle | 1521 | TCP banner | | Cassandra | 9042 | TCP banner | | RethinkDB | 28015, 5000\* | TCP banner | | DB2 | 50000\* | TCP banner | | Riak | 8098 | HTTP GET `/` | \* non-default — included only when `--ports` is set explicitly. **Severity model:** | Outcome | Severity | Meaning | |---------|----------|---------| | Port open + no-auth confirmed | **CRITICAL** | Data directly accessible without credentials | | Port open + service banner confirmed | **HIGH** | Auth likely required but service is exposed | | Port open, service unconfirmed | **MEDIUM** | Port responding, service unclear from banner | | Port closed / filtered / timeout | INFO | Not reported in findings | **No-auth probe logic per service:** | Service | No-auth trigger | |---------|----------------| | Redis | `+PONG` received after `PING` | | Elasticsearch | HTTP 200 with `cluster_name` + `version` in body | | CouchDB | HTTP 200 with `couchdb` + `Welcome` in body | | InfluxDB | HTTP 204 on `/ping` | | Neo4j | HTTP 200 with `neo4j` + `bolt` in body | | MongoDB | `isMaster` / `isWritablePrimary` in OP_MSG reply | | Memcached | `STAT` lines returned on `stats` command | **Dork-to-port hints** — if a result's URL, title, or snippet matches a known DB keyword, those ports are promoted to the front of the scan queue for that host: | Keyword pattern | Hinted ports | |----------------|-------------| | `phpmyadmin`, `mysqladmin` | 3306 | | `pgadmin`, `postgresql` | 5432 | | `mongodb`, `robo3t` | 27017, 27018 | | `redis`, `redisinsight` | 6379 | | `elasticsearch`, `kibana` | 9200, 9300 | | `couchdb`, `fauxton` | 5984 | | `influx` | 8086 | | `neo4j` | 7474 | | `mssql`, `sqlserver` | 1433 | | `oracle`, `tns listener` | 1521 | | `cassandra` | 9042 | | `memcache` | 11211 | **CLI flags:** ```bash --dbscan # Enable DBScanAgent in the pipeline --dbscan-timeout 2.5 # TCP connect timeout in seconds (default: 2.5) --dbscan-threads 60 # Worker threads per host (default: 60) --dbscan-ports 3306 5432 6379 # Override default port list --dbscan-max-hosts 200 # Max hosts to scan (default: 200) --dbscan-stealth # Add 1.5–3.5s random delay between hosts ``` **Standalone usage:** ```bash # Scan all hosts in a results file (default ports) python db_portscan.py results.json # Custom timeout and thread count python db_portscan.py results.json --timeout 3 --threads 80 # Target specific ports only python db_portscan.py results.json --ports 3306 5432 27017 6379 # Stealth mode with host cap python db_portscan.py results.json --stealth --max-hosts 50 # Custom output path python db_portscan.py results.json --out Dump/custom_scan ``` **Output files:** ``` Dump/_dbscan_.json # Full structured report Dump/_dbscan_.txt # Human-readable summary, usable as reference list ``` **Output structure (JSON):** ```json { "generated_at": "2025-01-01 12:00:00", "stats": { "hosts_scanned": 12, "ports_scanned": 192, "open_ports": 7, "critical": 2, "high": 3, "medium": 2 }, "hosts": [ { "host": "target.com", "scanned": 16, "duration": 4.12, "critical": 1, "high": 1, "open_ports": [6379, 9200], "findings": [ { "host": "target.com", "port": 6379, "service": "Redis", "status": "open", "severity": "CRITICAL", "probe": "redis", "no_auth": true, "banner": "", "detail": "Unauthenticated PING/PONG — data directly accessible", "source_url": "https://target.com/redisinsight/", "timestamp": "2025-01-01 12:00:01" } ] } ] } ``` **Python integration:** ```python from Tools.db_portscan import DBPortScanAgent, save_dbscan_report agent = DBPortScanAgent( timeout = 2.5, threads = 60, stealth = False, max_hosts = 200, ) report = agent.run(results) # results: list[dict] from DorkEye pipeline report.print_summary() # terminal summary with CRITICAL highlights save_dbscan_report(report, out_path) # writes .json + .txt ``` --- ## ReportAgent Produces the final analysis report. Accepts `html`, `md`, `json`, `txt`. **HTML report sections:** - Metrics bar — CRITICAL / HIGH / MEDIUM / LOW / TOTAL / SECRETS / PII / EMAILS - Top Findings (CRITICAL & HIGH) - Secrets Found — with severity badge (CRITICAL/HIGH/MEDIUM/LOW), detection source (REGEX/LLM) - PII Detected - Emails Harvested - Subdomains Found - CVE / Follow-up Dorks - DB Port Scan Summary (when DBScanAgent has run) - All Results table **JSON report top-level keys:** ```json { "meta": { "generated_at": "...", "target": "...", "engine": "DorkEye + Agents" }, "metrics": { "total": N, "by_label": {...}, "secrets": N, "pii": N, "emails": N, "subdomains": N }, "analysis": {}, "secrets": [...], "pii": [...], "emails": [...], "subdomains": { "target.com": ["api.target.com", "..."] }, "cve_dorks": [...], "db_scan": { "stats": {...}, "hosts": [...] }, "results": [...] } ``` --- ## Standalone Usage `dorkeye_agents.py` can run directly on any existing DorkEye result file: ```bash # Basic analysis python dorkeye_agents.py Dump/results.json # With page fetch python dorkeye_agents.py Dump/results.json --analyze-fetch --analyze-fetch-max 50 # HTML report to specific path python dorkeye_agents.py Dump/results.json \ --analyze-fetch --analyze-fmt html --analyze-out report.html # With target label for the report title python dorkeye_agents.py Dump/results.json --target "example.com" --analyze-fetch # Skip LLM triage (regex only, even if LLM plugin available) python dorkeye_agents.py Dump/results.json --analyze-no-llm-triage # Full pipeline including DB port scan python dorkeye_agents.py Dump/results.json --analyze-fetch --dbscan --dbscan-stealth ```