Bugbounty Subdomain enum script

Github-subdomains requires multiple tokens in the current directory to avoid rate limiting, edit Seclists subdomains wordlists if needed.

#!/bin/bash

# Function to execute subfinder command for each domain in domains.txt
subfinder_enum() {
    local total_lines=$(wc -l < domains.txt)
    local current_line=0

    echo -e "\n\e[1;33mStarting subfinder enumeration...\e[0m"
    while IFS= read -r domain; do
        subfinder -d "$domain" >> subs.txt >/dev/null 2>&1
        ((current_line++))
        print_progress "$current_line" "$total_lines"
    done < domains.txt
    echo -e "\n\e[1;32mSubfinder enumeration complete.\e[0m"
}

# Function to execute crt.sh command for each domain in domains.txt
crtsh_enum() {
    local total_lines=$(wc -l < domains.txt)
    local current_line=0

    echo -e "\n\e[1;33mStarting crt.sh enumeration...\e[0m"
    while IFS= read -r domain; do
        curl -s "https://crt.sh/?q=$domain&output=json" | jq -r '.[].name_value' | grep -Po '(\w+\.\w+\.\w+)$' >> subs.txt >/dev/null 2>&1
        ((current_line++))
        print_progress "$current_line" "$total_lines"
    done < domains.txt
    echo -e "\n\e[1;32mcrt.sh enumeration complete.\e[0m"
}

# Function to execute github-subdomains command for each domain in domains.txt
github_enum() {
    local total_lines=$(wc -l < domains.txt)
    local current_line=0

    echo -e "\n\e[1;33mStarting GitHub subdomains enumeration...\e[0m"
    while IFS= read -r domain; do
        github-subdomains -d "$domain" >> subs.txt >/dev/null 2>&1
        ((current_line++))
        print_progress "$current_line" "$total_lines"
    done < domains.txt
    echo -e "\n\e[1;32mGitHub subdomains enumeration complete.\e[0m"
}

# Function to execute ffuf command for each domain in domains.txt
ffuf_enum() {
    local total_lines=$(wc -l < domains.txt)
    local current_line=0

    echo -e "\n\e[1;33mStarting ffuf enumeration...\e[0m"
    while IFS= read -r domain; do
        ffuf -w /usr/share/seclists/Discovery/DNS/bug-bounty-program-subdomains-trickest-inventory.txt -u "https://FUZZ.$domain" -mc 200 -o output.txt -of csv >/dev/null 2>&1
        ((current_line++))
        print_progress "$current_line" "$total_lines"
    done < domains.txt
    echo -e "\n\e[1;32mffuf enumeration complete.\e[0m"
}

# Function to print progress bar
print_progress() {
    local current_line=$1
    local total_lines=$2
    local progress=$((current_line * 100 / total_lines))
    local bar_length=$((progress / 2))
    local color_code=$(get_color_code "$progress")

    printf "\rProgress: [%-${bar_length}s] %d%%" "$(printf '#%.0s' $(seq 1 "$bar_length"))" "$progress" | sed "s/#/${color_code}#/"
}

# Function to determine color code based on progress
get_color_code() {
    local progress=$1
    if ((progress < 25)); then
        echo -e "\033[31m"  # Red
    elif ((progress < 50)); then
        echo -e "\033[33m"  # Yellow
    elif ((progress < 75)); then
        echo -e "\033[32m"  # Green
    else
        echo -e "\033[34m"  # Blue
    fi
}

# Main function to orchestrate the enumeration process
main() {
    # Ensure subs.txt is empty before starting
    > subs.txt
    
    # Execute each enumeration method
    subfinder_enum
    crtsh_enum
    github_enum
    ffuf_enum

    # Combine all subdomains into a single file and remove duplicates
    cat subs.txt | sort -u > subs-final.txt

    # Cleanup temporary files
    rm -f subs.txt output.txt
}

# Parse command line arguments
while getopts ":s" opt; do
    case $opt in
        s)
            # Silent mode, suppress progress output
            main
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
    esac
done
shift $((OPTIND -1))

# If no option is provided, execute with progress output
if [ $# -eq 0 ]; then
    main
fi

Last updated