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