[LINUX] Auto-protection du noyau (1/2)

À l'origine, il fait partie du code source du noyau Linux, il sera donc traité comme GPLv2 (reconnaissance qu'il devrait l'être).

https://www.kernel.org/doc/html/latest/index.html

Licensing documentation

The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.

https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

https://www.kernel.org/doc/html/latest/security/self-protection.html

Kernel Self-Protection

Kernel self-protection is the design and implementation of systems and structures within the Linux kernel to protect against security flaws in the kernel itself.

L'autoprotection du noyau est conçue et mise en œuvre avec un système et une structure pour se protéger contre les failles de sécurité dans le noyau Linux lui-même.

This covers a wide range of issues, including removing entire classes of bugs, blocking security flaw exploitation methods, and actively detecting attack attempts.

Il couvre un large éventail de questions. Éliminer toute la classe de bogues, bloquer les moyens d'exploiter les failles de sécurité, détecter les tentatives d'attaques agressives, etc.

Not all topics are explored in this document, but it should serve as a reasonable starting point and answer any frequently asked questions. (Patches welcome, of course!)

Ce document ne divulgue pas tous les sujets, mais il peut être un bon point de départ ou pour certaines questions fréquemment posées (les correctifs sont les bienvenus, bien sûr!).

.

In the worst-case scenario, we assume an unprivileged local attacker has arbitrary read and write access to the kernel’s memory.

Dans le pire des cas, on suppose qu'une vue d'encens locale non autorisée dispose d'autorisations de lecture / écriture arbitraires sur la mémoire du noyau.

In many cases, bugs being exploited will not provide this level of access, but with systems in place that defend against the worst case we’ll cover the more limited cases as well.

Dans de nombreux cas, même les bogues abusés ne permettent pas d'accéder à ce niveau. Cependant, un système qui peut éviter le pire des cas peut couvrir des cas encore plus limités.

A higher bar, and one that should still be kept in mind, is protecting the kernel against a privileged local attacker, since the root user has access to a vastly increased attack surface.

Pour garder cette idée à l'esprit, un niveau supérieur consiste à protéger le noyau des attaquants locaux «privilégiés». En tant qu'utilisateur root, vous avez accès à une zone d'attaque considérablement accrue.

(Especially when they have the ability to load arbitrary kernel modules.)

(Surtout s'ils peuvent charger n'importe quel module du noyau).

The goals for successful self-protection systems would be that they are effective, on by default, require no opt-in by developers, have no performance impact, do not impede kernel debugging, and have tests.

L'objectif de réussite des systèmes d'autoprotection est de pouvoir tester efficacement, dans l'état par défaut, sans demander au développeur, sans affecter les performances, ce qui nuirait au débogage et aux tests. ..

It is uncommon that all these goals can be met, but it is worth explicitly mentioning them, since these aspects need to be explored, dealt with, and/or accepted.

Il n'est pas courant d'atteindre tous ces objectifs, mais cela vaut la peine de le mentionner. L'enquête doit être menée ou acceptée.

Attack Surface Reduction

The most fundamental defense against security exploits is to reduce the areas of the kernel that can be used to redirect execution.

La protection la plus élémentaire contre les abus de sécurité est de réduire la zone du noyau disponible pour l'exécution de la redirection.

This ranges from limiting the exposed APIs available to userspace, making in-kernel APIs hard to use incorrectly, minimizing the areas of writable kernel memory, etc.

Cela inclut la limitation des API exposées disponibles dans l'espace utilisateur, ce qui rend plus difficile l'utilisation accidentelle d'API dans le noyau, la minimisation de la quantité de mémoire du noyau inscriptible, et bien plus encore. ..

Strict kernel memory permissions

When all of kernel memory is writable, it becomes trivial for attacks to redirect execution flow.

Si toutes les mémoires du noyau sont accessibles en écriture, il sera plus facile pour un attaquant de rediriger le flux d'exécution.

To reduce the availability of these targets the kernel needs to protect its memory with a tight set of permissions.

Pour réduire ce potentiel, le noyau doit protéger sa mémoire avec des autorisations strictes.

Executable code and read-only data must not be writable

Any areas of the kernel with executable memory must not be writable.

