返回
2
0

Ohhh

Ohh,2026-04-30 17:56

CTF Reverse Engineering Write-Up: Challenge

基本

文件类型: ELF 64-bit LSB executable, x86-64, stripped

目标: 逆向分析二进制验证逻辑,获取正确 flag

Flag 格式: geesec{...}


静态分析

信息收集

首先通过 strings 提取可打印字符串,获得关键线索:

geesec{ ← flag 前缀
Unmask the hidden secret. Input your flag:
flag length error ← 长度错误提示
flag format is incorrect ← 格式错误提示
Incorrect flag, please try again.
Congratulations! The flag is correct.
86f;6a30:?ln>?o<'&v#%q#u(}x,,~-( ← 可疑加密字符串(32字节)

主函数逻辑 (0x401470)

通过反汇编分析主函数流程:

输出提示信息 "Unmask the hidden secret..."

scanf 读取用户输入到栈缓冲区

调用 strlen 检查输入长度是否为 0x28(40 字节)

调用 0x4012d0 验证 flag 格式并提取内容

调用 0x4013b0 对内容进行 XOR 加密变换

memcpy 从 0x4020d0 拷贝 33 字节加密数据到局部缓冲区

strncmp 比较 XOR 结果与加密数据(32 字节)

匹配则输出 "Congratulations!",否则输出 "Incorrect flag"

格式验证函数 (0x4012d0)

strncmp(input, "geesec{", 7) → 验证前缀

input[len-1] == '}' → 验证后缀

strncpy(result, input+7, len-8) → 提取花括号内内容

返回内容指针

XOR 加密函数 (0x4013b0)

核心加密循环:

for (int i = 0; i < length; i++) {
result[i] = input[i] ^ (i & 0xff);
}

即每个字节与自身索引进行 XOR。

加密数据

从 .rodata 段 0x4020d0 提取 32 字节加密数据:

38 36 66 3b 36 61 33 30
3a 3f 6c 6e 3e 3f 6f 3c
27 26 76 23 25 71 23 75
28 7d 78 2c 2c 7e 2d 28

对应字符串:86f;6a30:?ln>?o<'&v#%q#u(}x,,~-(

逆向算法

XOR 是可逆运算,解密公式:

content[i] = encrypted[i] ^ i

解密脚本:

encoded = bytes([
0x38, 0x36, 0x66, 0x3b, 0x36, 0x61, 0x33, 0x30,
0x3a, 0x3f, 0x6c, 0x6e, 0x3e, 0x3f, 0x6f, 0x3c,
0x27, 0x26, 0x76, 0x23, 0x25, 0x71, 0x23, 0x75,
0x28, 0x7d, 0x78, 0x2c, 0x2c, 0x7e, 0x2d, 0x28
])

content = ''.join(chr(encoded[i] ^ i) for i in range(32))
flag = f'geesec{{{content}}}'
print(flag)

Flag

geesec{87d82d5726fe22a377d01d5b0db70c37}

验证

重新用加密算法加密解密结果,与原始加密数据完全一致,确认 flag 正确。

注意事项

二进制文件被 strip 过,所有符号被移除,但不影响逆向分析

注意 objdump -s 的 hex 输出是按内存地址顺序逐字节显示,4 字节分组仅为视觉辅助,不要当成小端序 32
位整数解析(这是初期的易错点)

暂无回复。你的想法是什么?


bottom-logo1
bottom-logo2captionbottom-logo3
GeeSec
商务合作
bottom-logo4