Aller au contenu principal

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 base64 absente.

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:

  • tar absent
  • 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:

  1. capturer le TCP port 4444
  2. copier le payload hex ou base64
  3. ouvrir la vue Decrypt
  4. saisir le mot de passe
  5. 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