Les zones du noyau avec la mémoire exécutable ne doivent pas être inscriptibles.

While this obviously includes the kernel text itself, we must consider all additional places too: kernel modules, JIT memory, etc.

Cela inclut évidemment le texte du noyau lui-même, mais vous devez également prendre en compte tout l'espace supplémentaire. module noyau, mémoire JIT, etc.

(There are temporary exceptions to this rule to support things like instruction alternatives, breakpoints, kprobes, etc.

(Il existe des exceptions à cette règle, principalement pour prendre en charge les instructions, les points d'arrêt, les kproves, etc.

If these must exist in a kernel, they are implemented in a way where the memory is temporarily made writable during the update, and then returned to the original permissions.)

Si ceux-ci sont requis pour le noyau, la mémoire sera temporairement inscriptible pendant la mise à jour et sera implémentée pour revenir aux autorisations d'origine une fois qu'elle sera terminée. )

In support of this are CONFIG_STRICT_KERNEL_RWX and CONFIG_STRICT_MODULE_RWX, which seek to make sure that code is not writable, data is not executable, and read-only data is neither writable nor executable.

Pour supporter cela, il existe CONFIG_STRICT_KERNEL_RWX et CONFIG_STRICT_MODULE_RWX. Celles-ci garantissent que le code n'est pas inscriptible, que les données sont irréalisables et que les données qui ne peuvent être lues que ne peuvent pas être écrites ou exécutées.

.

Most architectures have these options on by default and not user selectable.

Sur de nombreuses architectures, ces options sont activées par défaut et ne peuvent pas être sélectionnées par l'utilisateur.

For some architectures like arm that wish to have these be selectable, the architecture Kconfig can select ARCH_OPTIONAL_KERNEL_RWX to enable a Kconfig prompt.

Pour certaines architectures, comme le bras, vous pouvez choisir selon vos souhaits. architecure Kconfig vous permet d'activer ARCH_OPTIONAL_KERNEL_RWX avec l'invite Kconfig.

CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT determines the default setting when ARCH_OPTIONAL_KERNEL_RWX is enabled.

Détermine CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT lorsque CONFIG_ARCH_OPTIONAL_KERNEL_RWX est en vigueur. .

Function pointers and sensitive variables must not be writable

Vast areas of kernel memory contain function pointers that are looked up by the kernel and used to continue execution

Une grande partie de la mémoire du noyau contient des pointeurs de noyau qui sont récupérés par le noyau et utilisés pour continuer l'exécution.

(e.g. descriptor/vector tables, file/network/etc operation structures, etc).

