Skip to content

Commit 3090ab0

Browse files
file renamed and added debug code to check IP extraction
1 parent f986560 commit 3090ab0

1 file changed

Lines changed: 247 additions & 0 deletions

File tree

bug_bounty/run.sh

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
#!/usr/bin/env bash
2+
# ======================================================
3+
# Automated Scan Script for bug bounty targets
4+
# ======================================================
5+
# Author: Naveen Jagadeesan(thevillagehacker)
6+
# Description: Runs reconnaissance against the targets
7+
# ======================================================
8+
9+
# Color codes for output
10+
RED='\033[0;31m'
11+
GREEN='\033[0;32m'
12+
YELLOW='\033[1;33m'
13+
NC='\033[0m' # No Color
14+
15+
# Logging functions
16+
log() {
17+
echo -e "${GREEN}[+]${NC} $1"
18+
}
19+
20+
error() {
21+
echo -e "${RED}[-]${NC} $1"
22+
exit 1
23+
}
24+
25+
# Check if required tool is installed
26+
check_tool() {
27+
if ! command -v "$1" &> /dev/null; then
28+
error "$1 is not installed. Please install it first."
29+
fi
30+
}
31+
32+
# Function to setup target directory
33+
setup_target() {
34+
local target_id="$1"
35+
local scope_path="$ppath/scope/$target_id"
36+
37+
# Create scope and target directories
38+
mkdir -p "$scope_path"
39+
40+
# Ask for roots content (send prompts to stderr so they don't get captured by command substitution)
41+
echo "" >&2
42+
echo -e "${YELLOW}[*]${NC} Enter the target roots (domains/IPs) for $target_id" >&2
43+
echo -e "${YELLOW}[*]${NC} You can enter multiple roots, one per line." >&2
44+
echo -e "${YELLOW}[*]${NC} Press Ctrl+D (or Ctrl+Z on Windows) when done:" >&2
45+
echo "---" >&2
46+
47+
# Read user input and write to roots.txt
48+
cat > "$scope_path/roots.txt"
49+
50+
echo "---" >&2
51+
echo "" >&2
52+
echo -e "${GREEN}[+]${NC} Target directory created at: $scope_path" >&2
53+
echo -e "${GREEN}[+]${NC} Roots file saved at: $scope_path/roots.txt" >&2
54+
echo "" >&2
55+
56+
# Only echo the target_id to stdout so it gets captured by command substitution
57+
echo "$target_id"
58+
}
59+
60+
# Set vars
61+
ppath="$(pwd)"
62+
lists_path="$ppath/lists"
63+
64+
# Usage and disclaimer
65+
if [ "$1" == "-h" ]; then
66+
echo "Usage: ./scan.sh [id]"
67+
echo ""
68+
echo "This script performs a scan for a given target ID."
69+
echo ""
70+
echo "Options:"
71+
echo " [id] - Optional. If provided, uses existing scope/[id]/roots.txt"
72+
echo " -h - Show this help message"
73+
echo ""
74+
echo "If no ID is provided, the script will prompt you to:"
75+
echo " 1. Enter a target name (will create scope/[target_name]/ directory)"
76+
echo " 2. Enter roots (domains/IPs to scan, one per line)"
77+
echo ""
78+
echo "Directory structure:"
79+
echo "├── scan.sh"
80+
echo "├── scans"
81+
echo "└── scope"
82+
echo " └── [target_name]"
83+
echo " └── roots.txt"
84+
echo ""
85+
echo "Examples:"
86+
echo " ./scan.sh example # Use existing scope/example/roots.txt"
87+
echo " ./scan.sh # Interactive mode - create new target"
88+
exit 0
89+
fi
90+
91+
# Prompt for target if not provided as argument
92+
if [ -z "$1" ]; then
93+
echo -e "${YELLOW}[-]${NC} No target ID provided"
94+
read -p "Enter target name: " id
95+
if [ -z "$id" ]; then
96+
error "Target name cannot be empty"
97+
fi
98+
id=$(setup_target "$id")
99+
else
100+
id="$1"
101+
fi
102+
103+
scope_path="$ppath/scope/$id"
104+
105+
timestamp="$(date +%s)"
106+
scan_path="$ppath/scans/$id-$timestamp"
107+
108+
# Check required tools
109+
log "Checking required tools..."
110+
check_tool "haktrails"
111+
check_tool "subfinder"
112+
check_tool "alterx"
113+
check_tool "puredns"
114+
check_tool "dnsx"
115+
check_tool "nmap"
116+
check_tool "httpx"
117+
check_tool "gospider"
118+
check_tool "jq"
119+
check_tool "wget"
120+
121+
# Create necessary directories
122+
log "Creating necessary directories..."
123+
mkdir -p "$lists_path"
124+
mkdir -p "$scan_path"
125+
126+
log "Scan path: $scan_path"
127+
128+
### PERFORM SCAN ###
129+
log "Starting scan against roots:"
130+
cat "$scope_path/roots.txt" > "$scan_path/roots.txt"
131+
sleep 2
132+
133+
134+
# DNS Enumeration - Find Subdomains
135+
log "DNS Enumeration: Running haktrails..."
136+
cat "$scan_path/roots.txt" | haktrails subdomains | anew "$scan_path/subs.txt" | wc -l
137+
138+
log "DNS Enumeration: Running subfinder..."
139+
subfinder -d "$(cat "$scan_path/roots.txt")" -all -silent | anew "$scan_path/subs.txt" | wc -l
140+
141+
# alterx subdomain wordlist generation
142+
log "Generating subdomain permutations with alterx..."
143+
cat "$scan_path/roots.txt" | alterx -silent | anew "$scan_path/subs.txt" | wc -l
144+
145+
# Download resolver lists (only if they don't exist or are older than 7 days)
146+
download_if_needed() {
147+
local url="$1"
148+
local output="$2"
149+
if [ ! -f "$output" ] || [ "$(find "$output" -mtime +7 2>/dev/null)" ]; then
150+
log "Downloading $(basename "$output")..."
151+
wget -q --show-progress "$url" -O "$output"
152+
else
153+
log "Using cached $(basename "$output")..."
154+
fi
155+
}
156+
157+
download_if_needed "https://raw.githubusercontent.com/trickest/resolvers/refs/heads/main/resolvers.txt" "$lists_path/resolvers.txt"
158+
download_if_needed "https://raw.githubusercontent.com/trickest/resolvers/refs/heads/main/resolvers-trusted.txt" "$lists_path/resolvers-trusted.txt"
159+
download_if_needed "https://raw.githubusercontent.com/trickest/resolvers/refs/heads/main/resolvers-extended.txt" "$lists_path/resolvers-extended.txt"
160+
download_if_needed "https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Discovery/DNS/combined_subdomains.txt" "$lists_path/combined_subdomains.txt"
161+
162+
# Sort and unique resolvers
163+
log "Sorting resolvers..."
164+
cat "$lists_path"/resolvers*.txt | anew > "$lists_path/sorted_resolvers.txt"
165+
166+
# Copy sorted resolvers to puredns config
167+
log "Copying resolvers to puredns config folder..."
168+
mkdir -p "$HOME/.config/puredns"
169+
cp "$lists_path/sorted_resolvers.txt" "$HOME/.config/puredns/resolvers.txt"
170+
171+
# DNS Resolution - Resolve Discovered Subdomains
172+
log "DNS Resolution: Resolving subdomains with puredns..."
173+
puredns resolve "$scan_path/subs.txt" -r "$lists_path/resolvers.txt" --resolvers-trusted "$lists_path/resolvers-trusted.txt" -w "$scan_path/resolved.txt" | wc -l
174+
175+
log "DNS Resolution: Extracting IP addresses with dnsx..."
176+
dnsx -l "$scan_path/resolved.txt" -json -o "$scan_path/dns.json"
177+
log "Extracting IP addresses from $scan_path/dns.json"
178+
179+
# DEBUG: Check if dns.json exists and has content
180+
echo "[DEBUG] Checking dns.json file..." >&2
181+
if [ -f "$scan_path/dns.json" ]; then
182+
file_size=$(wc -c < "$scan_path/dns.json")
183+
echo "[DEBUG] dns.json exists. File size: $file_size bytes" >&2
184+
echo "[DEBUG] First 500 chars of dns.json:" >&2
185+
head -c 500 "$scan_path/dns.json" >&2
186+
echo "" >&2
187+
else
188+
error "dns.json not found at $scan_path/dns.json"
189+
fi
190+
191+
# DEBUG: Extract with grep and show count
192+
echo "[DEBUG] Running grep to extract IPs..." >&2
193+
grep_count=$(grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$scan_path/dns.json" | wc -l)
194+
echo "[DEBUG] Grep found $grep_count IP matches" >&2
195+
196+
# DEBUG: Show first 10 IPs found by grep
197+
echo "[DEBUG] First 10 IPs found by grep:" >&2
198+
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$scan_path/dns.json" | head -10 >&2
199+
200+
# Extract, sort, validate, and write to ips.txt
201+
echo "[DEBUG] Sorting and validating IPs..." >&2
202+
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$scan_path/dns.json" | sort -u > "$scan_path/ips.tmp"
203+
tmp_count=$(wc -l < "$scan_path/ips.tmp")
204+
echo "[DEBUG] After sort -u: $tmp_count unique IPs" >&2
205+
206+
# Validate octets
207+
awk -F'.' '($1<=255 && $2<=255 && $3<=255 && $4<=255){print}' "$scan_path/ips.tmp" > "$scan_path/ips.txt"
208+
final_count=$(wc -l < "$scan_path/ips.txt")
209+
echo "[DEBUG] After validation: $final_count valid IPs written to ips.txt" >&2
210+
echo "[DEBUG] First 10 IPs in ips.txt:" >&2
211+
head -10 "$scan_path/ips.txt" >&2
212+
213+
rm -f "$scan_path/ips.tmp"
214+
log "Wrote $final_count IPs to $scan_path/ips.txt"
215+
216+
# Port Scanning & HTTP Server Discovery
217+
log "Port Scanning: Running nmap on discovered IPs..."
218+
nmap -iL "$scan_path/ips.txt" --top-ports 3000 -oN "$scan_path/nmap.txt" -v
219+
220+
log "HTTP Discovery: Finding live HTTP services..."
221+
cat "$scan_path/nmap.txt" | dnsx -l "$scan_path/dns.json" --hosts | httpx -json -o "$scan_path/http.json"
222+
223+
cat "$scan_path/http.json" | jq -r '.url' | sed -e 's/:80$//' -e 's/:443$//' | sort -u > "$scan_path/http.txt"
224+
225+
log "Found $(wc -l < "$scan_path/http.txt") live HTTP services"
226+
227+
# Crawling
228+
log "Web Crawling: Running gospider..."
229+
gospider -S "$scan_path/http.txt" --json | grep '{}' | jq -r '.output?' | tee "$scan_path/crawl.txt"
230+
231+
# more crawling with katana
232+
#katana -u "$scan_path/resolved.txt" -xhr -jsl -d 6
233+
234+
# Calculate time diff
235+
end_time=$(date +%s)
236+
seconds=$(expr $end_time - $timestamp)
237+
238+
if [ "$seconds" -gt 59 ]; then
239+
minutes=$(expr $seconds / 60)
240+
time="$minutes minutes"
241+
else
242+
time="$seconds seconds"
243+
fi
244+
245+
log "Scan completed for '$id' in $time"
246+
log "Results saved to: $scan_path"
247+
#log "Scan $id took $time" | notify

0 commit comments

Comments
 (0)