
Injecter une bibliothèque partagée (c'est-à-dire du code arbitraire) dans un processus linux en cours d'exécution, sans ptrace
Injecter une bibliothèque partagée (c'est-à-dire du code arbitraire) dans un processus Linux en cours d'exécution, sans ptrace. Inspiré par Cexigua et linux-inject, entre autres.
.___.__ .__ __ __
__| _/| | |__| ____ |__| ____ _____/ |_ ______ ___.__.
/ __ | | | | |/ \ | |/ __ \_/ ___\ __\ \____ < | |
/ /_/ | | |_| | | \ | \ ___/\ \___| | | |_> >___ |
\____ | |____/__|___| /\__| |\___ >\___ >__| /\| __// ____|
\/ \/\______| \/ \/ \/|__| \/
source : https://github.com/DavidBuchanan314/dlinject
usage: dlinject.py [-h] [--stopmethod {sigstop,cgroup_freeze,none}]
pid /path/to/lib.so
Injecter une bibliothèque partagée dans un processus en cours d'exécution.
arguments positionnels :
pid Le pid du processus cible
/path/to/lib.so Chemin de la bibliothèque partagée à charger (remarque : doit être
relatif au répertoire de travail du processus cible, ou absolu)
arguments optionnels :
-h, --help afficher ce message d'aide et quitter
--stopmethod {sigstop,cgroup_freeze,none}
Comment arrêter le processus cible avant l'injection
de shellcode. SIGSTOP (par défaut) peut avoir des effets secondaires.
cgroup freeze nécessite les droits root. 'none' risque de provoquer
des conditions de concurrence.
Parce que je le peux.
Il existe diverses techniques anti-ptrace, que cet outil contourne en n'utilisant tout simplement pas ptrace.
Je n'aime pas ptrace.
Utiliser LD_PRELOAD peut parfois être délicat ou impossible, si le processus que vous voulez injecter est créé par un autre processus avec un environnement propre.
Envoyer le signal d'arrêt au processus cible. (optionnel)
Localiser le symbole _dl_open().
Récupérer RIP et RSP via /proc/[pid]/syscall.
Faire une sauvegarde d'une partie de la pile et du code que nous allons écraser avec notre shellcode, en lisant depuis /proc/[pid]/mem.
Générer des tampons de shellcode primaire et secondaire.
Insérer le shellcode primaire à RIP, en écrivant dans /proc/[pid]/mem.
Le shellcode primaire :
mmap().Le shellcode secondaire :
_dl_open() pour charger la bibliothèque spécifiée par l'utilisateur. Les constructeurs seront exécutés au chargement, comme d'habitude.Envoyer SIGSTOP peut provoquer des effets secondaires indésirables, par exemple si un autre thread attend sur waitpid(). L'option --stopmethod=cgroup_freeze évite cela, mais nécessite les droits root (sur la plupart des distributions, au moins).
Je ne suis pas entièrement sûr de la façon dont cela interagira avec des applications multithread complexes. Il y a certainement un risque de dysfonctionnement.
Linux x86-64 uniquement (pour l'instant - un support 32 bits pourrait potentiellement être ajouté).
Nécessite les droits root, ou une configuration YAMA assouplie (echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope est utile pour les tests).
Si le processus cible est en bac à sable (par exemple, des filtres seccomp), il pourrait ne pas avoir la permission de mmap() le shellcode de second étage, ou de dlopen() la bibliothèque.
SIGSTOP