title: Hook avec LD_PRELOAD author: depierre published: 2013-01-06 categories: Trick keywords: ld preload, unix, hook, bypass, trick # Comment hook une fonction standarde avec LD_PRELOAD Futex m'a parlé il y a peu d'un trick unix qui m'était inconnu jusqu'alors : poser un hook avec _LD_PRELOAD_. Pour faire simple, _LD_PRELOAD_ permet de charger une lib avec celles standardes. Cette méthode peut être utile si vous voulez modifier le comportement d'un programme de manière simple mais efficace. Pour cela, il suffit de créer une fausse lib contenant votre fonction maison ayant le même nom que celle que vous voulez hook et renseigner le chemin d'accès vers celle-ci dans la variable d'environnement _LD_PRELOAD_. La méthode est applicable seulement si le programme cible a été compiler pour pouvoir utiliser des lib partagées. C'est généralement le cas puisque les fonctions standardes de C comme printf, strcmp, etc. sont contenues dans ce type de lib. Donc si la cible les utilise alors vous pouvez appliquer ce trick. Pour en être certain il suffit d'utiliser le tool _file_ et de regarder si c'est le cas. :::bash $ file example example: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x24a0e0e2aa5e5603263aa9f6e89d839dc1eb4090, not stripped # Mis en pratique Je pense que le meilleur moyen de bien saisir l'affaire est de l'appliquer. Comme exemple je propose le programme suivant : :::c #include #include #include int main(int argv, char *argc[]) { if (argv < 2) { printf("need argument\n"); return 0; } else { if (!strcmp(argc[1], "password")) printf("good job!\n"); else printf("bad password!\n"); } return 0; } Si on lance notre programme avec un argument quelconque, on obtient un joli __bad password!__. :::bash $ ./example test bad password! # Création de la fake lib Notre but ici est de modifier le comportement de _strcmp_ et bypasser la comparaison. On écrit alors une autre fonction _strcmp_ qui retournera toujours 0 et affichera aussi les deux paramètres. :::c #include int strcmp(char *str1, char *str2) { printf("hook of strcmp\n"); printf("str1: %s\n", str1); printf("str2: %s\n", str2); return 0; } On compile notre fake lib avec la commande suivante : :::bash gcc -fPIC -shared fake_strcmp.c -o fake_strcmp.so Il faut encore modifier la variable _LD_PRELOAD_ pour la faire pointer vers notre lib fraichement compilée. :::c $ export LD_PRELOAD=./fake_strcmp.so Relançons le programme d'exemple pour voir ce que ça donne : :::bash $ ./example test hook of strcmp str1: test str2: password good job! La comparaison faite par _strcmp_ est bien bypassée. Le trick a été appliqué avec succès !