web-dev-qa-db-fra.com

Créez un processus ininterrompu dans Windows

Je suis un étudiant et je suis vraiment curieux de connaître les processus intemporels dans Windows.

À des fins éducatives, je voudrais créer une application (éventuellement en VB6?) Qui ne peut pas être résiliée par un utilisateur depuis le gestionnaire de tâches ou taskkill. Quelles sont les stratégies et les exploits que ces applications utilisent pour rendre cela possible?

41
user20825

Contrairement à ce que beaucoup de gens croient, il existe en fait plusieurs façons de procéder. Certains d'entre eux sont communs, d'autres rarement vus. Certains d'entre eux sont faibles, d'autres forts. Tout dépend de la façon dont vous le faites.

Passons en revue une collection d'entre eux:


1. Pré-NT RegisterServiceProcess astuce
Windows 9x, et d'autres systèmes d'exploitation antérieurs à NT, avaient une API non documentée dans kernel32.dll appelée RegisterServiceProcess, qui (comme son nom l'indique) enregistre le processus en tant que service système. Une fois qu'un processus avait appelé cette fonction, le système d'exploitation la considérait comme critique et ne permettait pas au gestionnaire de tâches de la tuer. Cette fonction a été supprimée lorsque NT est apparu, donc elle ne fonctionne pas sur XP ou supérieur.

2. Astuces de dénomination des processus
De retour dans WinXP, l'exécutable du Gestionnaire des tâches contenait une liste codée en dur de noms de processus qu'il refuserait de tuer, affichant à la place un message comme celui que vous avez mentionné. Ceux-ci couvraient essentiellement les services système critiques tels que smss.exe et rpcss.exe. Le problème était que le chemin n'était pas vérifié, donc tout autre exécutable avec le même nom entraînerait un processus irrécupérable. Cette astuce n'empêche pas le processus d'être tué, en soi, mais empêche plutôt le gestionnaire de tâches Windows XP de pouvoir tuer le processus. Il est toujours possible d'utiliser un autre outil pour tuer le processus.

3. Processus de maintien en vie
Ce sont de loin les plus courants. Deux processus sont créés et vérifient à plusieurs reprises l'existence de l'autre. Si l'un est tué, l'autre le ressuscite. Cela ne vous empêche pas vraiment de tuer le processus, mais cela rend ennuyeux d'empêcher le processus de revenir.

Le Gestionnaire des tâches inclut une option pour tuer l'arborescence des processus, qui vous permet de tuer un processus et tous les processus enfants, ce qui peut aider à résoudre ce problème. Lorsqu'un processus est créé dans Windows, le système d'exploitation conserve la trace de l'ID de processus qui l'a créé. L'arbre de processus Kill parcourt tous les processus et recherche ceux qui ont un ID parent égal à l'ID de processus que vous tuez. Étant donné que les processus persistants fonctionnent généralement sur une interrogation répétée, vous pouvez tuer les deux processus avant qu'ils ne remarquent un problème.

Une défense contre cela est de créer un processus fictif qui engendre le processus de maintien en vie, puis de quitter ce processus fictif. Le processus principal transmet son ID au processus factice et le processus factice transmet son ID au processus de maintien en vie, mais la chaîne est rompue à la fin du processus factice. Cela laisse à la fois le processus principal et le processus en vie, mais rend impossible l'utilisation de la fonction d'arborescence des processus de suppression du Gestionnaire des tâches. Au lieu de cela, vous devez écrire un script pour les tuer ou utiliser un outil qui vous permet de tuer plusieurs processus simultanément.

4. Hooks en mode utilisateur via des DLL chargées
Il est possible de injecter une DLL dans un processus en cours. En fait, Windows offre une fonctionnalité pour avoir n'importe quel DLL chargé dans tous les processus qui importent user32.dll, à des fins d'extensibilité. Cette méthode est appelée DLL AppInit. Une fois un DLL est injectée, elle peut manipuler la mémoire du processus. Il est alors possible d'écraser les valeurs de certains pointeurs de fonction de telle sorte que l'appel est redirigé vers une routine de stub, qui appelle ensuite la fonction cible. Cette routine de stub peut être utilisé pour filtrer ou manipuler les paramètres et renvoyer les valeurs d'un appel de fonction. Cette technique est appelée hooking, et elle peut être très puissante. Dans ce cas, il serait possible d'injecter un DLL dans les processus en cours d'exécution qui accrochent OpenProcess et TerminateProcess pour garantir qu'aucune application ne peut obtenir un descripteur de votre processus, ou y mettre fin. Cela se traduit quelque peu par un course aux armements, car des API alternatives en mode utilisateur peuvent être utilisées pour mettre fin aux processus, et il est difficile de les accrocher et de les bloquer toutes, surtout si l'on considère les API non documentées.

5. Crochets en mode utilisateur via des threads injectés
Cette astuce fonctionne de la même manière que pour les DLL, sauf qu'aucun DLL est nécessaire. Un descripteur du processus cible est créé, de la mémoire y est allouée via VirtualAllocEx, le code et les données sont copiés dans le bloc de mémoire via WriteProcessMemory, et un thread est créé dans le processus via CreateRemoteThread. Cela se traduit par l'exécution de code étranger dans un processus cible, qui peut alors déclencher divers crochets pour empêcher la mort d'un processus.

6. Crochets d'appel en mode noyau
Dans le noyau, il existe une structure spéciale appelée Table de répartition des services système (SSDT), qui mappe les ID de fonction des appels en mode utilisateur aux pointeurs de fonction vers les API du noyau. Ce tableau est utilisé pour la transition entre le mode utilisateur et le mode noyau. Si un pilote malveillant peut être chargé, il peut modifier le SSDT pour provoquer l'exécution de sa propre fonction, au lieu de l'API appropriée. Il s'agit d'un hook en mode noyau, qui constitue un rootkit. Il est essentiellement possible de tirer la laine sur les yeux du système d'exploitation en renvoyant de fausses données d'appels. En fait, il est possible de rendre le processus non seulement impossible à tuer, mais aussi invisible. Un problème avec cela sur les versions x64 est que le SSDT est protégé par Kernel Patch Protection (KPP). Il est possible de désactiver KPP, mais cela a des conséquences importantes qui peuvent rendre difficile le développement d'un rootkit.

7. Manipulation directe des objets du noyau (DKOM)
Cette astuce implique également le chargement d'un pilote malveillant sur le système d'exploitation, mais ne nécessite pas de modification du SSDT. Les processus sur le système sont stockés sous forme de structures EPROCESS dans le noyau. Gardez à l'esprit que cette structure dépend entièrement de la version et n'est que partiellement documentée par Microsoft, donc la rétro-ingénierie est requise sur plusieurs versions cibles afin de s'assurer que le code n'essaie pas de lire les mauvais pointeurs ou les mauvaises données. Cependant, si vous pouvez localiser et énumérer avec succès les structures EPROCESS dans le noyau, il est possible de les manipuler.

Chaque entrée de la liste des processus a un pointeur FLink et BLink, qui pointe vers les processus suivant et précédent dans la liste. Si vous identifiez votre processus cible et que ses pointeurs FLink et BLink pointent vers eux-mêmes, et que les FLink et BLink de ses frères et sœurs pointent l'un vers l'autre , l'OS saute simplement votre processus lorsque vous effectuez des opérations de nettoyage, processus de mise à mort. Cette astuce est appelée dissociation. Non seulement cela rend le processus invisible pour l'utilisateur, mais cela empêche également toutes les API en mode utilisateur de cibler le processus à moins qu'un descripteur du processus n'ait été généré avant qu'il ne soit dissocié. Il s'agit d'une technique de rootkit très puissante, en particulier parce qu'elle est difficile à récupérer.

8. Astuces du débogueur
C'est un truc assez cool que je n'ai pas encore vu dans la nature, mais ça marche assez bien. L'API de débogueur Windows permet à n'importe quel processus d'en déboguer un autre, tant qu'il dispose des autorisations nécessaires. Si vous utilisez l'API de débogage, il est possible de placer un processus dans un état "débogué". Si ce processus contient un thread qui est actuellement interrompu par un débogueur, le processus ne peut pas être supprimé par Windows, car le contrôle du thread approprié ne peut pas être garanti pendant la terminaison lorsque le thread est bloqué. Bien sûr, si vous tuez le débogueur, le processus cesse d'être débogué et se ferme ou se bloque. Cependant, il est parfois possible de produire une situation où il existe une chaîne de processus qui se déboguent en boucle. Si chaque processus arrête un fil factice dans le suivant, aucun ne peut être tué. Notez qu'il est possible pour un utilisateur expérimenté de tuer manuellement d'autres threads dans le processus, le rendant inutile, mais il ne sera toujours pas tué.

9. Windows 8 DRM
Ceci est un nouveau dont je n'ai entendu parler que récemment, mais je n'en sais pas grand-chose. Il y avait un peu de rumeur à ce sujet sur Twitter, et j'ai vu des extraits ici et là sur divers sites techniques, mais je n'ai pas encore vu de recherche concrète. Je pense que c'est encore tôt. Essentiellement, l'histoire est que Windows 8 dispose d'un mécanisme qui permet aux "fournisseurs de confiance" d'enregistrer les processus comme DRM critiques, les empêchant d'être tués ou manipulés par l'utilisateur. Certaines personnes ont émis l'hypothèse que le mécanisme de vérification des fournisseurs de confiance est faible et peut être ouvert aux attaques. <- On dirait que celui-ci était faux. Voilà pour le moulin à rumeurs!

Mise à jour: Harry Johnston a souligné dans les commentaires que Windows 8.1 introduit services protégés , qui sont conçus pour être utilisés par AV et DRM pour se protéger contre la manipulation ou l'attaque par du code moins privilégié sur le système.

10. Manipulation d'outils
Celui-ci a probablement été beaucoup utilisé dans la nature, mais je ne l'ai jamais vu correctement. Cette astuce consiste essentiellement à cibler des outils spécifiques, par exemple Gestionnaire des tâches, en modifiant les exécutables sur le disque d'une manière qui modifie les fonctionnalités. Ceci est très similaire aux astuces de hook en mode utilisateur que j'ai mentionnées plus tôt, mais dans ce cas, elles persistent sur le disque et ont des conséquences plus étendues que le simple hooking d'API. Bien sûr, un problème est que la protection des fichiers Windows (WFP) empêche l'altération de certains fichiers système critiques, y compris le gestionnaire de tâches. De manière amusante, cependant, il est possible de modifier le chemin exécutable du gestionnaire de tâches par défaut via le registre. Ainsi, au lieu de jouer avec le fichier exécutable du gestionnaire de tâches, videz simplement votre propre version quelque part et faites-la utiliser par le système d'exploitation.


Dans l'ensemble, il existe de nombreuses façons d'y parvenir, avec différents degrés de robustesse. Ce qui précède en représente la majorité, mais n'est pas exhaustif. En fait, bon nombre des astuces que j'ai décrites peuvent être réalisées de différentes manières, en utilisant différents mécanismes ou API pour atteindre le même objectif.

96
Polynomial

Je ne pense pas que ce que vous essayez de faire soit possible. Vous devrez subvertir le système d'exploitation pour empêcher qu'un processus puisse être tué. Tous les processus s'exécutent dans le système d'exploitation, par conséquent, le système d'exploitation peut tuer n'importe quel processus. Vous pouvez même tuer des processus comme "Explorer.exe" qui exécute le menu Démarrer et le bureau.

La plupart des programmes qui semblent "inéluctables" sont en fait tuables, mais un autre programme surveille leur exécution et lorsqu'il verra le processus se fermer, il sera automatiquement redémarré immédiatement. Lorsque vous tuez processA, processB le démarre et lorsque vous tuez processB, processA le démarre. Comme vous ne pouvez pas facilement tuer les deux processus exactement ensemble, il devient très difficile de s'en débarrasser pendant que le système fonctionne.

Cette même technique est utilisée par plusieurs fournisseurs d'antivirus ainsi que par le populaire programme anti-triche PunkBuster.

Il est également possible, sur des systèmes plus anciens, que le processus s'exécute en tant que service. Dans Windows XP et Windows 2000, le Gestionnaire des tâches n'est pas en mesure de tuer les processus qui ont été démarrés par le gestionnaire de services car le gestionnaire de services s'exécute dans un contexte utilisateur différent. Sur ces anciens systèmes, la création d'un Le service Windows serait résistant à la destruction directe avec le Gestionnaire des tâches, mais les nouvelles versions de Windows permettront de le tuer.

Il peut être utile de voir dans quel contexte le processus s'exécute si l'autorisation est refusée. Vous pouvez utiliser un outil comme Process Explorer de la suite SysInternal pour voir dans quel contexte utilisateur le processus s'exécute. Si le contexte utilisateur sous lequel le Gestionnaire des tâches s'exécute n'a pas accès aux processus d'arrêt sous le contexte utilisateur sous lequel le processus s'exécute, le processus d'arrêt échouera.

Des informations connexes sont disponibles sur le super utilisateur sous cette question https://superuser.com/questions/109010/kill-a-process-which-gives-access-denied . Il semble qu'il existe un paramètre de sécurité par processus qui peut être appliqué pour supprimer le droit de tuer. Cela pourrait être fait par programme et compliquerait sa mise à mort, mais un administrateur pourrait toujours s'approprier le processus, puis ajuster les autorisations pour permettre de le tuer. Les API Windows particulières sont CreateProcessWithTokenW et SetSecurityInfo.

8
AJ Henderson

Comme mentionné par AJ, l'OS est finalement en charge. Il décide si un processus peut être tué, quand il est tué, comment, etc. Certains processus peuvent être "protégés" par le système d'exploitation, ce qui les empêche d'être interrompus, ou comme c'est également le cas, le processus peut être techniquement tuable, mais l'arrêt du processus déclenche l'arrêt de toute la machine.

Si vous écriviez des logiciels malveillants et que vous vouliez rendre impossible la suppression d'un processus, le mieux serait de modifier le système d'exploitation pour l'empêcher. Ce n'est pas hors de question, et c'est en fait quelque chose que les auteurs ont déjà pensé. En fait, apporter des modifications au système d'exploitation pour protéger les ressources est un fil conducteur si commun qu'ils ont un nom: " rootkit ".

Alors, comment modifiez-vous le système d'exploitation en cours d'exécution? Heureusement, les systèmes d'exploitation modernes sont tous écrits pour vous permettre d'apporter de telles modifications; il suffit d'écrire un module du noyau (a.k.a. "driver"). Il y a même un kit de développement pour vous aider à démarrer.

Une fois que vous y êtes, accrochez simplement le chemin de code qui gère le contrôle de processus et insérez votre petite règle d'exclusion. Lisez les rootkits pour plus d'informations.

1
tylerl

Créer un processus vraiment impossible à tuer n'est pas une bonne idée. Il est cependant parfaitement possible de protéger un processus contre toute interruption par un autre utilisateur qu'un administrateur. Les administrateurs ont et devraient avoir un accès complet au processus et ils peuvent le tuer.

La façon de le faire est de modifier l'ACL du processus afin que le système d'exploitation refuse toute tentative de tuer le processus par des non-administrateurs.

Dans votre code de démarrage de processus, vous devez obtenir le processus DACL, y ajouter une restriction afin que "Tout le monde" obtienne un "Accès refusé" lorsque vous essayez de tuer le processus, puis réécrire le processus DACL.

Je pourrais vous fournir le code source .NET sur la façon de le faire, si vous êtes intéressé.

1
Evert

Une chose qui a été négligée ici est le concept (ab) utilisant la virtualisation pour implémenter un hyperviseur au-dessus des fenêtres contenant votre code.

Comme votre code s'exécute ensuite à l'extérieur et au-dessus des fenêtres, il n'est pas facilement détectable et ne peut pas être interrompu par Windows.

" Blue Pill " était une preuve de concept d'un tel concept, mais après quelques histoires initiales, une telle implémentation est très rarement mentionnée et personnellement, je n'ai pas encore vu une telle chose dans la nature.

1
braindigitalis