// PROJECT
Recon Script v2.0
Iteration on the v1 recon script — adds mode selection (service / directory / subdomain / all), a rotating progress spinner, and a whois/nslookup baseline.
Problem
v1 shipped, and two pain points showed up immediately:
- No feedback loop. When
nmapordirbwas running, there was no way to tell whether the script was making progress, hung, or about to finish. - All or nothing. v1 ran the entire pipeline every time. If I only needed subdomain enumeration, I had to wait through the rest.
v2 set out to fix both.
Approach
I considered borrowing a flag-style interface from the underlying tools (-A for nmap-style options) but landed on a simpler interactive prompt — service / directory / subdomain / all — to keep the script approachable.
What's new in v2:
- Rotating progress spinner. A
progress()function watches a backgrounded PID and prints|/-\until the process exits. Every long-running scan is now wrapped with it, so the script never looks hung. - Mode selection — interactive prompt picks one of
serv,dir,sub, orall. Each mode is its own function, so adding more later is just anothercasearm. - Always-on baseline recon —
whoisandnslookuprun on every invocation regardless of mode, written tobasic_recon/. - Function-organized layout —
service_enum,directory_enum, andsubdomain_enumreplace v1's linear flow. ffufis in the rotation — was commented out in v1; v2 runs it against thedirbuster/directory-list-2.3-medium.txtwordlist.
The script
#!/bin/bash
<< comment
This handy recon tool combines a bunch of different methods
for finding subdomains, directories, and more. It helps you
get a clear picture of how a web application is set up,
making it easier to see the whole layout and spot any
potential issues.
Disclaimer:
This script is intended for educational purposes and authorized security testing only.
The author is not responsible for any misuse or damage caused by this tool.
Users are responsible for ensuring they have proper authorization before running
any security scans. Always verify the scope of your testing to ensure compliance
with relevant laws and policies.
By using this tool, you agree to use it responsibly and in accordance with all
applicable laws and regulations. The author disclaims all liability for any actions
taken based on the information provided by this tool.
comment
# Declare variables
domain=$1
mode=$2
YELLOW="\033[0;33m"
WHITE="\033[0;37m"
RESET="\033[0m"
LINE="\033[0;37m----------------------------------------------------------\033[0m"
basic_path=$domain/basic_recon
service_path=$domain/service_recon
directory_path=$domain/directory_recon
subdomain_path=$domain/subdomain_recon
screenshot_path=$subdomain_path/screenshots
# Function to display a rotating progress indicator
progress() {
local pid=$1
local delay=0.1
local spinstr='|/-\'
while ps -p $pid > /dev/null 2>&1; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
# TOOL BANNER
echo -e "${WHITE}
___ ___ ___ __ ___ ___ ___ ___ __ __ _ _
( _)( \( \( )( _)/ __) ( ,) ( _) / _)/ \( \( )
) _) ) ) )) ) ))( ) _)\__ \ ) \ ) _)( (_( () )) (
(___)(___/(___/(__)(___)(___/ (_)\_)(___) \__)\__/(_)\_)
${RESET}"
echo -e "${LINE}"
sleep 1
# Directory making
echo "Creating directories for recon : $domain"
sleep 1
## Make top-level recon directory
if [ ! -d "$domain" ]; then
mkdir $domain
fi
if [ ! -d "$basic_path" ]; then
mkdir $basic_path
fi
# Basic enumeration (whois and nslookup) — included in every mode
## whois scan
echo "Conducting basic scans ..."
echo "Executing \"whois $domain\""
whois $domain > $basic_path/whois.txt &
pid=$!
progress $pid
wait $pid
echo "[+] whois scan complete"
echo -e "${LINE}"
sleep 1
## nslookup scan
echo "Executing \"nslookup $domain\""
nslookup $domain > $basic_path/nslookup.txt &
pid=$!
progress $pid
wait $pid
echo "[+] nslookup scan complete"
echo -e "${LINE}"
sleep 1
# Service mode
service_enum() {
## Make directory for service enumeration
echo -e "Making service enumeration folder"
if [ ! -d "$service_path" ]; then
mkdir $service_path
fi
## nmap scan -> Feel free to add options to nmap (sake of testing script I will not)
echo "Executing \"nmap $domain\" :"
nmap $domain > $service_path/nmap.txt &
pid=$!
progress $pid
wait $pid
echo "[+] NMAP Scan completed!"
echo -e "${LINE}"
sleep 1
}
# Directory mode
directory_enum() {
## Make directory for directory enumeration
echo -e "Making directory enumeration folder"
if [ ! -d "$directory_path" ]; then
mkdir $directory_path
fi
## ffuf -> uses medium wordlist
ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt:FUZZ -u https://$domain/FUZZ > $directory_path/ffuf.txt &
pid=$!
progress $pid
wait $pid
echo "[+] FFUF Scan completed!"
echo -e "${LINE}"
sleep 1
## dirb -> recursive directory enumeration
dirb https://$domain > $directory_path/dirb.txt &
pid=$!
progress $pid
wait $pid
echo "[+] Dirb Scan completed!"
echo -e "${LINE}"
sleep 1
}
# Subdomain mode
subdomain_enum() {
## Make directory for subdomain enumeration
echo -e "Making subdomain enumeration folder"
if [ ! -d "$subdomain_path" ]; then
mkdir $subdomain_path
fi
if [ ! -d "$screenshot_path" ]; then
mkdir $screenshot_path
fi
## subfinder
echo -e "${WHITE} [+] Executing subfinder ... ${RESET}"
subfinder -d $domain > $subdomain_path/found_subdomain.txt &
pid=$!
progress $pid
wait $pid
echo "[+] Subfinder Scan completed!"
echo -e "${LINE}"
sleep 1
## assetfinder
echo -e "${WHITE} [+] Executing assetfinder ... ${RESET}"
assetfinder $domain | grep $domain >> $subdomain_path/found_subdomain.txt &
pid=$!
progress $pid
wait $pid
echo "[+] Assetfinder Scan completed!"
echo -e "${LINE}"
sleep 1
## Find alive subdomains (httprobe)
echo -e "${WHITE} [+] Finding alive subdomains (HTTPROBE) ... ${RESET}"
cat $subdomain_path/found_subdomain.txt | grep $domain | sort -u | httprobe -prefer-https | grep https | sed 's/https\?:\/\///' > $subdomain_path/alive_subdomains.txt &
pid=$!
progress $pid
wait $pid
echo "[+] HTTPROBE Scan completed!"
echo -e "${LINE}"
sleep 1
## Screenshot alive subdomains (gowitness)
echo -e "${WHITE} [+] Taking screenshots of alive subdomains (GOWITNESS) ... ${RESET}"
gowitness file -f $subdomain_path/found_subdomain.txt -P $screenshot_path/ --no-http &
pid=$!
progress $pid
wait $pid
echo "[+] Screenshots completed!"
echo -e "${LINE}"
sleep 1
}
# Prompt for mode only if it wasn't passed as a CLI arg ($2)
if [ -z "$mode" ]; then
echo "What mode would you like to use? (serv for service, dir for directory, sub for subdomain, all for everything)"
read -r mode
fi
# Main logic to handle user input
case "$mode" in
serv)
service_enum
;;
dir)
directory_enum
;;
sub)
subdomain_enum
;;
all)
service_enum
directory_enum
subdomain_enum
;;
*)
echo "Invalid option. Please use 'serv' for service, 'dir' for directory, 'sub' for subdomain, 'all' for everything"
;;
esacOutcome
The tool count didn't really change — the win was structural. Modes give the user control over the time they're willing to spend, and the spinner makes the script feel alive instead of frozen. Functions and case statements clicked for me through this iteration; future me will thank past me for the modular layout when v3 rolls around.
Some directions I'm sketching for v3:
- Flag-style mode selection (
edsrecon -dir,edsrecon -serv) instead of (or in addition to) the interactive prompt. - More tools in the chain — dnsenum, gobuster as a
dirbalternative, maybe waybackurls for historical recon.
Resources
- Vickie Li's blog
- Bug Bounty Bootcamp by Vickie Li — not sponsored, just genuinely top-tier
- TCM Security Academy
- GeeksForGeeks — Linux shell & shell scripting