Erreur32 ha revisionato questo gist 2 years ago. Vai alla revisione
1 file changed, 251 insertions
bash_scan_port_html.sh(file creato)
| @@ -0,0 +1,251 @@ | |||
| 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 | |
Più nuovi
Più vecchi