Cours de sécurité informatique expliquant comment détourner le fonctionnement normal d'un programme, en environnement Unix / Linux, à l'aide de LD_PRELOAD.
[...] Détourner le fonctionnement normal d'un programme sous Unix / Linux. Sommaire : Introduction I Notion de “statique” et de “dynamique”. II La variable d'environnement LD_PRELOAD. III Pour aller plus loin - Une autre manière de trouver le mot de passe - Faire croire que vous êtes root. Introduction. Pour détourner le comportement normal d'un programme en environnement Unix, il convient d'abord de bien comprendre les bases son fonctionnement. Prenons en exemple un programme simple, écrit en C : vim hello_world.c cat hello_world.c #include int main(void) { puts(“Hello world return } Nous allons ensuite le compiler, puis l'exécuter. [...]
[...] Procédons maintenant comme si nous n'avions jamais vu le code source de ce programme. Nous allons tout d'abord regarder la liste des symboles qu'il utilise, en prêtant particulièrement attention aux symboles de type “unknown” marqués d'un avec la commande nm password 08049f20 d _DYNAMIC 08049ff4 d _GLOBAL_OFFSET_TABLE_ 080485c4 R _IO_stdin_used w _Jv_RegisterClasses 0804a020 A __bss_start 0804a014 D __data_start 0804a018 D __dso_handle w __gmon_start__ 08048567 T __i686.get_pc_thunk.bx 08049f0c d __init_array_end 08049f0c d __init_array_start 080484f0 T __libc_csu_fini 08048500 T __libc_csu_init U __libc_start_main@@GLIBC_ 2.0 0804a020 A _edata 0804a028 A _end 080485a4 T _fini 080485c0 R _fp_hw 08048328 T _init 080483a0 T _start 0804a014 W data_start U fprintf@@GLIBC_ T main U puts@@GLIBC_ 2.0 0804a020 B stderr@@GLIBC_ 2.0 U strcmp@@GLIBC_ 2.0 Nous savons maintenant deux choses importantes. [...]
[...] Pour cela, nous allons utiliser qui va nous lister les symboles de notre programme. nm hello_world 08049f20 d _DYNAMIC 08049ff4 d _GLOBAL_OFFSET_TABLE_ 080484c4 R _IO_stdin_used w _Jv_RegisterClasses 0804a018 A __bss_start 0804a00c D __data_start 0804a010 D __dso_handle w __gmon_start__ 08048467 T __i686.get_pc_thunk.bx 08049f0c d __init_array_end 08049f0c d __init_array_start 080483f0 T __libc_csu_fini 08048400 T __libc_csu_init U __libc_start_main@@GLIBC_ 2.0 0804a018 A _edata 0804a01c A _end 080484a4 T _fini 080484c0 R _fp_hw 080482b4 T _init 08048310 T _start 0804a00c W data_start 080483b4 T main U puts@@GLIBC_ 2.0 Vous pouvez le voir tout en bas, le symbole de la fonction que nous utilisons est bien là. [...]
[...] Tout fonctionne exactement comme avant, à première vue, aucune différence. Mais regardons tout cela de plus prêt. ldd hello_world_static not a dynamic executable du hello_world 8.0 K hello_world du hello_world_static 536K hello_world_static Le binaire “hello_world_static” n'a pas de dépendances de libraires et il pèse 67 fois plus (536Ko contre 8Ko) que son camarade dynamique “hello_world”. En effet, la compilation statique va embarquer l'intégralité des librairies dont il aurait été dépendant à l'intérieur du binaire, ce qui décuple son poids. Il est à noter que la notion statique / dynamique est aussi valable pour les librairies. [...]
[...] Cette libraire va contenir une fonction et sera appelée à la place de la fonction originale ! Ecrivons le bout de code nécessaire à cette manipulation, en prenant garde à utiliser le même prototype que la fonction que nous souhaitons détourner strcmp(const char const char La valeur de retour est égale à 0 si les deux paramètres sont égaux, si ce n'est pas le cas, les deux chaînes sont différentes. vim hook.c cat hook.c int strcmp(const char const char { return } gcc hook.c hook.so -shared Le code est vraiment très simple, notre fonction renvoi toujours 0 sans tester les chaînes. [...]
Source aux normes APA
Pour votre bibliographieLecture en ligne
avec notre liseuse dédiée !Contenu vérifié
par notre comité de lecture