Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,64 @@

All notable changes to this project will be documented in this file.

## [1.1.0] - 2026-10-06

### Added
- **AI / LLM security reference** (`docs/ai-llm-security.md`) — prompt injection
(direct + indirect), system-prompt extraction, insecure output handling,
tool/function-call abuse, LLM data exfiltration, and malicious model-file RCE,
mapped to the OWASP LLM Top 10. Closes the biggest 2026 coverage gap.
- **Vulnerability-class deep-dives** in `bugbounty/QUICK-REFERENCE.md`: account
takeover via password reset, broken access control/IDOR depth, mass assignment,
race conditions, JWT/OAuth flaws, GraphQL abuse, prototype pollution, web cache
poisoning/deception, CORS misconfiguration, subdomain takeover, CSV injection,
path traversal with encoding bypass (CWE-22), NoSQL/Elasticsearch Painless
script injection (CWE-943/94), and cloud secrets/identity in JS bundles
(CWE-200/798, incl. AWS Cognito IdentityPoolId abuse).
- **`scripts/duplicate_check.py`** — pre-submission self-duplicate check
(fuzzy-matches a new finding against your `programs/*.md` "Submitted Reports"
tables) plus a structured Hacktivity search template. Stdlib only.
- **`auto-scanner/kev-correlate.sh`** — correlates the live CISA KEV catalog
against a target's detected stack (from `httpx -td`), with optional webhook
alerting and documented EPSS/NVD/OSV extension points.
- **Recon depth** in `bugbounty-hunter.sh`: crt.sh + certspotter (two Certificate Transparency sources) for subdomains,
enriched `httpx` output (`-td -title -server -cname -asn -json`), JS
endpoint/secret analysis (`jsluice`/`secretfinder`, source-map candidates),
API-spec discovery (swagger/openapi/graphql), and optional `paramspider`/`arjun`
param mining — all guarded, skipped gracefully when a tool is absent.
- **`--passive-only` flag** (and `BB_PASSIVE_ONLY=1`) that skips every stage that
touches the target directly (httpx/katana/param-mining).
- CVE watchlist now has a **Source column** (NVD link per row) and adds
high-volume perimeter/DevOps families: GitLab ATO (CVE-2023-7028), CitrixBleed
(CVE-2023-4966), Ivanti (CVE-2023-46805 + CVE-2024-21887), FortiOS
(CVE-2024-21762), Jenkins (CVE-2024-23897).

### Changed
- **`report-template.md`**: per-metric CVSS justification, a narrative "Attack
Scenario" section, explicit "Privileges required" and "Affected users/assets"
fields, a PoC video/GIF slot, and expanded pre-submission checklist.
- **`scope_filter_file`** (`lib/common.sh`) now logs discarded candidates to
`*.discarded.txt` and collects unlisted-but-seen hosts in
`candidates-pending-scope.txt` for manual scope review instead of dropping them
silently.
- `BB_VERSION` bumped to `1.1.0`.

### Fixed
- **Portable IP resolution** (`resolve_ip` in `lib/common.sh`, dig → host → getent
→ python3): `quickscan.sh`, `pentest-express.sh`, `autopentest.sh` and
`autopentest-pro.sh` no longer hard-fail with `dig: command not found` on boxes
without `dnsutils`. This also unblocks the CDN guard (it needs a resolved IP).
- `scope_filter_file` no longer errors with "No such file or directory" when an
upstream tool (e.g. katana) is absent and produces no input file.
- crt.sh integration validates the body is JSON and retries (crt.sh frequently
returns 502), parsing with `jq` when available; recon now also probes the
target host itself even when no subdomains are discovered.
- HTTP-probing stage detects when the installed `httpx` is the Python HTTP-client
CLI rather than ProjectDiscovery's `httpx`, and skips with a clear message
instead of failing silently.
- `pentest-express.sh` reflected-XSS check: `grep -c ... || echo 0` produced
`"0\n0"` and broke the numeric test; corrected.

## [1.0.7] - 2026-10-06

