#!/bin/bash # --- Sudo Check --- if [[ $EUID -ne 0 ]]; then echo -e "\e[1;31mERROR: This script must be run as root (sudo).\e[0m" exit 1 fi # --- Dependency Check --- dependencies=("nmap" "python3" "awk" "pandoc" "texlive-xetex") for dependency in "${dependencies[@]}"; do if ! command -v "$dependency" &> /dev/null; then echo -e "\e[1;31mERROR: $dependency is not installed.\e[0m" read -p "Do you want to install it now? [y/n] " install_choice if [[ "$install_choice" =~ ^[Yy]$ ]]; then # Install the dependency (replace with appropriate command for your system) sudo apt-get install "$dependency" # Example for Debian/Ubuntu echo -e "\e[1;32m Finished installing dependencies, Starting Script \e[0m" sleep 2.5 else echo "Exiting script. Please install the missing dependencies and try again." exit 1 fi fi done # ... (Rest of your script) ... if [ $# -eq 0 ]; then echo "Usage: ./external_pentest.sh " echo "" exit 1; fi echo "" echo "" echo -e "\e[1;96m External Pentesting Start Script by Daniel Brown \e[0m" echo "" echo "" # User Input of Information # echo -n " Input the number of top TCP ports you would like to scan (recommended 1024) greater than 0 : " read topports if [ $topports -eq 0 ]; then echo -e "\e[34m Number must be greater than zero! \e[0m"; exit 1 fi #Folder where raw scan files are stored mkdir raw_files #Variable storage f1='raw_files' total_ips=$(wc -l < "$1") ## Pingable IP Check ## echo "" echo -e "\e[34m Checking for Ping on Hosts \e[0m" echo "" nmap -sP -iL $1 -PE -oG - | awk '/Up/{print $2}' > $f1/pingable_hosts.txt echo "" echo -e "\e[34m Finished Checking for Ping \e[0m" echo "" sleep 5 # Performs NMAP TCP Scans# echo -e "\e[34m Starting NMAP TCP scans this can take a very long time \e[0m" echo ""; nmap -sS -Pn -n -iL $1 --top-ports=$topports -T4 -oA $f1/nmap-sT-Pn-n-top-$topports &>/dev/null echo "" echo -e "\e[34m Finished NMAP TCP scans \e[0m" echo "" sleep 2.5 ##python parser ## python3 << EOF import re,os import tabulate from sys import argv def help(): print("\n " + "-" * 52) print(" Nmap Parser v2.0, Daniel Brown (dbrow43@gmail.com) ") print(" " + "-" * 52) print("\n Usage: %s " % argv[0]) print() exit() def start(argv): if len(argv) < 1: help() if not os.path.exists('open-ports'): os.makedirs('open-ports') target_file = open(argv[-1]) targett_file = target_file.read().split('\n') for line in targett_file: ip_address = line[line.find(":")+2:line.find("(")-1] pattern = '([0-9]+)/open/(tcp|udp)/' find_pattern = re.findall(pattern, line) tcpwrapped_pattern = '([0-9]+)/open/tcp//tcpwrapped' find_tcpwrapped = re.findall(tcpwrapped_pattern, line) if find_pattern: for i in find_pattern: if i in find_tcpwrapped: continue tcp_file = open('open-ports/%s.txt' % i[0],'a') tcp_file.write("%s\n" % ip_address) tcp_file.close() target_file.close() print("Done. Check the \"open-ports\" folder for results.") if __name__ == "__main__": try: # Construct the filename and pass it as an argument filename = "$f1/nmap-sT-Pn-n-top-$topports.gnmap" start([filename]) except KeyboardInterrupt: print("\nExiting. Closed by user (ctrl-c).") except Exception as err: print(err) EOF # Get the current date for archiving # current_date=$(date +%Y-%m-%d) # Get the date here results_dir="results_$current_date" # Define the results directory name echo -e "\e[33mArchiving results...\e[0m" # Move the open-ports and raw_files directories into the results directory mkdir $results_dir mv open-ports "$results_dir" mv raw_files "$results_dir" echo -e "\e[32mResults archived in: $results_dir\e[0m" echo "" # --- Check for specific open ports --- echo -e "\e[33mChecking for unexpected open ports...\e[0m" # List of allowed ports allowed_ports=$(cat << EOF 80 443 EOF ) # Get a list of all files (ports) in the open-ports directory found_ports=$(ls $results_dir/open-ports) # Loop through each found port for port in $found_ports; do # Remove the .txt extension from the filename port_number=$(basename "$port" .txt) # Check if the port is NOT in the allowed_ports list if ! echo "$allowed_ports" | grep -qw "$port_number"; then echo -e "\e[1;31mWARNING: Unexpected port $port_number is open on some hosts! See $results_dir/open-ports/$port for details.\e[0m" fi done # --- Generate Markdown Report --- echo -e "\e[33mGenerating Markdown report...\e[0m" # Create the Markdown report file report_file="security_report_$current_date.md" # Create the Markdown template (using a here document) cat << EOF > "$report_file" # Security Scan Report - $current_date ## Target Information **Input File:** $1 containing $total_ips ip addresses **Total Ports Scanned:** $topports ## Open Ports Summary **(Summary of open ports and affected hosts will be inserted here)** ## Suspicious Open Ports ## Ping Sweep Results **(Host IPs from ping sweep will be inserted here)** EOF echo -e "\e[33mPopulating Open Ports Summary...\e[0m" # Generate the Markdown table for open ports open_ports_table="" open_ports_table+="| Port | Count |\n" # Table header with newline open_ports_table+="|---|---|\n" # Separator line with newline for port_file in "$results_dir"/open-ports/*; do port_number=$(basename "$port_file" .txt) ip_count=$(wc -l < "$port_file") open_ports_table+="| $port_number | $ip_count |\n" done # Insert the open ports table into the Markdown report sed -i "/(Summary of open ports and affected hosts will be inserted here)/c\\ $open_ports_table" "$report_file" # Use 'c' instead of 'a' # --- Populate Warning Open Ports --- echo -e "\e[33mPopulating Warning Open Ports...\e[0m" # Generate the Markdown list for warning open ports warning_ports_list="" for port in $found_ports; do port_number="${port%.txt}" # Extract the port number (remove .txt) # Check if the port is NOT in the allowed_ports list if ! echo "$allowed_ports" | grep -qw "$port_number"; then warning_ports_list+="* **$port_number:** See $results_dir/open-ports/$port for a list of IP's with the port open.\n" fi done # Now, use awk to insert the warning_ports_list into the markdown report awk -v warning_ports="$warning_ports_list" ' /## Suspicious Open Ports/ { print; print warning_ports; next } 1' "$report_file" > temp_report.md && mv temp_report.md "$report_file" echo -e "\e[33mPopulating Ping Sweep Results...\e[0m" # Count the number of pingable hosts host_count=$(wc -l < "$results_dir/raw_files/pingable_hosts.txt") # Determine the number of columns (adjust as needed) columns=4 # Calculate the number of rows needed rows=$(( (host_count + columns - 1) / columns )) # Initialize the table ping_table="" ping_table+="| | | | |\n" # Adjust header based on 'columns' ping_table+="|---|---|---|---|\n" # Adjust separator based on 'columns' # Read the pingable hosts into an array mapfile -t pingable_hosts < "$results_dir/raw_files/pingable_hosts.txt" # Populate the table i=0 for row in $(seq 1 $rows); do for col in $(seq 1 $columns); do if [[ $i -lt $host_count ]]; then ping_table+="| ${pingable_hosts[$i]} " else ping_table+="| " # Empty cell if no more hosts fi ((i++)) done ping_table+="|\n" done # Insert the ping table into the Markdown report sed -i "/(Host IPs from ping sweep will be inserted here)/c\\ $ping_table" "$report_file" echo -e "\e[33mConverting Markdown report to PDF...\e[0m" # Convert the Markdown report to PDF using Pandoc pandoc "$report_file" -o "security_report_$current_date.pdf" --pdf-engine=xelatex mv "$report_file" "$results_dir/raw_files" echo -e "\e[32mPDF report generated: security_report_$current_date.pdf\e[0m" echo "" echo -e "\e[1;34m Finished Running Script \e[0m" echo ""