Aller au contenu principal

Choix du noyau

Le noyau retenu est:

5.15.0-171-generic

Il est utilisé sur les deux VMs.

Pourquoi Ubuntu Desktop 22.04?

Ubuntu Desktop 22.04 apporte:

  • une famille de noyaux 5.15 disponible dans les dépôts Jammy
  • les paquets linux-image, linux-headers, linux-modules et linux-modules-extra
  • gcc-12, attendu par les headers Ubuntu Jammy
  • NetworkManager, utile pour configurer les interfaces par MAC
  • Firefox et une session graphique pour la page victime, le dashboard et la capture d'écran.

Ubuntu Server ou Debian pourraient fonctionner, mais demanderaient plus de configuration graphique et réseau pour peu de gain dans ce projet.

Pourquoi 5.15.0-171-generic?

Le projet dépend de détails internes du noyau:

  • symboles __x64_sys_getdents64, __x64_sys_getdents, __x64_sys_read, __x64_sys_openat, __x64_sys_statx et autres hooks déclarés
  • ftrace avec FTRACE_OPS_FL_IPMODIFY
  • lookup de symboles via kprobe et kallsyms_lookup_name
  • structures linux_dirent et linux_dirent64
  • sockets kernel
  • call_usermodehelper
  • chargement d'un module non signé dans une VM du projet.

Ces éléments ne sont pas des API applicatives stables. Un noyau peut compiler le module mais changer assez de détails pour casser le hook, le masquage ou la session réseau.

Pour comprendre précisément ce que chaque terme veut dire, garder ouverte la page Références techniques: ftrace, Kprobes et symboles, pt_regs, Sockets kernel et call_usermodehelper.

La version 5.15.0-171-generic est aussi antérieure au seuil utilisé par les scripts pour le scénario Copy Fail côté victime:

COPY_FAIL_FIXED_FROM="5.15.0-179.189"

Le script documente donc un noyau Jammy testé pour le module et compatible avec le scénario prévu.

Pourquoi aligner l'attaquant et la victime?

La victime charge le module, mais l'attaquant le compile. Pour éviter les erreurs vermagic, les deux VMs démarrent sur le même noyau.

Cela évite:

  • de mettre une chaîne de build complète sur la victime
  • de copier manuellement les headers victime
  • de faire un cross-build
  • de diagnostiquer des erreurs invalid module format pendant l'exécution du projet.

Paquets installés

Les scripts installent:

linux-image-5.15.0-171-generic
linux-headers-5.15.0-171-generic
linux-modules-5.15.0-171-generic
linux-modules-extra-5.15.0-171-generic # si disponible

Ils mettent ensuite en hold:

linux-generic
linux-image-generic
linux-headers-generic
linux-image-5.15.0-171-generic
linux-headers-5.15.0-171-generic
linux-modules-5.15.0-171-generic

Ils désactivent aussi les timers d'upgrade automatique pour éviter qu'un reboot démarre sur un noyau différent.

Comparaison rapide

NoyauIntérêtRisque pour ce projet
5.4ancien, documentéfin de support standard, APIs différentes
5.10LTS, prochemoins aligné avec Ubuntu Desktop 22.04
5.15.0-171noyau Jammy testéchoix retenu
5.15.0-181+Jammy plus récentscénario Copy Fail différent selon le seuil du script
6.xplus modernesymboles, ftrace, lockdown et APIs à revalider

Un noyau plus récent n'est pas impossible, mais il peut casser le projet pour des raisons techniques précises:

  • Les symboles __x64_sys_* ne sont pas une API stable. Selon la version et la configuration, un symbole peut être renommé, masqué, non traçable ou absent de la table visible par kallsyms.
  • La résolution par kprobe peut être refusée. Si register_kprobe() ne peut plus être posé sur kallsyms_lookup_name ou sur un syscall cible, wlkom_find_kernel_symbol() retourne 0 et les hooks ne s'installent pas.
  • ftrace doit accepter FTRACE_OPS_FL_IPMODIFY. Si le noyau interdit la modification de registers->ip, ou si la fonction cible n'est pas traçable, register_ftrace_function() ou ftrace_set_filter_ip() échoue.
  • Secure Boot ou le mode lockdown peuvent bloquer le chargement d'un module non signé, l'usage de kprobes ou certaines capacités de tracing. Dans ce cas, le module peut échouer avant même d'arriver à wlkom_start_module().
  • Les wrappers de syscalls et structures internes peuvent changer. Le code lit les arguments dans pt_regs et dépend des conventions __x64_sys_*. Une évolution côté noyau peut compiler avec les headers, mais ne plus donner le comportement attendu au runtime.
  • Le chargement peut devenir plus strict: signature obligatoire, vermagic incompatible, options de compilation différentes, ou politiques LSM plus restrictives.

Donc la vraie justification n'est pas seulement "il faut retester". Le problème est que le module s'appuie sur des points internes du noyau: résolution de symboles, kprobes, redirection ftrace, ABI syscall x86_64 et chargement de module. La compilation valide seulement que le code correspond aux headers. Elle ne prouve pas que les hooks seront atteignables et redirigeables dans le noyau en cours d'exécution.

Pour porter le projet sur un autre noyau, il faut au minimum vérifier:

  1. modinfo -F vermagic wlkom.ko face à uname -r
  2. résolution runtime de chaque symbole __x64_sys_*
  3. succès de ftrace_set_filter_ip() et register_ftrace_function()
  4. absence de blocage Secure Boot/lockdown
  5. comportement réel des hooks getdents, read, mmap et accès par chemin
  6. seulement ensuite, les fonctionnalités haut niveau: persistance, C2, transferts et screenshot.

Secure Boot et lockdown

Le projet suppose une VM où le chargement de module non signé et l'usage de ftrace/kprobes ne sont pas bloqués par Secure Boot ou lockdown. Sur une machine durcie, le module peut échouer avant même d'arriver à ses hooks.

Vérifications

Dans chaque VM:

uname -r

Attendu:

5.15.0-171-generic

Dans l'attaquant:

modinfo -F vermagic ~/wlkom-attacker/web_payloads/rootkit-demo/wlkom.ko

Le début doit correspondre à uname -r.

Pour les notions liées, voir Kbuild et vermagic, Syscalls, ftrace et Kprobes et symboles.