Troubleshooting
Cette page cible les pannes probables pendant l'installation ou l'exécution du projet.
Pour les mots kernel dans les messages d'erreur (vermagic, ftrace, kprobe, EACCES, EMSGSIZE), voir Références techniques.
La VM est très lente
Vérifier KVM sur le host:
ls -l /dev/kvm
grep -Ec '(vmx|svm)' /proc/cpuinfo
groups
Si l'utilisateur n'est pas dans le groupe kvm:
sudo usermod -aG kvm "$USER"
Se déconnecter puis se reconnecter.
Le serveur de fichiers host est inaccessible
Dans la VM:
curl -I http://10.0.2.2:8000/setup-attacker.sh
ip route
Sur le host:
./scripts/serve-host.sh
Vérifier l'archive:
ls -lh served/wlkom-src.tar.gz
Si elle manque:
./utils/package-served.sh
Le bridge ou les TAP manquent
Sur le host:
ip addr show br-wlkom
ip link show tap-attacker
ip link show tap-victim
Réparer:
./utils/clean-network.sh
./scripts/host-setup.sh --no-start
La VM n'a pas la bonne IP
Dans la VM:
nmcli connection show
ip -brief addr
Relancer le setup correspondant:
wget -qO- http://10.0.2.2:8000/setup-attacker.sh | bash
ou:
wget -qO- http://10.0.2.2:8000/setup-victim.sh | bash
Attendu:
attaquant: 192.168.100.1
victime: 192.168.100.2
La VM n'est pas sur 5.15.0-171-generic
uname -r
Si la sortie est différente:
wget -qO- http://10.0.2.2:8000/setup-victim.sh | bash
sudo reboot
ou côté attaquant:
wget -qO- http://10.0.2.2:8000/setup-attacker.sh | bash
sudo reboot
Si GRUB ne sélectionne pas le bon noyau:
Advanced options for Ubuntu > Ubuntu, with Linux 5.15.0-171-generic
Le build du module échoue
Dans l'attaquant:
uname -r
ls -ld /lib/modules/$(uname -r)/build
gcc --version
gcc-12 --version
make --version
Relancer:
wget -qO- http://10.0.2.2:8000/setup-attacker.sh | bash
Puis:
~/build-demo-rootkit.sh
insmod retourne invalid module format
Comparer victime et payload.
Victime:
uname -r
Attaquant:
modinfo -F vermagic ~/wlkom-attacker/web_payloads/rootkit-demo/wlkom.ko
Les versions doivent commencer pareil.
Lire les logs victime:
sudo dmesg | tail -50
Si le payload est vieux:
~/build-demo-rootkit.sh
Puis relancer freecloude.py côté victime.
insmod échoue avec les hooks
Symptômes possibles dans dmesg:
cannot resolve syscall symbol
ftrace_set_filter_ip failed
register_ftrace_function failed
refusing to load without syscall hooks
Causes probables:
- mauvais noyau
- Secure Boot/lockdown
- symboles
__x64_sys_*indisponibles - ftrace désactivé ou incompatible.
Le code refuse de charger si les hooks ne s'installent pas. C'est normal: sans hooks, le module aurait le canal réseau mais pas le masquage attendu.
Vérifier:
uname -r
sudo dmesg | grep -i wlkom | tail -80
cat /sys/kernel/security/lockdown 2>/dev/null || true
La résolution la plus simple dans ce projet est de revenir au noyau cible et à la configuration VM prévue.
Le dashboard ne s'ouvre pas
Dans l'attaquant:
~/start-attacker-panel.sh
curl -fsS http://192.168.100.1:8080/api/rootkit/status
Si le port est occupé:
~/kill-attacker-panel.sh
~/start-attacker-panel.sh
Vérifier:
ss -lntp | grep -E ':8080|:4444'
La victime ne voit pas la page victime
Dans la victime:
curl -I http://192.168.100.1:8080/freecloude
curl -I http://192.168.100.1:8080/payload/freecloude.py
curl -I http://192.168.100.1:8080/payload/freecloude.sh
curl -I http://192.168.100.1:8080/payload/rootkit-demo/wlkom.ko
Si connection refused, démarrer le panel attaquant.
Si No route to host, vérifier les IPs du projet.
Le loader victime refuse le module
Le parcours victime démarre par freecloude.py, puis l'installation réelle est faite par freecloude.sh. Le .sh vérifie vermagic avant la persistance.
Victime:
uname -r
Attaquant:
modinfo -F vermagic ~/wlkom-attacker/web_payloads/rootkit-demo/wlkom.ko
Si les versions divergent:
~/build-demo-rootkit.sh
Puis retélécharger et relancer freecloude.py.
Le dashboard reste en attente
Dans l'attaquant:
curl -fsS http://192.168.100.1:8080/api/rootkit/status
ss -lntp | grep 4444
Dans la victime:
sudo dmesg | grep -i wlkom | tail -60
ip route
Si le module loggue des retries, le listener n'est probablement pas disponible:
~/kill-attacker-panel.sh
~/start-attacker-panel.sh
Si detected=true et needs_password=true, le module est connecté: il faut authentifier dans le dashboard.
Le mot de passe est refusé
Le mot de passe doit être exactement celui saisi dans l'installeur freecloude.sh, lancé par freecloude.py.
Vérifier:
- pas d'espace au début ou à la fin
- caractères dans
[A-Za-z0-9._-] - pas d'ancien module déjà actif avec un ancien secret.
Si un ancien module est actif:
sudo reboot
Puis relancer le panel et authentifier avec le mot de passe persistant courant.
Les commandes échouent
Tester:
whoami
id
pwd
echo test
Si seule une commande complexe échoue, regarder l'exit code. Le module exécute via:
/bin/sh -c
Les règles de quoting sont donc celles du shell.
Si la sortie est énorme, elle peut dépasser:
MAX_RESPONSE_BYTES = 6 MiB
WLKOM_TX_SIZE = 4 MiB
Le module tronque aussi sa réponse si elle approche WLKOM_TX_SIZE, puis ajoute [output truncated].
Upload échoue
Le backend chunk l'upload, mais chaque commande doit tenir dans:
WLKOM_RX_SIZE = 160 KiB
UPLOAD_BASE64_CHUNK_SIZE = 120 KiB
WLKOM_USERMODE_SHELL_COMMAND_MAX = 128 KiB
Causes possibles:
- chemin distant trop long
- fichier lu mais chunk impossible à faire tenir dans la commande texte
- destination non écrivable
- commande userland
base64absente.
Tester une destination simple:
/opt/wlkom_data/test.bin
Si même ce chemin échoue, tester une commande simple dans le terminal du dashboard:
command -v base64 && touch /opt/wlkom_data/test-write
Download fichier échoue
Le backend utilise le mode chunké pour tous les downloads fichier. Il commence par lire la taille distante avec stat, puis demande des blocs download-chunk.
Vérifier côté shell:
stat -c '%s' <path>
dd if=<path> bs=1 skip=0 count=262144 2>/dev/null | base64 -w0 | head -c 80
Si le fichier est énorme, tester d'abord un petit fichier comme /etc/hostname.
Download dossier échoue
Le download dossier crée d'abord une archive distante:
/opt/wlkom_data/.download-dir.tar.gz
Puis il télécharge cette archive avec le download fichier chunké. Les causes probables sont donc:
tarabsent- dossier trop gros pour l'espace disque temporaire
- échec du download de l'archive
- nettoyage de l'archive impossible.
Tester d'abord avec un petit dossier.
Screenshot échoue
Dans la victime:
command -v gnome-screenshot
command -v scrot
command -v import
command -v xwd
command -v convert
loginctl list-sessions
echo "$DISPLAY"
La capture dépend de la session graphique active, de X11/Wayland et des permissions. gnome-screenshot est installé par setup-victim.sh, mais l'environnement graphique peut quand même bloquer la capture.
Le trafic Wireshark semble illisible
C'est attendu: le canal est chiffré par XOR/FNV-1a.
Pour vérifier:
- capturer le TCP port
4444 - copier le payload hex ou base64
- ouvrir la vue Decrypt
- saisir le mot de passe
- choisir RX, TX ou offset manuel selon le sens.
Si la sortie est illisible, l'offset n'est probablement pas le bon.
Rappel: si la socket a reconnecté, les offsets repartent à zéro côté module et backend. Une capture prise au milieu d'une ancienne session ne se déchiffre pas avec les offsets d'une nouvelle session.
Nettoyer la victime
bash ~/uninstall.sh
Sans reboot automatique:
bash ~/uninstall.sh --no-reboot
Pour viser explicitement un arbre kernel:
bash ~/uninstall.sh --kernel 5.15.0-171-generic
Le redémarrage automatique est volontaire. Quand wlkom tourne déjà, ses hooks peuvent refuser la suppression de /lib/modules/.../wlkom.ko ou cacher des chemins. Le désinstallateur installe donc un service one-shot zz-lab-clean.service qui s'exécute au boot suivant avant systemd-modules-load.service, nettoie la persistance, puis se supprime.
Vérifier après reboot:
test ! -e /etc/modules-load.d/wlkom.conf && echo OK modules-load
test ! -e /etc/modprobe.d/wlkom.conf && echo OK modprobe
test ! -e /lib/modules/$(uname -r)/kernel/drivers/wlkom.ko && echo OK module
test ! -d /sys/module/wlkom && echo OK not-loaded
sudo tail -80 /var/log/zz-lab-clean.log 2>/dev/null || true
Nettoyer l'attaquant
~/kill-attacker-panel.sh
Vérifier:
ss -lntp | grep -E ':8080|:4444' || echo OK