bash_scan_port_html.sh
· 8.5 KiB · Bash
Ham
#!/bin/bash
# Couleurs pour les messages en console
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # Pas de couleur
# Vérifie si l'outil nmap est installé
if ! command -v nmap &> /dev/null; then
echo -e "${RED}❌ nmap n'est pas installé. Installez-le d'abord.\n try: apt install nmap ${NC}"
exit 1
fi
# Vérifie si le dossier de sortie existe, sinon le crée
output_dir="/home/www-adm1n/rapports"
mkdir -p "$output_dir"
# Création d'un fichier HTML avec la date et l'heure courantes
current_datetime=$(date +"%Y-%m-%d %H:%M:%S")
output_file="$output_dir/scan_ports_$(date +"%Y-%m-%d_%H-%M-%S").html"
temp_file="/tmp/nmap_scan_result.txt"
# Récupère des informations système
hostname=$(hostname)
os_info=$(uname -srvmo)
# Début du script avec message et emoji
echo -e "${YELLOW}🔍 Démarrage du scan complet des ports...${NC}"
# Création du fichier HTML avec thème sombre, style moderne, tri, encodage UTF-8 et adaptation mobile
echo "<html>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>📊 Rapport de Scan Complet des Ports</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css'>
<style>
body {
background-color: #121212;
color: #e0e0e0;
font-family: Arial, sans-serif;
}
h1 {
color: #ffca28;
text-align: center;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.badge {
background-color: #e53935;
color: white;
border-radius: 50%;
padding: 5px 10px;
margin-left: 10px;
font-weight: bold;
font-size: 0.8em;
}
table {
width: 90%;
max-width: 1200px;
margin: 20px auto;
border-collapse: collapse;
overflow: hidden;
border-radius: 10px;
}
th, td {
padding: 15px;
border-bottom: 1px solid #333;
text-align: left;
}
th {
background-color: #333;
color: #ffca28;
font-weight: bold;
cursor: pointer;
}
tr:nth-child(even) {
background-color: #1e1e1e;
}
tr:nth-child(odd) {
background-color: #292929;
}
tr:hover {
background-color: #444444;
}
.icon-cell {
text-align: center;
}
footer {
text-align: center;
margin-top: 20px;
color: #888;
}
footer a {
color: #ffca28;
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}
</style>
<script>
function sortTable(n) {
var table = document.getElementById('portTable');
var rows = Array.from(table.rows).slice(1);
var asc = table.getAttribute('data-sort-asc') !== 'true';
rows.sort(function (row1, row2) {
var cell1 = row1.cells[n].innerText.toLowerCase();
var cell2 = row2.cells[n].innerText.toLowerCase();
if (cell1 < cell2) return asc ? -1 : 1;
if (cell1 > cell2) return asc ? 1 : -1;
return 0;
});
table.tBodies[0].append(...rows);
table.setAttribute('data-sort-asc', asc);
}
</script>
</head>
<body>
<h1>📊 Rapport de Scan Complet des Ports <span class='badge' id='port-count'>0</span></h1>
<p style='text-align: center;'>${current_datetime}</p>
<table id='portTable'>
<tr>
<th onclick='sortTable(0)'>Port</th>
<th onclick='sortTable(1)'>Type</th>
<th onclick='sortTable(2)'>Service</th>
<th>Icone</th>
<th onclick='sortTable(4)'>Statut</th>
</tr>" > "$output_file"
# Affiche une barre de progression simulée
function progress_bar {
for i in {1..10}; do
echo -ne "${YELLOW}⏳ Progression : $((i * 10))% \r${NC}"
sleep 0.3
done
echo -ne '\n'
}
progress_bar
# Exécution du scan de tous les ports TCP et UDP avec Nmap sans détection de version, enregistrement dans un fichier temporaire
nmap -sS -sU -p- localhost > "$temp_file"
# Vérification si le fichier temporaire a bien été créé et contient des données
if [[ ! -s "$temp_file" ]]; then
echo -e "${RED}❌ Erreur : Aucun résultat trouvé. Le scan nmap n'a pas produit de sortie.${NC}"
exit 1
fi
# Compteur de ports
port_count=0
# Fonction pour attribuer une icône selon le service et le port
function get_icon {
service="$1"
port_number="$2"
if [[ $service == "docker" ]]; then
echo "<i class='fa-brands fa-docker'></i>"
elif [[ $service == "http" || $service == "https" || $service == "apache" ]]; then
echo "<i class='fa-solid fa-feather '></i>"
elif [[ $service == "mysql" ]]; then
echo "<i class='fas fa-database'></i>"
elif [[ $service == "ssh" ]]; then
echo "<i class='fas fa-lock'></i>"
elif [[ $service == "smtp" ]]; then
echo "<i class='fas fa-envelope'></i>"
elif [[ $port_number -eq 80 || $port_number -eq 81 || $port_number -eq 8080 || $port_number -eq 443 || ( $port_number -ge 8060 && $port_number -le 8090 ) ]]; then
echo "<i class='fa-solid fa-earth-europe'></i>"
elif [[ $service == "mysql" || $port_number -eq 3306 ]]; then
echo "<i class='fas fa-database'></i>" # MySQL
elif [[ $service == "rpcbind" || $port_number -eq 111 ]]; then
echo "<i class='fas fa-link'></i>" # RPC services
elif [[ $service == "netbios-ssn" || $service == "netbios-ns" || $service == "netbios-dgm" ]]; then
echo "<i class='fas fa-network-wired'></i>" # NetBIOS
elif [[ $service == "microsoft-ds" || $port_number -eq 445 ]]; then
echo "<i class='fab fa-microsoft'></i>" # Microsoft Directory Services
elif [[ $service == "nessus" || $port_number -eq 3001 ]]; then
echo "<i class='fas fa-shield-alt'></i>" # Nessus
elif [[ $service == "redis" || $port_number -eq 6379 ]]; then
echo "<i class='fas fa-database'></i>" # Redis
elif [[ $service == "memcache" || $port_number -eq 11211 ]]; then
echo "<i class='fas fa-memory'></i>" # Memcache
elif [[ $service == "unot" || $port_number -eq 5055 ]]; then
echo "<i class='fas fa-info-circle'></i>" # Unot (générique pour services inconnus)
elif [[ $service == "pharos" || $port_number -eq 4443 ]]; then
echo "<i class='fas fa-project-diagram'></i>" # Pharos
elif [[ $service == "llmnr" || $port_number -eq 5355 ]]; then
echo "<i class='fas fa-broadcast-tower'></i>" # LLMNR (Link-Local Multicast)
elif [[ $service == "tor-orport" || $port_number -eq 9001 ]]; then
echo "<i class='fas fa-user-secret'></i>" # Tor
elif [[ $service == "sdr" || $port_number -eq 9010 ]]; then
echo "<i class='fas fa-broadcast-tower'></i>" # SDR (Service Discovery Relay)
elif [[ $service == "dhcpc" || $port_number -eq 68 ]]; then
echo "<i class='fas fa-network-wired'></i>" # DHCP client
elif [[ $service == "unknown" ]]; then
echo "<i class='fas fa-question-circle'></i>" # Unknown service
elif [[ $port_number -eq 443 || $port_number -eq 8443 || $service == "https-alt" ]]; then
echo "<i class='fas fa-lock'></i>" # HTTPS and secure ports
else
echo ""
fi
}
# Lecture et analyse du fichier temporaire ligne par ligne
while read -r line; do
echo -e "${YELLOW}🔹 Ligne lue : $line${NC}" # Message de débogage
# Filtre des lignes correspondant aux ports ouverts et extraction des informations
if [[ $line =~ ^[0-9]+/(tcp|udp) ]]; then
port=$(echo "$line" | awk '{print $1}')
protocol=$(echo "$port" | awk -F'/' '{print $2}')
port_number=$(echo "$port" | cut -d'/' -f1)
status=$(echo "$line" | awk '{print $2}')
service=$(echo "$line" | awk '{print $3}')
icon=$(get_icon "$service" "$port_number")
# Incrément du compteur de ports
((port_count++))
# Ajout des informations au fichier HTML
echo "<tr><td>$port</td><td>$protocol</td><td>$service</td><td class='icon-cell'>$icon</td><td>$status</td></tr>" >> "$output_file"
fi
done < "$temp_file"
# Ajout du compteur dans la balise de la pastille
echo "<script>document.getElementById('port-count').innerText = '$port_count';</script>" >> "$output_file"
# Finalisation du fichier HTML avec informations supplémentaires et lien vers le fichier généré
echo "</table>
<footer>
<p>🔒 Rapport généré avec Nmap le ${current_datetime}</p>
<p>📍 Nom de l'hôte : $hostname | OS : $os_info</p>
<p><a href='$output_file' target='_blank'>🔗 Ouvrir le rapport généré</a></p>
</footer>
</body>
</html>" >> "$output_file"
# Suppression du fichier temporaire
rm "$temp_file"
# Confirmation de la création du fichier
if [[ -f "$output_file" ]]; then
echo -e "${GREEN}✅ Scan terminé. Rapport sauvegardé dans :${NC} $output_file"
else
echo -e "${RED}❌ Erreur : Impossible de créer le rapport.$NC"
fi
| 1 | #!/bin/bash |
| 2 | |
| 3 | # Couleurs pour les messages en console |
| 4 | RED='\033[0;31m' |
| 5 | GREEN='\033[0;32m' |
| 6 | YELLOW='\033[0;33m' |
| 7 | NC='\033[0m' # Pas de couleur |
| 8 | |
| 9 | # Vérifie si l'outil nmap est installé |
| 10 | if ! command -v nmap &> /dev/null; then |
| 11 | echo -e "${RED}❌ nmap n'est pas installé. Installez-le d'abord.\n try: apt install nmap ${NC}" |
| 12 | exit 1 |
| 13 | fi |
| 14 | |
| 15 | # Vérifie si le dossier de sortie existe, sinon le crée |
| 16 | output_dir="/home/www-adm1n/rapports" |
| 17 | mkdir -p "$output_dir" |
| 18 | |
| 19 | # Création d'un fichier HTML avec la date et l'heure courantes |
| 20 | current_datetime=$(date +"%Y-%m-%d %H:%M:%S") |
| 21 | output_file="$output_dir/scan_ports_$(date +"%Y-%m-%d_%H-%M-%S").html" |
| 22 | temp_file="/tmp/nmap_scan_result.txt" |
| 23 | |
| 24 | # Récupère des informations système |
| 25 | hostname=$(hostname) |
| 26 | os_info=$(uname -srvmo) |
| 27 | |
| 28 | # Début du script avec message et emoji |
| 29 | echo -e "${YELLOW}🔍 Démarrage du scan complet des ports...${NC}" |
| 30 | |
| 31 | # Création du fichier HTML avec thème sombre, style moderne, tri, encodage UTF-8 et adaptation mobile |
| 32 | echo "<html> |
| 33 | <head> |
| 34 | <meta charset='UTF-8'> |
| 35 | <meta name='viewport' content='width=device-width, initial-scale=1.0'> |
| 36 | <title>📊 Rapport de Scan Complet des Ports</title> |
| 37 | <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css'> |
| 38 | <style> |
| 39 | body { |
| 40 | background-color: #121212; |
| 41 | color: #e0e0e0; |
| 42 | font-family: Arial, sans-serif; |
| 43 | } |
| 44 | h1 { |
| 45 | color: #ffca28; |
| 46 | text-align: center; |
| 47 | padding: 20px; |
| 48 | display: flex; |
| 49 | align-items: center; |
| 50 | justify-content: center; |
| 51 | } |
| 52 | .badge { |
| 53 | background-color: #e53935; |
| 54 | color: white; |
| 55 | border-radius: 50%; |
| 56 | padding: 5px 10px; |
| 57 | margin-left: 10px; |
| 58 | font-weight: bold; |
| 59 | font-size: 0.8em; |
| 60 | } |
| 61 | table { |
| 62 | width: 90%; |
| 63 | max-width: 1200px; |
| 64 | margin: 20px auto; |
| 65 | border-collapse: collapse; |
| 66 | overflow: hidden; |
| 67 | border-radius: 10px; |
| 68 | } |
| 69 | th, td { |
| 70 | padding: 15px; |
| 71 | border-bottom: 1px solid #333; |
| 72 | text-align: left; |
| 73 | } |
| 74 | th { |
| 75 | background-color: #333; |
| 76 | color: #ffca28; |
| 77 | font-weight: bold; |
| 78 | cursor: pointer; |
| 79 | } |
| 80 | tr:nth-child(even) { |
| 81 | background-color: #1e1e1e; |
| 82 | } |
| 83 | tr:nth-child(odd) { |
| 84 | background-color: #292929; |
| 85 | } |
| 86 | tr:hover { |
| 87 | background-color: #444444; |
| 88 | } |
| 89 | .icon-cell { |
| 90 | text-align: center; |
| 91 | } |
| 92 | footer { |
| 93 | text-align: center; |
| 94 | margin-top: 20px; |
| 95 | color: #888; |
| 96 | } |
| 97 | footer a { |
| 98 | color: #ffca28; |
| 99 | text-decoration: none; |
| 100 | } |
| 101 | footer a:hover { |
| 102 | text-decoration: underline; |
| 103 | } |
| 104 | </style> |
| 105 | <script> |
| 106 | function sortTable(n) { |
| 107 | var table = document.getElementById('portTable'); |
| 108 | var rows = Array.from(table.rows).slice(1); |
| 109 | var asc = table.getAttribute('data-sort-asc') !== 'true'; |
| 110 | rows.sort(function (row1, row2) { |
| 111 | var cell1 = row1.cells[n].innerText.toLowerCase(); |
| 112 | var cell2 = row2.cells[n].innerText.toLowerCase(); |
| 113 | if (cell1 < cell2) return asc ? -1 : 1; |
| 114 | if (cell1 > cell2) return asc ? 1 : -1; |
| 115 | return 0; |
| 116 | }); |
| 117 | table.tBodies[0].append(...rows); |
| 118 | table.setAttribute('data-sort-asc', asc); |
| 119 | } |
| 120 | </script> |
| 121 | </head> |
| 122 | <body> |
| 123 | <h1>📊 Rapport de Scan Complet des Ports <span class='badge' id='port-count'>0</span></h1> |
| 124 | <p style='text-align: center;'>${current_datetime}</p> |
| 125 | <table id='portTable'> |
| 126 | <tr> |
| 127 | <th onclick='sortTable(0)'>Port</th> |
| 128 | <th onclick='sortTable(1)'>Type</th> |
| 129 | <th onclick='sortTable(2)'>Service</th> |
| 130 | <th>Icone</th> |
| 131 | <th onclick='sortTable(4)'>Statut</th> |
| 132 | </tr>" > "$output_file" |
| 133 | |
| 134 | # Affiche une barre de progression simulée |
| 135 | function progress_bar { |
| 136 | for i in {1..10}; do |
| 137 | echo -ne "${YELLOW}⏳ Progression : $((i * 10))% \r${NC}" |
| 138 | sleep 0.3 |
| 139 | done |
| 140 | echo -ne '\n' |
| 141 | } |
| 142 | |
| 143 | progress_bar |
| 144 | |
| 145 | # Exécution du scan de tous les ports TCP et UDP avec Nmap sans détection de version, enregistrement dans un fichier temporaire |
| 146 | nmap -sS -sU -p- localhost > "$temp_file" |
| 147 | |
| 148 | # Vérification si le fichier temporaire a bien été créé et contient des données |
| 149 | if [[ ! -s "$temp_file" ]]; then |
| 150 | echo -e "${RED}❌ Erreur : Aucun résultat trouvé. Le scan nmap n'a pas produit de sortie.${NC}" |
| 151 | exit 1 |
| 152 | fi |
| 153 | |
| 154 | # Compteur de ports |
| 155 | port_count=0 |
| 156 | |
| 157 | # Fonction pour attribuer une icône selon le service et le port |
| 158 | function get_icon { |
| 159 | service="$1" |
| 160 | port_number="$2" |
| 161 | |
| 162 | if [[ $service == "docker" ]]; then |
| 163 | echo "<i class='fa-brands fa-docker'></i>" |
| 164 | elif [[ $service == "http" || $service == "https" || $service == "apache" ]]; then |
| 165 | echo "<i class='fa-solid fa-feather '></i>" |
| 166 | elif [[ $service == "mysql" ]]; then |
| 167 | echo "<i class='fas fa-database'></i>" |
| 168 | elif [[ $service == "ssh" ]]; then |
| 169 | echo "<i class='fas fa-lock'></i>" |
| 170 | elif [[ $service == "smtp" ]]; then |
| 171 | echo "<i class='fas fa-envelope'></i>" |
| 172 | elif [[ $port_number -eq 80 || $port_number -eq 81 || $port_number -eq 8080 || $port_number -eq 443 || ( $port_number -ge 8060 && $port_number -le 8090 ) ]]; then |
| 173 | echo "<i class='fa-solid fa-earth-europe'></i>" |
| 174 | elif [[ $service == "mysql" || $port_number -eq 3306 ]]; then |
| 175 | echo "<i class='fas fa-database'></i>" # MySQL |
| 176 | elif [[ $service == "rpcbind" || $port_number -eq 111 ]]; then |
| 177 | echo "<i class='fas fa-link'></i>" # RPC services |
| 178 | elif [[ $service == "netbios-ssn" || $service == "netbios-ns" || $service == "netbios-dgm" ]]; then |
| 179 | echo "<i class='fas fa-network-wired'></i>" # NetBIOS |
| 180 | elif [[ $service == "microsoft-ds" || $port_number -eq 445 ]]; then |
| 181 | echo "<i class='fab fa-microsoft'></i>" # Microsoft Directory Services |
| 182 | elif [[ $service == "nessus" || $port_number -eq 3001 ]]; then |
| 183 | echo "<i class='fas fa-shield-alt'></i>" # Nessus |
| 184 | elif [[ $service == "redis" || $port_number -eq 6379 ]]; then |
| 185 | echo "<i class='fas fa-database'></i>" # Redis |
| 186 | elif [[ $service == "memcache" || $port_number -eq 11211 ]]; then |
| 187 | echo "<i class='fas fa-memory'></i>" # Memcache |
| 188 | elif [[ $service == "unot" || $port_number -eq 5055 ]]; then |
| 189 | echo "<i class='fas fa-info-circle'></i>" # Unot (générique pour services inconnus) |
| 190 | elif [[ $service == "pharos" || $port_number -eq 4443 ]]; then |
| 191 | echo "<i class='fas fa-project-diagram'></i>" # Pharos |
| 192 | elif [[ $service == "llmnr" || $port_number -eq 5355 ]]; then |
| 193 | echo "<i class='fas fa-broadcast-tower'></i>" # LLMNR (Link-Local Multicast) |
| 194 | elif [[ $service == "tor-orport" || $port_number -eq 9001 ]]; then |
| 195 | echo "<i class='fas fa-user-secret'></i>" # Tor |
| 196 | elif [[ $service == "sdr" || $port_number -eq 9010 ]]; then |
| 197 | echo "<i class='fas fa-broadcast-tower'></i>" # SDR (Service Discovery Relay) |
| 198 | elif [[ $service == "dhcpc" || $port_number -eq 68 ]]; then |
| 199 | echo "<i class='fas fa-network-wired'></i>" # DHCP client |
| 200 | elif [[ $service == "unknown" ]]; then |
| 201 | echo "<i class='fas fa-question-circle'></i>" # Unknown service |
| 202 | elif [[ $port_number -eq 443 || $port_number -eq 8443 || $service == "https-alt" ]]; then |
| 203 | echo "<i class='fas fa-lock'></i>" # HTTPS and secure ports |
| 204 | else |
| 205 | echo "" |
| 206 | fi |
| 207 | } |
| 208 | |
| 209 | # Lecture et analyse du fichier temporaire ligne par ligne |
| 210 | while read -r line; do |
| 211 | echo -e "${YELLOW}🔹 Ligne lue : $line${NC}" # Message de débogage |
| 212 | |
| 213 | # Filtre des lignes correspondant aux ports ouverts et extraction des informations |
| 214 | if [[ $line =~ ^[0-9]+/(tcp|udp) ]]; then |
| 215 | port=$(echo "$line" | awk '{print $1}') |
| 216 | protocol=$(echo "$port" | awk -F'/' '{print $2}') |
| 217 | port_number=$(echo "$port" | cut -d'/' -f1) |
| 218 | status=$(echo "$line" | awk '{print $2}') |
| 219 | service=$(echo "$line" | awk '{print $3}') |
| 220 | icon=$(get_icon "$service" "$port_number") |
| 221 | |
| 222 | # Incrément du compteur de ports |
| 223 | ((port_count++)) |
| 224 | |
| 225 | # Ajout des informations au fichier HTML |
| 226 | echo "<tr><td>$port</td><td>$protocol</td><td>$service</td><td class='icon-cell'>$icon</td><td>$status</td></tr>" >> "$output_file" |
| 227 | fi |
| 228 | done < "$temp_file" |
| 229 | |
| 230 | # Ajout du compteur dans la balise de la pastille |
| 231 | echo "<script>document.getElementById('port-count').innerText = '$port_count';</script>" >> "$output_file" |
| 232 | |
| 233 | # Finalisation du fichier HTML avec informations supplémentaires et lien vers le fichier généré |
| 234 | echo "</table> |
| 235 | <footer> |
| 236 | <p>🔒 Rapport généré avec Nmap le ${current_datetime}</p> |
| 237 | <p>📍 Nom de l'hôte : $hostname | OS : $os_info</p> |
| 238 | <p><a href='$output_file' target='_blank'>🔗 Ouvrir le rapport généré</a></p> |
| 239 | </footer> |
| 240 | </body> |
| 241 | </html>" >> "$output_file" |
| 242 | |
| 243 | # Suppression du fichier temporaire |
| 244 | rm "$temp_file" |
| 245 | |
| 246 | # Confirmation de la création du fichier |
| 247 | if [[ -f "$output_file" ]]; then |
| 248 | echo -e "${GREEN}✅ Scan terminé. Rapport sauvegardé dans :${NC} $output_file" |
| 249 | else |
| 250 | echo -e "${RED}❌ Erreur : Impossible de créer le rapport.$NC" |
| 251 | fi |
| 252 |