(Par exemple, des tables de descripteurs / vecteurs, des structures d'opération fichier / réseau / etc, etc.)

The number of these variables must be reduced to an absolute minimum.

Le nombre de ces variables doit être réduit au minimum absolu.

.

Many such variables can be made read-only by setting them “const” so that they live in the .rodata section instead of the .data section of the kernel, gaining the protection of the kernel’s strict memory permissions as described above.

Beaucoup de ces variables peuvent être en lecture seule en définissant const. Cela le placera dans la section .rodata au lieu de la section .data du noyau. Protégé par les autorisations de mémoire strictes du noyau.

.

For variables that are initialized once at __init time, these can be marked with the (new and under development) __ro_after_init attribute.

Pour les variables initialisées une fois pendant __init, celles-ci peuvent être marquées par l'attribut __ro_after_init (si elles sont nouvelles ou en cours de développement).

.

What remains are variables that are updated rarely (e.g. GDT).

Il ne reste que des variables rarement mises à jour (par exemple, GDT).

These will need another infrastructure (similar to the temporary exceptions made to kernel code mentioned above) that allow them to spend the rest of their lifetime read-only.

Celles-ci nécessitent un autre mécanisme pour les rendre disponibles en lecture seule pendant leur durée de vie. (Similaire à l'exception temporaire dans le code du noyau ci-dessus).

(For example, when being updated, only the CPU thread performing the update would be given uninterruptible write access to the memory.)

(Par exemple, au moment de la mise à jour, le thread du processeur reçoit une autorisation d'écriture ininterrompue dans la mémoire).

Segregation of kernel memory from userspace memory

The kernel must never execute userspace memory.

Le noyau ne doit pas exécuter la mémoire de l'espace utilisateur.

The kernel must also never access userspace memory without explicit expectation to do so.

Le noyau ne doit pas non plus accéder à la mémoire de l'espace utilisateur sans attente explicite.

These rules can be enforced either by support of hardware-based restrictions (x86’s SMEP/SMAP, ARM’s PXN/PAN) or via emulation (ARM’s Memory Domains).

Cette règle est appliquée par un mécanisme basé sur le matériel (SMEP / SMAP pour x86, PXN / PAN pour ARM). Également, émulation (domaines de mémoire pour ARM).

By blocking userspace memory in this way, execution and data parsing cannot be passed to trivially-controlled userspace memory, forcing attacks to operate entirely in kernel memory.

Cela bloque la mémoire de l'espace utilisateur, ce qui rend impossible le passage de la mémoire de l'espace utilisateur facilement contrôlable en tant qu'exécution ou données, ce qui rend impossible l'attaque dans la mémoire du noyau.

Reduced access to syscalls

One trivial way to eliminate many syscalls for 64-bit systems is building without CONFIG_COMPAT. However, this is rarely a feasible scenario.

Un moyen simple de désactiver de nombreux appels système sur un système 64 bits consiste à créer sans CONFIG_COMPAT. Cependant, il s'agit d'un scénario rarement réaliste.

.

The “seccomp” system provides an opt-in feature made available to userspace, which provides a way to reduce the number of kernel entry points available to a running process.

Le système «seccom» fournit une fonction opt-in qui permet de libérer de l'espace utilisateur. Cela permet de réduire le nombre de points d'entrée du noyau pour l'exécution des processus.

This limits the breadth of kernel code that can be reached, possibly reducing the availability of a given bug to an attack.

Cela peut limiter la plage accessible du code du noyau et réduire l'utilité des bogues donnés lors des attaques.

.

An area of improvement would be creating viable ways to keep access to things like compat, user namespaces, BPF creation, and perf limited only to trusted processes.

La zone améliorée fournit un moyen de continuer à permettre l'accès à des éléments tels que la compatibilité, la création d'espaces de noms d'utilisateurs BPF, les performances de processus fiables.

This would keep the scope of kernel entry points restricted to the more regular set of normally available to unprivileged userspace.

Cela limite également la portée du point d'entrée du noyau à l'ensemble standard normalement disponible pour les espaces utilisateurs non autorisés.

Restricting access to kernel modules

The kernel should never allow an unprivileged user the ability to load specific kernel modules, since that would provide a facility to unexpectedly extend the available attack surface.

Le noyau ne doit pas autoriser les utilisateurs non autorisés à charger des modules de noyau spécifiques. Cela offre la possibilité d'étendre l'efficacité des aspects attaquables que vous n'avez jamais imaginés.

(The on-demand loading of modules via their predefined subsystems, e.g. MODULE_ALIAS_*, is considered “expected” here, though additional consideration should be given even to these.)

(Les modules qui spécifient "MODULE_ALIAS_ *" et sont chargés selon les besoins sont les sous-systèmes précédemment attendus, qui nécessitent également une considération supplémentaire.)

For example, loading a filesystem module via an unprivileged socket API is nonsense: only the root or physically local user should trigger filesystem module loading.

Par exemple, il n'a pas de sens d'appeler le module du système de fichiers tout en regardant une API socket non autorisée. Seuls les utilisateurs root ou physiquement locaux devraient pouvoir charger le module du système de fichiers.

(And even this can be up for debate in some scenarios.)

Et il est possible de discuter de certains scénarios.

.

To protect against even privileged users, systems may need to either disable module loading entirely (e.g. monolithic kernel builds or modules_disabled sysctl), or provide signed modules (e.g. CONFIG_MODULE_SIG_FORCE, or dm-crypt with LoadPin), to keep from having root load arbitrary kernel code via the module loader interface.

Le système peut avoir besoin de désactiver complètement le chargement du module (construit comme un noyau monolithique ou modules_disable sysctl) pour le protéger également des utilisateurs privilégiés. Sinon, vous devez utiliser un module signé (CONFIG_MODULE_SIG_FORCE et dm-crypt avec LoadPing). Cela empêche root de charger le code du noyau via n'importe quelle interface de chargeur de module.

Memory integrity

There are many memory structures in the kernel that are regularly abused to gain execution control during an attack,

Le noyau a une structure de mémoire couramment utilisée pour obtenir le contrôle de l'exécution lors d'une attaque.

By far the most commonly understood is that of the stack buffer overflow in which the return address stored on the stack is overwritten.

Le plus couramment compris jusqu'à présent est un débordement de la mémoire tampon de la pile, qui écrase l'adresse de retour stockée sur la pile.

Many other examples of this kind of attack exist, and protections exist to defend against them.

Il existe de nombreux autres exemples de ce type d'attaque, et il existe des protections pour les protéger.

Stack buffer overflow

The classic stack buffer overflow involves writing past the expected end of a variable stored on the stack, ultimately writing a controlled value to the stack frame’s stored return address.

Dans le débordement de tampon de pile classique, en écrivant au-delà de la fin du vendeur yukata de la variable contenue dans la pile, il essaie finalement d'écrire l'adresse contrôlée dans l'adresse de retour stockée dans la trame de pile.

The most widely used defense is the presence of a stack canary between the stack variables and the return address (CONFIG_STACKPROTECTOR), which is verified just before the function returns.

La défense la plus largement utilisée est de fournir un canari de pile entre la variable de pile et l'adresse de retour (CONFIG_STACKPROTECTOR). Ceci est confirmé juste avant le retour de la fonction.

Other defenses include things like shadow stacks.

Une autre sauvegarde consiste à inclure une pile d'ombre.

Stack depth overflow

A less well understood attack is using a bug that triggers the kernel to consume stack memory with deep function calls or large stack allocations.

Une attaque moins connue est l'utilisation de bogues qui poussent le noyau à consommer de la mémoire de la pile via des appels de fonction profonds ou des allocations de pile énormes.

With this attack it is possible to write beyond the end of the kernel’s preallocated stack space and into sensitive structures.

Cette attaque permet d'écrire dans une structure sensible au-delà de la fin de l'espace de pile réservé par le noyau.

Two important changes need to be made for better protections: moving the sensitive thread_info structure elsewhere, and adding a faulting memory hole at the bottom of the stack to catch these overflows.

Deux modifications sont nécessaires pour une meilleure protection. Déplacement de la structure sensible thread_info vers un autre emplacement et ajout d'un trou de mémoire sous la pile en cas d'échec de capture du débordement.

Heap memory integrity

The structures used to track heap free lists can be sanity-checked during allocation and freeing to make sure they aren’t being used to manipulate other memory areas.

L'intégrité de la structure qui assure le suivi des listes libres de tas peut être vérifiée lors de l'allocation et de la publication pour vérifier qu'elle n'est pas utilisée par d'autres opérations de la zone de mémoire.

Counter integrity

Many places in the kernel use atomic counters to track object references or perform similar lifetime management.

Dans de nombreuses parties du noyau, les compteurs atomiques sont utilisés pour suivre les références d'objets et effectuer la gestion de la durée de vie.

When these counters can be made to wrap (over or under) this traditionally exposes a use-after-free flaw.

Lorsque ce compteur s'enroule (excessivement ou sous-dimensionné), il a longtemps causé un défaut d'utilisation après utilisation.

By trapping atomic wrapping, this class of bug vanishes.

En piégeant le wrapping atomique, ce genre de bogue disparaît.

Size calculation overflow detection

Similar to counter overflow, integer overflows (usually size calculations) need to be detected at runtime to kill this class of bug, which traditionally leads to being able to write past the end of kernel buffers.

Semblable au débordement de compteur, un débordement d'entier (généralement le calcul de la taille) doit être détecté au moment de l'exécution pour supprimer ce type de bogue. Traditionnellement, vous pouvez écrire au-delà de la fin du tampon du noyau.

Continuez vers la seconde moitié ...

C'est trop long, donc le reste est la seconde mi-temps.

Recommended Posts

Auto-protection du noyau (1/2)
Auto-protection du noyau (2/2)
k-means et kernel k-means
Mode noyau NEON
SVM du noyau (make_circles)