### Fixed
Expand Down
28 changes: 16 additions & 12 deletions auto-scanner/autopentest-pro.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,20 @@ reconocimiento_avanzado() {

# 1.1 Full DNS resolution
log_action "Full DNS resolution..."
log_tool "dig"
dig +noall +answer "$DOMAIN" > "$TEMP_DIR/dns_full.txt" 2>/dev/null
dig +short "$DOMAIN" > "$TEMP_DIR/dns_ip.txt" 2>/dev/null

# Additional records
dig ANY "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_any.txt" 2>/dev/null
dig MX "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_mx.txt" 2>/dev/null
dig NS "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_ns.txt" 2>/dev/null
dig TXT "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_txt.txt" 2>/dev/null

if check_tool dig; then
log_tool "dig"
dig +noall +answer "$DOMAIN" > "$TEMP_DIR/dns_full.txt" 2>/dev/null
dig +short "$DOMAIN" > "$TEMP_DIR/dns_ip.txt" 2>/dev/null
# Additional records
dig ANY "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_any.txt" 2>/dev/null
dig MX "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_mx.txt" 2>/dev/null
dig NS "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_ns.txt" 2>/dev/null
dig TXT "$DOMAIN" +noall +answer > "$TEMP_DIR/dns_txt.txt" 2>/dev/null
else
log_warning "dig not installed; recording resolved IP only"
resolve_ip "$DOMAIN" > "$TEMP_DIR/dns_ip.txt"
fi

log_info "DNS resolved: $(cat "$TEMP_DIR/dns_ip.txt" | head -1)"

# 1.2 Whois
Expand Down Expand Up @@ -179,7 +183,7 @@ reconocimiento_avanzado() {
escaneo_profundo() {
print_section "PHASE 2: DEEP PORT SCANNING"

TARGET_IP=$(dig +short "$DOMAIN" | head -1)
TARGET_IP=$(resolve_ip "$DOMAIN")

if [ -z "$TARGET_IP" ]; then
log_error "Could not resolve IP"
Expand Down Expand Up @@ -382,7 +386,7 @@ pruebas_avanzadas() {
enumeracion_servicios() {
print_section "PHASE 5: SERVICE ENUMERATION"

TARGET_IP=$(dig +short "$DOMAIN" | head -1)
TARGET_IP=$(resolve_ip "$DOMAIN")

# 5.1 SMB Enumeration
if check_tool enum4linux; then
Expand Down
2 changes: 1 addition & 1 deletion auto-scanner/autopentest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ escaneo_puertos() {

# 2.1 Determine IP
log_action "Resolving IP..."
TARGET_IP=$(dig +short "$DOMAIN" | head -1)
TARGET_IP=$(resolve_ip "$DOMAIN")

if [ -z "$TARGET_IP" ]; then
log_error "Could not resolve IP"
Expand Down
117 changes: 117 additions & 0 deletions auto-scanner/kev-correlate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash
# ============================================
# KEV / Threat-Intel Correlation
# ============================================
# Pulls the CISA Known-Exploited-Vulnerabilities catalog (public, no API key)
# and correlates it against a list of products/technologies you detected on a
# target (e.g. from `httpx -td`). Prints KEV entries whose vendor/product match,
# so you prioritize CVEs that are BOTH in your target's stack AND known-exploited.
#
# Optional extra sources (documented, enable as needed):
# - EPSS score per CVE: https://api.first.org/data/v1/epss?cve=CVE-XXXX-YYYY
# - NVD 2.0 detail: https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=...
# - OSV (OSS deps): https://api.osv.dev/v1/query
# - nuclei-templates: new templates often land days after a CVE is public
#
# Usage:
# ./kev-correlate.sh <tech-list-file> # one product/vendor per line
# ./kev-correlate.sh --tech "Grafana,Kibana,Next.js"
# httpx -td ... | ./kev-correlate.sh - # read tech tokens from stdin
# WEBHOOK_URL=https://hooks.slack.com/... ./kev-correlate.sh tech.txt # alert
# ============================================

set -uo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
KEV_URL="https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
CACHE_DIR="$(dirname "$0")/threat-intel"
KEV_CACHE="$CACHE_DIR/kev.json"
mkdir -p "$CACHE_DIR"

have() { command -v "$1" >/dev/null 2>&1; }

if ! have jq; then
echo -e "${RED}jq is required for this script.${NC}" >&2
exit 1
fi

# ── Collect technology tokens ────────────────────────────────────────
TECH=""
case "${1:-}" in
--tech)
TECH=$(echo "${2:-}" | tr ',' '\n')
;;
-)
# stdin: grab words that look like product names from httpx/-td output
TECH=$(tr ',[]' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -vE '^$')
;;
"")
echo -e "${YELLOW}Usage: $0 <tech-list-file> | --tech \"A,B\" | -${NC}"
exit 1
;;
*)
if [ -f "$1" ]; then
TECH=$(cat "$1")
else
echo -e "${RED}File not found: $1${NC}" >&2
exit 1
fi
;;
esac

TECH=$(echo "$TECH" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -vE '^$' | sort -u)
if [ -z "$TECH" ]; then
echo -e "${YELLOW}No technology tokens provided.${NC}"
exit 1
fi

# ── Fetch KEV catalog (cache 12h) ────────────────────────────────────
echo -e "${CYAN}Fetching CISA KEV catalog...${NC}"
if [ ! -f "$KEV_CACHE" ] || [ "$(find "$KEV_CACHE" -mmin +720 2>/dev/null)" ]; then
if ! curl -s "$KEV_URL" -o "$KEV_CACHE" 2>/dev/null || ! jq -e . "$KEV_CACHE" >/dev/null 2>&1; then
echo -e "${RED}Could not fetch/parse the KEV catalog.${NC}" >&2
exit 1
fi
fi
TOTAL=$(jq '.vulnerabilities | length' "$KEV_CACHE" 2>/dev/null || echo "?")
echo -e "${GREEN} KEV entries: $TOTAL${NC}"

# ── Correlate ────────────────────────────────────────────────────────
echo -e "${CYAN}Correlating against your target's stack...${NC}"
MATCHES=0
ALERT_LINES=""
while IFS= read -r token; do
[ -n "$token" ] || continue
# Case-insensitive substring match on vendorProject or product.
results=$(jq -r --arg t "$token" '
.vulnerabilities[]
| select((.vendorProject + " " + .product) | ascii_downcase | contains($t | ascii_downcase))
| "\(.cveID)\t\(.vendorProject) \(.product)\t\(.vulnerabilityName)"
' "$KEV_CACHE" 2>/dev/null)
if [ -n "$results" ]; then
while IFS= read -r line; do
[ -n "$line" ] || continue
cve=$(echo "$line" | cut -f1)
desc=$(echo "$line" | cut -f2-)
echo -e "${RED} [KEV] $cve${NC} ($token) — $desc"
ALERT_LINES="${ALERT_LINES}\n$cve ($token) — $desc"
MATCHES=$((MATCHES + 1))
done <<<"$results"
fi
done <<<"$TECH"

echo ""
if [ "$MATCHES" -eq 0 ]; then
echo -e "${GREEN}No KEV entries matched the provided stack.${NC}"
exit 0
fi
echo -e "${YELLOW}$MATCHES known-exploited CVE(s) matched your target's stack — prioritize these.${NC}"
echo -e "${YELLOW}Tip: add EPSS with curl -s 'https://api.first.org/data/v1/epss?cve=<CVE>'${NC}"

# ── Optional webhook alert ───────────────────────────────────────────
if [ -n "${WEBHOOK_URL:-}" ]; then
payload=$(printf '{"text":"KEV match (%s): %b"}' "$MATCHES" "$ALERT_LINES")
curl -s -X POST -H "Content-Type: application/json" -d "$payload" "$WEBHOOK_URL" >/dev/null 2>&1 \
&& echo -e "${GREEN}Alert posted to webhook.${NC}" \
|| echo -e "${YELLOW}Webhook post failed.${NC}"
fi
42 changes: 41 additions & 1 deletion auto-scanner/lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ umask 077

# Version
# shellcheck disable=SC2034
BB_VERSION="1.0.7"
BB_VERSION="1.1.0"

# ── Colors ──────────────────────────────────────────────────────────
RED='\033[0;31m'
Expand Down Expand Up @@ -58,13 +58,53 @@ scope_filter_file() {
local output_file="$2"
local programs_dir="${3:-$PROGRAMS_DIR}"
local candidate
# Evidence trail: everything dropped goes here, and unlisted-but-live
# candidates go to candidates-pending-scope.txt for manual review instead of
# vanishing silently.
local discard_log="${output_file%.*}.discarded.txt"
local candidates_file
candidates_file="$(dirname "$output_file")/candidates-pending-scope.txt"
: > "$output_file"
: > "$discard_log"
# Input may be absent when an upstream tool (e.g. katana) is not installed —
# produce an empty output instead of erroring.
[ -f "$input_file" ] || return 0
while IFS= read -r candidate; do
[ -n "$candidate" ] || continue
if python3 "$SCOPE_GUARD" --programs-dir "$programs_dir" "$candidate" >/dev/null 2>&1; then
printf '%s\n' "$candidate" >> "$output_file"
else
printf '%s\n' "$candidate" >> "$discard_log"
printf '%s\n' "$candidate" >> "$candidates_file"
fi
done < "$input_file"
if [ -s "$candidates_file" ]; then
sort -u "$candidates_file" -o "$candidates_file"
fi
}

# ── Portable IP resolution ──────────────────────────────────────────
# Not every box ships `dig` (dnsutils). Resolve the first A record using
# whatever is available: dig -> host -> getent -> python3. Prints the IP or
# nothing. Usage: ip=$(resolve_ip "$DOMAIN")
resolve_ip() {
local host="$1" ip=""
[ -n "$host" ] || return 0
if command -v dig >/dev/null 2>&1; then
ip=$(dig +short A "$host" 2>/dev/null | grep -E '^[0-9]+\.' | head -1)
fi
if [ -z "$ip" ] && command -v host >/dev/null 2>&1; then
ip=$(host -t A "$host" 2>/dev/null | awk '/has address/{print $NF; exit}')
fi
if [ -z "$ip" ] && command -v getent >/dev/null 2>&1; then
ip=$(getent ahostsv4 "$host" 2>/dev/null | awk '{print $1; exit}')
fi
if [ -z "$ip" ] && command -v python3 >/dev/null 2>&1; then
ip=$(python3 -c "import socket,sys
try: print(socket.gethostbyname(sys.argv[1]))
except Exception: pass" "$host" 2>/dev/null)
fi
printf '%s' "$ip"
}

# ── CDN / shared-edge safety guard ──────────────────────────────────
Expand Down
9 changes: 6 additions & 3 deletions auto-scanner/pentest-express.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ reconocimiento_rapido() {

# DNS
log_action "Resolving DNS..."
TARGET_IP=$(dig +short "$DOMAIN" | head -1)
dig +short "$DOMAIN" > "$TEMP_DIR/dns.txt"
TARGET_IP=$(resolve_ip "$DOMAIN")
printf '%s\n' "$TARGET_IP" > "$TEMP_DIR/dns.txt"
log_info "IP: $TARGET_IP"
# Do not port-scan a CDN/shared edge IP — it is a third party and out of scope.
if resolves_behind_cdn "$DOMAIN" "$TARGET_IP"; then TARGET_IP=""; fi
Expand Down Expand Up @@ -176,7 +176,10 @@ pruebas_basicas() {
log_action "Testing basic XSS..."
XSS_PAYLOAD="<script>alert(1)</script>"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${TARGET_URL}/?q=${XSS_PAYLOAD}" 2>/dev/null)
CONTENT=$(curl -s "${TARGET_URL}/?q=${XSS_PAYLOAD}" 2>/dev/null | grep -c "$XSS_PAYLOAD" || echo "0")
# grep -c already prints 0 on no match; a trailing '|| echo 0' would append a
# SECOND line, producing "0\n0" and breaking the numeric test below.
CONTENT=$(curl -s "${TARGET_URL}/?q=${XSS_PAYLOAD}" 2>/dev/null | grep -c "$XSS_PAYLOAD")
[ -n "$CONTENT" ] || CONTENT=0
if [ "$CONTENT" -gt 0 ]; then
log_warning "Possible reflected XSS"
fi
Expand Down
2 changes: 1 addition & 1 deletion auto-scanner/quickscan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fi
TARGET_URL="$1"
require_scope "$TARGET_URL" || exit 1
DOMAIN=$(normalize_target "$TARGET_URL") || exit 1
TARGET_IP=$(dig +short "$DOMAIN" | head -1)
TARGET_IP=$(resolve_ip "$DOMAIN")
# Do not port-scan a CDN/shared edge IP — it is a third party and out of scope.
if resolves_behind_cdn "$DOMAIN" "$TARGET_IP"; then TARGET_IP=""; fi

Expand Down
Loading
Loading