If you want to quickly health check your website, then the following script is a simple NMAP script that scans your site for common issues and formats the results in a nice report style.
#!/bin/bash
# Nmap Vulnerability Scanner with Severity Grouping, TLS checks, and Directory Discovery
# Usage: ./vunscan.sh <target_domain>
# Colors for output
RED='\033[0;31m'
ORANGE='\033[0;33m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Check if target is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <target_domain>"
echo "Example: $0 example.com"
exit 1
fi
TARGET=$1
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_DIR="vuln_scan_${TARGET}_${TIMESTAMP}"
RAW_OUTPUT="${OUTPUT_DIR}/raw_scan.xml"
OPEN_PORTS=""
# Debug output
echo "DEBUG: TARGET=$TARGET"
echo "DEBUG: TIMESTAMP=$TIMESTAMP"
echo "DEBUG: OUTPUT_DIR=$OUTPUT_DIR"
echo "DEBUG: RAW_OUTPUT=$RAW_OUTPUT"
# Create output directory
mkdir -p "$OUTPUT_DIR"
if [ ! -d "$OUTPUT_DIR" ]; then
echo -e "${RED}Error: Failed to create output directory $OUTPUT_DIR${NC}"
exit 1
fi
echo "================================================================"
echo " Vulnerability Scanner for $TARGET"
echo "================================================================"
echo "Scan started at: $(date)"
echo "Results will be saved in: $OUTPUT_DIR"
echo ""
# Function to print section headers
print_header() {
echo -e "\n${BLUE}================================================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}================================================================${NC}"
}
# Function to run nmap scan
run_scan() {
print_header "Running Comprehensive Vulnerability Scan"
echo "This may take several minutes…"
# First, determine which ports are open
echo "Phase 1: Port discovery..."
echo "Scanning for open ports (this may take a while)..."
# Try a faster scan first on common ports
nmap -p 1-1000,8080,8443,3306,5432,27017 --open -T4 "$TARGET" -oG "${OUTPUT_DIR}/open_ports_quick.txt" 2>/dev/null
# If user wants full scan, uncomment the next line and comment the previous one
# nmap -p- --open -T4 "$TARGET" -oG "${OUTPUT_DIR}/open_ports.txt" 2>/dev/null
# Extract open ports
if [ -f "${OUTPUT_DIR}/open_ports_quick.txt" ]; then
OPEN_PORTS=$(grep -oE '[0-9]+/open' "${OUTPUT_DIR}/open_ports_quick.txt" 2>/dev/null | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//')
fi
# If no ports found, try common web ports
if [ -z "$OPEN_PORTS" ] || [ "$OPEN_PORTS" = "" ]; then
echo -e "${YELLOW}Warning: No open ports found in quick scan. Checking common web ports...${NC}"
# Test common ports individually
COMMON_PORTS="80,443,8080,8443,22,21,25,3306,5432"
OPEN_PORTS=""
for port in $(echo $COMMON_PORTS | tr ',' ' '); do
echo -n "Testing port $port... "
if nmap -p $port --open "$TARGET" 2>/dev/null | grep -q "open"; then
echo "open"
if [ -z "$OPEN_PORTS" ]; then
OPEN_PORTS="$port"
else
OPEN_PORTS="$OPEN_PORTS,$port"
fi
else
echo "closed/filtered"
fi
done
fi
# Final fallback
if [ -z "$OPEN_PORTS" ] || [ "$OPEN_PORTS" = "" ]; then
echo -e "${YELLOW}Warning: No open ports detected. Using default web ports for scanning.${NC}"
OPEN_PORTS="80,443"
fi
echo ""
echo "Ports to scan: $OPEN_PORTS"
echo ""
# Main vulnerability scan with http-vulners-regex
echo "Phase 2: Vulnerability scanning..."
nmap -sV -sC --script vuln,http-vulners-regex \
--script-args vulns.showall,http-vulners-regex.paths={/} \
-p "$OPEN_PORTS" \
-oX "$RAW_OUTPUT" \
-oN "${OUTPUT_DIR}/scan_normal.txt" \
"$TARGET"
if [ $? -ne 0 ]; then
echo -e "${RED}Error: Nmap scan failed${NC}"
# Don't exit, continue with other scans
fi
}
# Function to parse and categorize vulnerabilities
parse_vulnerabilities() {
print_header "Parsing and Categorizing Vulnerabilities"
# Initialize arrays
declare -a critical_vulns=()
declare -a high_vulns=()
declare -a medium_vulns=()
declare -a low_vulns=()
declare -a info_vulns=()
# Create temporary files for each severity
CRITICAL_FILE="${OUTPUT_DIR}/critical.tmp"
HIGH_FILE="${OUTPUT_DIR}/high.tmp"
MEDIUM_FILE="${OUTPUT_DIR}/medium.tmp"
LOW_FILE="${OUTPUT_DIR}/low.tmp"
INFO_FILE="${OUTPUT_DIR}/info.tmp"
# Clear temp files
> "$CRITICAL_FILE"
> "$HIGH_FILE"
> "$MEDIUM_FILE"
> "$LOW_FILE"
> "$INFO_FILE"
# Parse XML output for vulnerabilities
if [ -f "$RAW_OUTPUT" ]; then
# Extract script output and categorize by common vulnerability indicators
grep -A 20 '<script id=".*vuln.*"' "$RAW_OUTPUT" | while read line; do
if echo "$line" | grep -qi "CRITICAL\|CVE.*CRITICAL\|score.*9\|score.*10"; then
echo "$line" >> "$CRITICAL_FILE"
elif echo "$line" | grep -qi "HIGH\|CVE.*HIGH\|score.*[7-8]"; then
echo "$line" >> "$HIGH_FILE"
elif echo "$line" | grep -qi "MEDIUM\|CVE.*MEDIUM\|score.*[4-6]"; then
echo "$line" >> "$MEDIUM_FILE"
elif echo "$line" | grep -qi "LOW\|CVE.*LOW\|score.*[1-3]"; then
echo "$line" >> "$LOW_FILE"
elif echo "$line" | grep -qi "INFO\|INFORMATION"; then
echo "$line" >> "$INFO_FILE"
fi
done
# Also parse normal output for vulnerability information
if [ -f "${OUTPUT_DIR}/scan_normal.txt" ]; then
# Look for common vulnerability patterns in normal output
grep -E "(CVE-|VULNERABLE|State: VULNERABLE)" "${OUTPUT_DIR}/scan_normal.txt" | while read vuln_line; do
if echo "$vuln_line" | grep -qi "critical\|9\.[0-9]\|10\.0"; then
echo "$vuln_line" >> "$CRITICAL_FILE"
elif echo "$vuln_line" | grep -qi "high\|[7-8]\.[0-9]"; then
echo "$vuln_line" >> "$HIGH_FILE"
elif echo "$vuln_line" | grep -qi "medium\|[4-6]\.[0-9]"; then
echo "$vuln_line" >> "$MEDIUM_FILE"
elif echo "$vuln_line" | grep -qi "low\|[1-3]\.[0-9]"; then
echo "$vuln_line" >> "$LOW_FILE"
else
echo "$vuln_line" >> "$INFO_FILE"
fi
done
fi
fi
}
# Function to display vulnerabilities by severity
display_results() {
print_header "VULNERABILITY SCAN RESULTS"
# Critical Vulnerabilities
echo -e "\n${RED}🔴 CRITICAL SEVERITY VULNERABILITIES${NC}"
echo "=================================================="
if [ -s "${OUTPUT_DIR}/critical.tmp" ]; then
cat "${OUTPUT_DIR}/critical.tmp" | head -20
CRITICAL_COUNT=$(wc -l < "${OUTPUT_DIR}/critical.tmp")
echo -e "${RED}Total Critical: $CRITICAL_COUNT${NC}"
else
echo -e "${GREEN}✓ No critical vulnerabilities found${NC}"
fi
# High Vulnerabilities
echo -e "\n${ORANGE}🟠 HIGH SEVERITY VULNERABILITIES${NC}"
echo "============================================="
if [ -s "${OUTPUT_DIR}/high.tmp" ]; then
cat "${OUTPUT_DIR}/high.tmp" | head -15
HIGH_COUNT=$(wc -l < "${OUTPUT_DIR}/high.tmp")
echo -e "${ORANGE}Total High: $HIGH_COUNT${NC}"
else
echo -e "${GREEN}✓ No high severity vulnerabilities found${NC}"
fi
# Medium Vulnerabilities
echo -e "\n${YELLOW}🟡 MEDIUM SEVERITY VULNERABILITIES${NC}"
echo "==============================================="
if [ -s "${OUTPUT_DIR}/medium.tmp" ]; then
cat "${OUTPUT_DIR}/medium.tmp" | head -10
MEDIUM_COUNT=$(wc -l < "${OUTPUT_DIR}/medium.tmp")
echo -e "${YELLOW}Total Medium: $MEDIUM_COUNT${NC}"
else
echo -e "${GREEN}✓ No medium severity vulnerabilities found${NC}"
fi
# Low Vulnerabilities
echo -e "\n${BLUE}🔵 LOW SEVERITY VULNERABILITIES${NC}"
echo "=========================================="
if [ -s "${OUTPUT_DIR}/low.tmp" ]; then
cat "${OUTPUT_DIR}/low.tmp" | head -8
LOW_COUNT=$(wc -l < "${OUTPUT_DIR}/low.tmp")
echo -e "${BLUE}Total Low: $LOW_COUNT${NC}"
else
echo -e "${GREEN}✓ No low severity vulnerabilities found${NC}"
fi
# Information/Other
echo -e "\n${GREEN}ℹ️ INFORMATIONAL${NC}"
echo "========================="
if [ -s "${OUTPUT_DIR}/info.tmp" ]; then
cat "${OUTPUT_DIR}/info.tmp" | head -5
INFO_COUNT=$(wc -l < "${OUTPUT_DIR}/info.tmp")
echo -e "${GREEN}Total Info: $INFO_COUNT${NC}"
else
echo "No informational items found"
fi
}
# Function to run gobuster scan for enhanced directory discovery
run_gobuster_scan() {
echo "Running gobuster directory scan..."
GOBUSTER_RESULTS="${OUTPUT_DIR}/gobuster_results.txt"
PERMISSION_ANALYSIS="${OUTPUT_DIR}/gobuster_permissions.txt"
> "$PERMISSION_ANALYSIS"
for port in $(echo "$WEB_PORTS" | tr ',' ' '); do
PROTOCOL="http"
if [[ "$port" == "443" || "$port" == "8443" ]]; then
PROTOCOL="https"
fi
echo "Scanning $PROTOCOL://$TARGET:$port with gobuster..."
# Run gobuster with common wordlist
if [ -f "/usr/share/wordlists/dirb/common.txt" ]; then
WORDLIST="/usr/share/wordlists/dirb/common.txt"
elif [ -f "/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt" ]; then
WORDLIST="/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt"
else
# Create a small built-in wordlist
WORDLIST="${OUTPUT_DIR}/temp_wordlist.txt"
cat > "$WORDLIST" <<EOF
admin
administrator
api
backup
bin
cgi-bin
config
data
database
db
debug
dev
development
doc
docs
documentation
download
downloads
error
errors
export
files
hidden
images
img
include
includes
js
library
log
logs
manage
management
manager
media
old
private
proc
public
resources
scripts
secret
secure
server-status
staging
static
storage
system
temp
templates
test
testing
tmp
upload
uploads
users
var
vendor
web
webapp
wp-admin
wp-content
.git
.svn
.env
.htaccess
.htpasswd
robots.txt
sitemap.xml
web.config
phpinfo.php
info.php
test.php
EOF
fi
# Run gobuster with status code analysis
gobuster dir -u "$PROTOCOL://$TARGET:$port" \
-w "$WORDLIST" \
-k \
-t 10 \
--no-error \
-o "${GOBUSTER_RESULTS}_${port}.txt" \
-s "200,204,301,302,307,401,403,405" 2>/dev/null
# Analyze results for permission issues
if [ -f "${GOBUSTER_RESULTS}_${port}.txt" ]; then
echo "Analyzing gobuster results for permission issues..."
# Check for 403 Forbidden directories
grep "Status: 403" "${GOBUSTER_RESULTS}_${port}.txt" | while read line; do
dir=$(echo "$line" | awk '{print $1}')
echo -e "${ORANGE}[403 Forbidden]${NC} $PROTOCOL://$TARGET:$port$dir - Directory exists but access denied" >> "$PERMISSION_ANALYSIS"
echo -e "${ORANGE} Permission Issue:${NC} $PROTOCOL://$TARGET:$port$dir (403 Forbidden)"
done
# Check for 401 Unauthorized directories
grep "Status: 401" "${GOBUSTER_RESULTS}_${port}.txt" | while read line; do
dir=$(echo "$line" | awk '{print $1}')
echo -e "${YELLOW}[401 Unauthorized]${NC} $PROTOCOL://$TARGET:$port$dir - Authentication required" >> "$PERMISSION_ANALYSIS"
echo -e "${YELLOW} Auth Required:${NC} $PROTOCOL://$TARGET:$port$dir (401 Unauthorized)"
done
# Check for directory listing enabled (potentially dangerous)
grep "Status: 200" "${GOBUSTER_RESULTS}_${port}.txt" | while read line; do
dir=$(echo "$line" | awk '{print $1}')
# Check if it's a directory by looking for trailing slash or common directory patterns
if [[ "$dir" =~ /$ ]] || [[ ! "$dir" =~ \. ]]; then
# Test if directory listing is enabled
RESPONSE=$(curl -k -s --max-time 5 "$PROTOCOL://$TARGET:$port$dir" 2>/dev/null)
if echo "$RESPONSE" | grep -qi "index of\|directory listing\|parent directory\|<pre>\|<dir>"; then
echo -e "${RED}[Directory Listing Enabled]${NC} $PROTOCOL://$TARGET:$port$dir - SECURITY RISK" >> "$PERMISSION_ANALYSIS"
echo -e "${RED} 🚨 Directory Listing:${NC} $PROTOCOL://$TARGET:$port$dir"
fi
fi
done
# Check for sensitive files with incorrect permissions
for sensitive_file in ".git/config" ".env" ".htpasswd" "web.config" "phpinfo.php" "info.php" ".DS_Store" "Thumbs.db"; do
if grep -q "/$sensitive_file.*Status: 200" "${GOBUSTER_RESULTS}_${port}.txt"; then
echo -e "${RED}[Sensitive File Exposed]${NC} $PROTOCOL://$TARGET:$port/$sensitive_file - CRITICAL SECURITY RISK" >> "$PERMISSION_ANALYSIS"
echo -e "${RED} 🚨 Sensitive File:${NC} $PROTOCOL://$TARGET:$port/$sensitive_file"
fi
done
fi
done
# Clean up temporary wordlist if created
[ -f "${OUTPUT_DIR}/temp_wordlist.txt" ] && rm -f "${OUTPUT_DIR}/temp_wordlist.txt"
# Display permission analysis summary
if [ -s "$PERMISSION_ANALYSIS" ]; then
echo ""
echo -e "${ORANGE}=== Directory Permission Issues Summary ===${NC}"
cat "$PERMISSION_ANALYSIS"
# Count different types of issues
FORBIDDEN_COUNT=$(grep -c "403 Forbidden" "$PERMISSION_ANALYSIS" 2>/dev/null || echo 0)
UNAUTH_COUNT=$(grep -c "401 Unauthorized" "$PERMISSION_ANALYSIS" 2>/dev/null || echo 0)
LISTING_COUNT=$(grep -c "Directory Listing Enabled" "$PERMISSION_ANALYSIS" 2>/dev/null || echo 0)
SENSITIVE_COUNT=$(grep -c "Sensitive File Exposed" "$PERMISSION_ANALYSIS" 2>/dev/null || echo 0)
echo ""
echo "Permission Issue Statistics:"
echo " - 403 Forbidden directories: $FORBIDDEN_COUNT"
echo " - 401 Unauthorized directories: $UNAUTH_COUNT"
echo " - Directory listings enabled: $LISTING_COUNT"
echo " - Sensitive files exposed: $SENSITIVE_COUNT"
fi
}
# Function to run TLS/SSL checks
run_tls_checks() {
print_header "Running TLS/SSL Security Checks"
# Check for HTTPS ports
HTTPS_PORTS=$(echo "$OPEN_PORTS" | tr ',' '\n' | grep -E '443|8443' | tr '\n' ',' | sed 's/,$//')
if [ -z "$HTTPS_PORTS" ]; then
HTTPS_PORTS="443"
echo "No HTTPS ports found in scan, checking default port 443..."
fi
echo "Checking TLS/SSL on ports: $HTTPS_PORTS"
# Run SSL scan using nmap ssl scripts
nmap -sV --script ssl-cert,ssl-enum-ciphers,ssl-known-key,ssl-ccs-injection,ssl-heartbleed,ssl-poodle,sslv2,tls-alpn,tls-nextprotoneg \
-p "$HTTPS_PORTS" \
-oN "${OUTPUT_DIR}/tls_scan.txt" \
"$TARGET" 2>/dev/null
# Parse TLS results
TLS_ISSUES_FILE="${OUTPUT_DIR}/tls_issues.txt"
> "$TLS_ISSUES_FILE"
# Check for weak ciphers
if grep -q "TLSv1.0\|SSLv2\|SSLv3" "${OUTPUT_DIR}/tls_scan.txt" 2>/dev/null; then
echo "CRITICAL: Outdated SSL/TLS protocols detected" >> "$TLS_ISSUES_FILE"
fi
# Check for weak cipher suites
if grep -q "DES\|RC4\|MD5" "${OUTPUT_DIR}/tls_scan.txt" 2>/dev/null; then
echo "HIGH: Weak cipher suites detected" >> "$TLS_ISSUES_FILE"
fi
# Check for certificate issues
if grep -q "expired\|self-signed" "${OUTPUT_DIR}/tls_scan.txt" 2>/dev/null; then
echo "MEDIUM: Certificate issues detected" >> "$TLS_ISSUES_FILE"
fi
# Display TLS results
echo ""
if [ -s "$TLS_ISSUES_FILE" ]; then
echo -e "${RED}TLS/SSL Issues Found:${NC}"
cat "$TLS_ISSUES_FILE"
else
echo -e "${GREEN}✓ No major TLS/SSL issues detected${NC}"
fi
echo ""
}
# Function to run directory busting and permission checks
run_dirbuster() {
print_header "Running Directory Discovery and Permission Checks"
# Check for web ports
WEB_PORTS=$(echo "$OPEN_PORTS" | tr ',' '\n' | grep -E '^(80|443|8080|8443)$' | tr '\n' ',' | sed 's/,$//')
if [ -z "$WEB_PORTS" ]; then
echo "No standard web ports found in open ports, checking defaults..."
WEB_PORTS="80,443"
fi
echo "Running directory discovery on web ports: $WEB_PORTS"
# Check if gobuster is available
if command -v gobuster &> /dev/null; then
echo -e "${GREEN}Using gobuster for enhanced directory discovery and permission checks${NC}"
run_gobuster_scan
else
echo -e "${YELLOW}Gobuster not found. Using fallback method.${NC}"
echo -e "${YELLOW}Install gobuster for enhanced directory permission checks: brew install gobuster${NC}"
fi
# Use nmap's http-enum script for directory discovery
nmap -sV --script http-enum \
--script-args http-enum.basepath='/' \
-p "$WEB_PORTS" \
-oN "${OUTPUT_DIR}/dirbuster.txt" \
"$TARGET" 2>/dev/null
# Common directory wordlist (built-in small list)
COMMON_DIRS="admin administrator backup api config test dev staging uploads download downloads files documents images img css js scripts cgi-bin wp-admin phpmyadmin .git .svn .env .htaccess robots.txt sitemap.xml"
# Quick check for common directories using curl
DIRS_FOUND_FILE="${OUTPUT_DIR}/directories_found.txt"
> "$DIRS_FOUND_FILE"
for port in $(echo "$WEB_PORTS" | tr ',' ' '); do
PROTOCOL="http"
if [[ "$port" == "443" || "$port" == "8443" ]]; then
PROTOCOL="https"
fi
echo "Checking common directories on $PROTOCOL://$TARGET:$port"
for dir in $COMMON_DIRS; do
URL="$PROTOCOL://$TARGET:$port/$dir"
STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" --max-time 3 "$URL" 2>/dev/null)
if [[ "$STATUS" == "200" || "$STATUS" == "301" || "$STATUS" == "302" || "$STATUS" == "401" || "$STATUS" == "403" ]]; then
echo "[$STATUS] $URL" >> "$DIRS_FOUND_FILE"
echo -e "${GREEN}Found:${NC} [$STATUS] $URL"
# Check for permission issues
if [[ "$STATUS" == "403" ]]; then
echo -e "${ORANGE} ⚠️ Permission denied (403) - Possible misconfiguration${NC}"
echo "[PERMISSION ISSUE] 403 Forbidden: $URL" >> "${OUTPUT_DIR}/permission_issues.txt"
elif [[ "$STATUS" == "401" ]]; then
echo -e "${YELLOW} 🔒 Authentication required (401)${NC}"
echo "[AUTH REQUIRED] 401 Unauthorized: $URL" >> "${OUTPUT_DIR}/permission_issues.txt"
fi
fi
done
done
# Display results
echo ""
if [ -s "$DIRS_FOUND_FILE" ]; then
echo -e "${YELLOW}Directories/Files discovered:${NC}"
cat "$DIRS_FOUND_FILE"
else
echo "No additional directories found"
fi
# Display permission issues if found
if [ -s "${OUTPUT_DIR}/permission_issues.txt" ]; then
echo ""
echo -e "${ORANGE}Directory Permission Issues Found:${NC}"
cat "${OUTPUT_DIR}/permission_issues.txt"
fi
echo ""
}
# Function to generate summary report
generate_summary() {
print_header "SCAN SUMMARY"
CRITICAL_COUNT=0
HIGH_COUNT=0
MEDIUM_COUNT=0
LOW_COUNT=0
INFO_COUNT=0
[ -f "${OUTPUT_DIR}/critical.tmp" ] && CRITICAL_COUNT=$(wc -l < "${OUTPUT_DIR}/critical.tmp")
[ -f "${OUTPUT_DIR}/high.tmp" ] && HIGH_COUNT=$(wc -l < "${OUTPUT_DIR}/high.tmp")
[ -f "${OUTPUT_DIR}/medium.tmp" ] && MEDIUM_COUNT=$(wc -l < "${OUTPUT_DIR}/medium.tmp")
[ -f "${OUTPUT_DIR}/low.tmp" ] && LOW_COUNT=$(wc -l < "${OUTPUT_DIR}/low.tmp")
[ -f "${OUTPUT_DIR}/info.tmp" ] && INFO_COUNT=$(wc -l < "${OUTPUT_DIR}/info.tmp")
echo "Target: $TARGET"
echo "Scan Date: $(date)"
echo ""
echo -e "${RED}Critical: $CRITICAL_COUNT${NC}"
echo -e "${ORANGE}High: $HIGH_COUNT${NC}"
echo -e "${YELLOW}Medium: $MEDIUM_COUNT${NC}"
echo -e "${BLUE}Low: $LOW_COUNT${NC}"
echo -e "${GREEN}Informational: $INFO_COUNT${NC}"
echo ""
TOTAL=$((CRITICAL_COUNT + HIGH_COUNT + MEDIUM_COUNT + LOW_COUNT))
echo "Total Vulnerabilities: $TOTAL"
# Risk assessment
if [ $CRITICAL_COUNT -gt 0 ]; then
echo -e "${RED}🚨 RISK LEVEL: CRITICAL - Immediate action required!${NC}"
elif [ $HIGH_COUNT -gt 0 ]; then
echo -e "${ORANGE}⚠️ RISK LEVEL: HIGH - Action required soon${NC}"
elif [ $MEDIUM_COUNT -gt 0 ]; then
echo -e "${YELLOW}⚡ RISK LEVEL: MEDIUM - Should be addressed${NC}"
elif [ $LOW_COUNT -gt 0 ]; then
echo -e "${BLUE}📋 RISK LEVEL: LOW - Monitor and plan fixes${NC}"
else
echo -e "${GREEN}✅ RISK LEVEL: MINIMAL - Good security posture${NC}"
fi
# Save summary to file
{
echo "Vulnerability Scan Summary for $TARGET"
echo "======================================"
echo "Scan Date: $(date)"
echo ""
echo "Critical: $CRITICAL_COUNT"
echo "High: $HIGH_COUNT"
echo "Medium: $MEDIUM_COUNT"
echo "Low: $LOW_COUNT"
echo "Informational: $INFO_COUNT"
echo "Total: $TOTAL"
echo ""
echo "Additional Checks:"
[ -f "${OUTPUT_DIR}/tls_issues.txt" ] && [ -s "${OUTPUT_DIR}/tls_issues.txt" ] && echo "TLS/SSL Issues: $(wc -l < "${OUTPUT_DIR}/tls_issues.txt")"
[ -f "${OUTPUT_DIR}/directories_found.txt" ] && [ -s "${OUTPUT_DIR}/directories_found.txt" ] && echo "Directories Found: $(wc -l < "${OUTPUT_DIR}/directories_found.txt")"
[ -f "${OUTPUT_DIR}/gobuster_permissions.txt" ] && [ -s "${OUTPUT_DIR}/gobuster_permissions.txt" ] && echo "Directory Permission Issues: $(wc -l < "${OUTPUT_DIR}/gobuster_permissions.txt")"
} > "${OUTPUT_DIR}/summary.txt"
}
# Main execution
main() {
echo "Starting vulnerability scan for $TARGET…"
# Check if required tools are installed
if ! command -v nmap &> /dev/null; then
echo -e "${RED}Error: nmap is not installed. Please install nmap first.${NC}"
exit 1
fi
if ! command -v curl &> /dev/null; then
echo -e "${RED}Error: curl is not installed. Please install curl first.${NC}"
exit 1
fi
# Check for optional tools
if command -v gobuster &> /dev/null; then
echo -e "${GREEN}✓ Gobuster found - Enhanced directory scanning enabled${NC}"
else
echo -e "${YELLOW}ℹ️ Gobuster not found - Basic directory scanning will be used${NC}"
echo -e "${YELLOW} Install with: brew install gobuster (macOS) or apt install gobuster (Linux)${NC}"
fi
# Run the main vulnerability scan
run_scan
# Run TLS/SSL checks
run_tls_checks
# Run directory discovery
run_dirbuster
# Parse results
parse_vulnerabilities
# Display formatted results
display_results
# Generate summary
generate_summary
# Cleanup temporary files
rm -f "${OUTPUT_DIR}"/*.tmp
print_header "SCAN COMPLETE"
echo "All results saved in: $OUTPUT_DIR"
echo "Summary saved in: ${OUTPUT_DIR}/summary.txt"
echo -e "${GREEN}Scan completed at: $(date)${NC}"
}
# Run main function
main
Here’s a comprehensive guide on how to fix each type of directory permission issue that the above script might find (for apache):
## 1. **403 Forbidden Errors**
### What it means:
The directory/file exists but the server is denying access to it.
### How to fix:
# For Apache (.htaccess)
# Add to .htaccess in the directory:
Order deny,allow
Deny from all
# Or remove the directory from web access entirely
# Move sensitive directories outside the web root
mv /var/www/html/backup /var/backups/
# For Nginx
# Add to nginx.conf:
location /admin {
deny all;
return 404; # Return 404 instead of 403 to hide existence
}
## 2. **401 Unauthorized Errors**
### What it means:
Authentication is required but may not be properly configured.
### How to fix:
# For Apache - create .htpasswd file
htpasswd -c /etc/apache2/.htpasswd username
# Add to .htaccess:
AuthType Basic
AuthName "Restricted Access"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
# For Nginx:
# Install apache2-utils for htpasswd
sudo apt-get install apache2-utils
htpasswd -c /etc/nginx/.htpasswd username
# Add to nginx.conf:
location /admin {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}
## 3. **Directory Listing Enabled (CRITICAL)**
### What it means:
Anyone can see all files in the directory - major security risk!
### How to fix:
# For Apache
# Method 1: Add to .htaccess in the directory
Options -Indexes
# Method 2: Add to Apache config (httpd.conf or apache2.conf)
<Directory /var/www/html>
Options -Indexes
</Directory>
# For Nginx
# Add to nginx.conf (Nginx doesn't have directory listing by default)
# If you see it enabled, remove:
autoindex off; # This should be the default
# Create index files in empty directories
echo "<!DOCTYPE html><html><head><title>403 Forbidden</title></head><body><h1>403 Forbidden</h1></body></html>" > index.html
## 4. **Sensitive Files Exposed (CRITICAL)**
### Common exposed files and fixes:
#### **.git directory**
# Remove .git from production
rm -rf /var/www/html/.git
# Or block access via .htaccess
<Files ~ "^\.git">
Order allow,deny
Deny from all
</Files>
# For Nginx:
location ~ /\.git {
deny all;
return 404;
}
#### **.env file**
# Move outside web root
mv /var/www/html/.env /var/www/
# Update your application to read from new location
# In PHP: require_once __DIR__ . '/../.env';
# Block via .htaccess
<Files .env>
Order allow,deny
Deny from all
</Files>
#### **Configuration files (config.php, settings.php)**
# Move sensitive configs outside web root
mv /var/www/html/config.php /var/www/config/
# Or restrict access via .htaccess
<Files "config.php">
Order allow,deny
Deny from all
</Files>
#### **Backup files**
# Remove backup files from web directory
find /var/www/html -name "*.bak" -o -name "*.backup" -o -name "*.old" | xargs rm -f
# Create a cron job to clean regularly
echo "0 2 * * * find /var/www/html -name '*.bak' -o -name '*.backup' -delete" | crontab -
## 5. **General Security Best Practices**
### Create a comprehensive .htaccess file:
# Disable directory browsing
Options -Indexes
# Deny access to hidden files and directories
<Files .*>
Order allow,deny
Deny from all
</Files>
# Deny access to backup and source files
<FilesMatch "(\.(bak|backup|config|dist|fla|inc|ini|log|psd|sh|sql|swp)|~)$">
Order allow,deny
Deny from all
</FilesMatch>
# Protect sensitive files
location ~ /(\.htaccess|\.htpasswd|\.env|composer\.json|composer\.lock|package\.json|package-lock\.json)$ {
deny all;
return 404;
}
## 6. Quick Security Audit Commands
## Run these commands to find and fix common issues:
# Find all .git directories in web root
find /var/www/html -type d -name .git
# Find all .env files
find /var/www/html -name .env
# Find all backup files
find /var/www/html -type f \( -name "*.bak" -o -name "*.backup" -o -name "*.old" -o -name "*~" \)
# Find directories without index files (potential listing)
find /var/www/html -type d -exec sh -c '[ ! -f "$1/index.html" ] && [ ! -f "$1/index.php" ] && echo "$1"' _ {} \;
# Set proper permissions
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;
## 7. Testing Your Fixes
## After implementing fixes, test them:
# Test that sensitive files are blocked
curl -I https://yoursite.com/.git/config
# Should return 403 or 404
# Test that directory listing is disabled
curl https://yoursite.com/images/
# Should not show a file list
# Run the vunscan.sh script again
./vunscan.sh yoursite.com
# Verify issues are resolved
## 8. Preventive Measures
## 1. Use a deployment script that excludes sensitive files:
bash
## 2. Regular security scans:
bash
## 3. Use a Web Application Firewall (WAF) like ModSecurity or Cloudflare
# Remember: The goal is not just to hide these files (security through obscurity) but to properly secure them or remove them from the web-accessible directory entirely.