wip
1#!/bin/bash
2
3# Configuration
4API_HOST="${API_HOST:-http://localhost:8080}"
5TIMEOUT=5
6PARALLEL_JOBS=20
7OUTPUT_DIR="./pds_scan_results"
8TIMESTAMP=$(date +%Y%m%d_%H%M%S)
9RESULTS_FILE="${OUTPUT_DIR}/scan_${TIMESTAMP}.txt"
10FOUND_FILE="${OUTPUT_DIR}/found_${TIMESTAMP}.txt"
11
12# Paths to check
13PATHS=(
14 "/info.php"
15 "/phpinfo.php"
16 "/test.php"
17 "/admin"
18 "/admin.php"
19 "/wp-admin"
20 "/robots.txt"
21 "/.env"
22 "/.git/config"
23 "/config.php"
24 "/backup"
25 "/db.sql"
26 "/.DS_Store"
27 "/server-status"
28 "/.well-known/security.txt"
29)
30
31# Colors
32RED='\033[0;31m'
33GREEN='\033[0;32m'
34YELLOW='\033[1;33m'
35BLUE='\033[0;34m'
36NC='\033[0m'
37
38# Check dependencies
39if ! command -v jq &> /dev/null; then
40 echo -e "${RED}Error: jq is required${NC}"
41 echo "Install: sudo apt-get install jq"
42 exit 1
43fi
44
45if ! command -v parallel &> /dev/null; then
46 echo -e "${RED}Error: GNU parallel is required${NC}"
47 echo "Install: sudo apt-get install parallel (or brew install parallel)"
48 exit 1
49fi
50
51mkdir -p "$OUTPUT_DIR"
52
53echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
54echo -e "${BLUE}║ PDS Security Scanner (Parallel) ║${NC}"
55echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
56echo ""
57echo "API Host: $API_HOST"
58echo "Timeout: ${TIMEOUT}s per request"
59echo "Parallel jobs: ${PARALLEL_JOBS}"
60echo "Paths to check: ${#PATHS[@]}"
61echo ""
62
63# Scan function - will be called by GNU parallel
64scan_endpoint() {
65 local endpoint="$1"
66 local timeout="$2"
67 shift 2
68 local paths=("$@")
69
70 for path in "${paths[@]}"; do
71 url="${endpoint}${path}"
72
73 response=$(curl -s -o /dev/null -w "%{http_code}" \
74 --max-time "$timeout" \
75 --connect-timeout "$timeout" \
76 --retry 0 \
77 -A "Mozilla/5.0 (Security Scanner)" \
78 "$url" 2>/dev/null)
79
80 if [ -n "$response" ] && [ "$response" != "404" ] && [ "$response" != "000" ]; then
81 if [ "$response" = "200" ] || [ "$response" = "301" ] || [ "$response" = "302" ]; then
82 echo "FOUND|$endpoint|$path|$response"
83 elif [ "$response" != "403" ] && [ "$response" != "401" ]; then
84 echo "MAYBE|$endpoint|$path|$response"
85 fi
86 fi
87 done
88}
89
90export -f scan_endpoint
91
92# Fetch active PDS endpoints
93echo -e "${YELLOW}Fetching active PDS endpoints...${NC}"
94ENDPOINTS=$(curl -s "${API_HOST}/api/v1/pds?status=online&limit=10000" | \
95 jq -r '.[].endpoint' 2>/dev/null)
96
97if [ -z "$ENDPOINTS" ]; then
98 echo -e "${RED}Error: Could not fetch endpoints from API${NC}"
99 echo "Check that the API is running at: $API_HOST"
100 exit 1
101fi
102
103ENDPOINT_COUNT=$(echo "$ENDPOINTS" | wc -l | tr -d ' ')
104echo -e "${GREEN}✓ Found ${ENDPOINT_COUNT} active PDS endpoints${NC}"
105echo ""
106
107# Write header to results file
108{
109 echo "PDS Security Scan Results"
110 echo "========================="
111 echo "Scan started: $(date)"
112 echo "Endpoints scanned: ${ENDPOINT_COUNT}"
113 echo "Paths checked: ${#PATHS[@]}"
114 echo "Parallel jobs: ${PARALLEL_JOBS}"
115 echo ""
116 echo "Results:"
117 echo "--------"
118} > "$RESULTS_FILE"
119
120# Run parallel scan
121echo -e "${YELLOW}Starting parallel scan...${NC}"
122echo -e "${BLUE}(This may take a few minutes depending on endpoint count)${NC}"
123echo ""
124
125echo "$ENDPOINTS" | \
126 parallel \
127 -j "$PARALLEL_JOBS" \
128 --bar \
129 --joblog "${OUTPUT_DIR}/joblog_${TIMESTAMP}.txt" \
130 scan_endpoint {} "$TIMEOUT" "${PATHS[@]}" \
131 >> "$RESULTS_FILE"
132
133echo ""
134echo -e "${YELLOW}Processing results...${NC}"
135
136# Count results
137FOUND_COUNT=$(grep -c "^FOUND|" "$RESULTS_FILE" 2>/dev/null || echo 0)
138MAYBE_COUNT=$(grep -c "^MAYBE|" "$RESULTS_FILE" 2>/dev/null || echo 0)
139
140# Extract found URLs to separate file
141{
142 echo "Found URLs (HTTP 200/301/302)"
143 echo "=============================="
144 echo "Scan: $(date)"
145 echo ""
146} > "$FOUND_FILE"
147
148grep "^FOUND|" "$RESULTS_FILE" 2>/dev/null | while IFS='|' read -r status endpoint path code; do
149 echo "$endpoint$path [$code]"
150done >> "$FOUND_FILE"
151
152# Create summary at end of results file
153{
154 echo ""
155 echo "Summary"
156 echo "======="
157 echo "Scan completed: $(date)"
158 echo "Total endpoints scanned: ${ENDPOINT_COUNT}"
159 echo "Total paths checked: $((ENDPOINT_COUNT * ${#PATHS[@]}))"
160 echo "Found (200/301/302): ${FOUND_COUNT}"
161 echo "Maybe (other codes): ${MAYBE_COUNT}"
162} >> "$RESULTS_FILE"
163
164# Display summary
165echo ""
166echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
167echo -e "${BLUE}║ Scan Complete! ║${NC}"
168echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
169echo ""
170echo -e "Endpoints scanned: ${GREEN}${ENDPOINT_COUNT}${NC}"
171echo -e "Paths checked per site: ${BLUE}${#PATHS[@]}${NC}"
172echo -e "Total requests made: ${BLUE}$((ENDPOINT_COUNT * ${#PATHS[@]}))${NC}"
173echo ""
174echo -e "Results:"
175echo -e " ${GREEN}✓ Found (200/301/302):${NC} ${FOUND_COUNT}"
176echo -e " ${YELLOW}? Maybe (other):${NC} ${MAYBE_COUNT}"
177echo ""
178echo "Files created:"
179echo " Full results: $RESULTS_FILE"
180echo " Found URLs: $FOUND_FILE"
181echo " Job log: ${OUTPUT_DIR}/joblog_${TIMESTAMP}.txt"
182
183# Show sample of found URLs if any
184if [ "$FOUND_COUNT" -gt 0 ]; then
185 echo ""
186 echo -e "${RED}⚠ SECURITY ALERT: Found exposed paths!${NC}"
187 echo ""
188 echo "Sample findings (first 10):"
189 grep "^FOUND|" "$RESULTS_FILE" 2>/dev/null | head -10 | while IFS='|' read -r status endpoint path code; do
190 echo -e " ${RED}✗${NC} $endpoint${RED}$path${NC} [$code]"
191 done
192
193 if [ "$FOUND_COUNT" -gt 10 ]; then
194 echo ""
195 echo " ... and $((FOUND_COUNT - 10)) more (see $FOUND_FILE)"
196 fi
197fi
198
199echo ""