Parent : [[INDEX-CYBERSECU]]
OSINT Reconnaissance - Favicon hash Shodan et scan Nmap
Problème
Comment un attaquant a-t-il trouvé l'IP du serveur de pré-production de YGGtorrent ? En utilisant le hash du favicon dans Shodan, puis un scan Nmap complet. Cette technique d'OSINT a révélé 13 ports ouverts sur un serveur Windows, dont SMB, RDP, MySQL, Redis et SphinxQL.
Contexte archive Ygg
- Source :
https://yggleak.top/fr/home/ygg-dossier#phase-1-reconnaissance - Phase 1 — Reconnaissance
- Favicon hash :
http.favicon.hash:456260082 - IP découverte :
X.X.X.X - Serveur : Windows, VM Hyper-V
- 13 ports ouverts, firewall probablement désactivé
Technique de reconnaissance
1. Favicon hash Shodan
Chaque favicon a une empreinte numérique unique. En calculant le hash de celle de YGG et en la cherchant dans Shodan, l'IP du serveur de pré-prod apparaît :
http.favicon.hash:456260082
Résultat : X.X.X.X, un serveur Windows hébergé sur une VM Hyper-V.
2. Scan Nmap
13 ports ouverts
13 ports ouverts sur un serveur Windows, dont SMB, RDP, MySQL, Redis et SphinxQL.
Pas de filtrage visible, le firewall est probablement désactivé.
Solution protectif — Défense contre l'OSINT
1. Randomisation du favicon
# favicon_randomizer.py — Générer un favicon unique par serveur
import hashlib
import random
from PIL import Image, ImageDraw
def generate_unique_favicon(seed=None):
"""Génère un favicon visuellement identique mais binairement unique"""
if seed is None:
seed = random.randint(0, 2**32)
# Créer une image 32x32 avec un pixel modifié (invisible)
img = Image.new('RGBA', (32, 32), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
# Dessiner le logo principal
# ... (même design visuel)
# Modifier un pixel invisible (alpha=0) avec la seed
x, y = seed % 32, (seed // 32) % 32
draw.point((x, y), fill=(0, 0, 0, 0))
# Sauvegarder avec métadonnées uniques
img.save('favicon.ico', format='ICO')
return seed
# Vérifier le hash
def get_favicon_hash(filepath):
with open(filepath, 'rb') as f:
data = f.read()
return hashlib.md5(data).hexdigest()
2. Détection de scan Nmap
# detect_nmap_scan.py — Détecter les scans Nmap
import scapy.all as scapy
from collections import defaultdict
import time
class NmapDetector:
def __init__(self):
self.port_hits = defaultdict(list)
self.threshold = 10 # 10 ports différents en 5 secondes
self.window = 5
def analyze_packet(self, packet):
if not packet.haslayer(scapy.TCP):
return None
src_ip = packet[scapy.IP].src
dst_port = packet[scapy.TCP].dport
timestamp = time.time()
# Enregistrer le hit
self.port_hits[src_ip].append((dst_port, timestamp))
# Nettoyer les anciens hits
self.port_hits[src_ip] = [
(p, t) for p, t in self.port_hits[src_ip]
if timestamp - t < self.window
]
# Vérifier le seuil
unique_ports = len(set(p for p, t in self.port_hits[src_ip]))
if unique_ports >= self.threshold:
return {
'alert': 'NMAP_SCAN_DETECTED',
'source_ip': src_ip,
'ports_scanned': unique_ports,
'timestamp': timestamp
}
return None
3. Hardening du firewall Windows
# windows-firewall-hardening.ps1
# Activer le firewall sur tous les profils
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
# Bloquer tous les ports entrants par défaut
New-NetFirewallRule -DisplayName "Block-All-Inbound" -Direction Inbound -Action Block -Enabled True
# Autoriser uniquement les ports nécessaires (whitelist)
$allowed_ports = @(80, 443) # Uniquement HTTP/HTTPS
foreach ($port in $allowed_ports) {
New-NetFirewallRule -DisplayName "Allow-Port-$port" -Direction Inbound -LocalPort $port -Protocol TCP -Action Allow
}
# Bloquer RDP depuis Internet
New-NetFirewallRule -DisplayName "Block-RDP-Internet" -Direction Inbound -LocalPort 3389 -Protocol TCP -RemoteAddress Internet -Action Block
# Bloquer SMB depuis Internet
New-NetFirewallRule -DisplayName "Block-SMB-Internet" -Direction Inbound -LocalPort 445 -Protocol TCP -RemoteAddress Internet -Action Block
# Bloquer MySQL depuis Internet
New-NetFirewallRule -DisplayName "Block-MySQL-Internet" -Direction Inbound -LocalPort 3306 -Protocol TCP -RemoteAddress Internet -Action Block
# Bloquer Redis depuis Internet
New-NetFirewallRule -DisplayName "Block-Redis-Internet" -Direction Inbound -LocalPort 6379 -Protocol TCP -RemoteAddress Internet -Action Block
# Bloquer SphinxQL depuis Internet
New-NetFirewallRule -DisplayName "Block-SphinxQL-Internet" -Direction Inbound -LocalPort 9306 -Protocol TCP -RemoteAddress Internet -Action Block
# Activer le logging
Set-NetFirewallProfile -Profile Domain,Public,Private -LogAllowed True -LogBlocked True -LogFileName "%systemroot%\system32\LogFiles\Firewall\pfirewall.log"
4. Hardening du serveur de pré-production
## Règles absolues pour un serveur de pré-prod
1. **IP dédiée** : Pas la même IP que la production
2. **Firewall strict** : Uniquement les ports nécessaires, whitelist IP
3. **Pas de favicon public** : Favicon différent de la production
4. **Pas de directory listing** : Apache/Nginx désactivé
5. **Pas de .env exposé** : Fichiers de config hors DocumentRoot
6. **VPN obligatoire** : Accès admin uniquement via VPN
7. **Pas de RDP/SMB exposés** : Uniquement via tunnel VPN
8. **Monitoring** : Alertes sur les scans de ports
9. **Canary tokens** : Fichiers pièges pour détecter l'accès
Checklist de validation
- Favicon unique par environnement (pas de hash identique)
- Firewall actif sur tous les profils (Domain/Public/Private)
- Uniquement ports 80/443 ouverts vers Internet
- RDP/SMB/MySQL/Redis/SphinxQL bloqués depuis Internet
- Directory listing désactivé
- .env et fichiers de config hors DocumentRoot
- Détection de scan de ports (fail2ban / IDS)
- VPN obligatoire pour l'accès admin
- Monitoring des accès aux fichiers sensibles
- Canary tokens dans les répertoires web
Références
- Archive Ygg : Phase 1 — Reconnaissance (YGGLeak)
- Shodan : https://www.shodan.io
- Nmap : https://nmap.org