首页
社区
课程
招聘
[原创]KCTF2025签到题
发表于: 2025-8-11 11:19 164

[原创]KCTF2025签到题

2025-8-11 11:19
164

题目设计思路(WP)

这道题是一个基础的 逆向签到题,核心在于避免 flag 以明文形式出现在可执行文件中,同时保持校验逻辑简单易控。

1. 明文隐藏

  • 题目将 flag 拆成两个等长的字节数组 part_apart_b,它们满足:

    1
    part_a[i] ^ part_b[i] = flag[i]
  • 因此,在二进制文件中不会直接出现明文 flag,即使用 strings 搜索也找不到完整口令。

2. 校验方式

  • 程序读取用户输入,先检查长度是否与 part_a 一致。

  • 然后逐字节进行异或对比:

    1
    if ch != (a[i] ^ b[i]) { return false; }
  • 一旦有字符不匹配,立即返回 false,不会生成完整的 flag 字符串。

3. 防优化与结构控制

  • #[inline(never)] 用来防止编译器将 part_apart_b 合并或优化,从而让它们在反汇编中保持独立存在,避免被意外优化成可见明文。
  • 这种方式也让逆向分析者必须手动提取两个数组进行计算。

4. 逆向解题方法

  • 反编译或直接用十六进制工具找到 part_apart_b 两段连续的字节数组。

  • 编写脚本逐字节进行异或,还原出明文 flag:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a = [0xe9,0x7a,0xc7,0xb0,0x00,0x98,0x4e,0xfc,
         0x67,0x3f,0x8e,0x08,0xff,0x59,0x4e,0x0e,
         0x02,0x7b,0x7c,0x40,0xf7,0x07,0xce,0x54,0x67]
     
    b = [0x8f,0x16,0xa6,0xd7,0x7b,0xf3,0x2d,0x88,
         0x01,0x60,0xfa,0x61,0x92,0x3c,0x11,0x62,
         0x67,0x1a,0x0c,0x1f,0xc5,0x37,0xfc,0x61,0x1a]
     
    flag = ''.join(chr(x ^ y) for x, y in zip(a, b))
    print(flag)
  • 运行脚本即可得到题目要求的签到口令。

5. 设计目的

  • 对初学者:练习数组提取与简单异或运算的逆向思路。
  • 对进阶者:理解为什么要避免直接存储明文,以及如何在二进制中隐藏敏感信息。

源码如下:

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
use std::io::{self, Write};
 
#[inline(never)]
fn part_a() -> &'static [u8] {
    &[
        0xe9, 0x7a, 0xc7, 0xb0, 0x00, 0x98, 0x4e, 0xfc,
        0x67, 0x3f, 0x8e, 0x08, 0xff, 0x59, 0x4e, 0x0e,
        0x02, 0x7b, 0x7c, 0x40, 0xf7, 0x07, 0xce, 0x54,
        0x67,
    ]
}
 
#[inline(never)]
fn part_b() -> &'static [u8] {
    &[
        0x8f, 0x16, 0xa6, 0xd7, 0x7b, 0xf3, 0x2d, 0x88,
        0x01, 0x60, 0xfa, 0x61, 0x92, 0x3c, 0x11, 0x62,
        0x67, 0x1a, 0x0c, 0x1f, 0xc5, 0x37, 0xfc, 0x61,
        0x1a,
    ]
}
 
#[inline(never)]
fn check_input(input: &str) -> bool {
    let a = part_a();
    let b = part_b();
 
    if input.len() != a.len() {
        return false;
    }
 
    for (i, ch) in input.bytes().enumerate() {
        if ch != (a[i] ^ b[i]) {
            return false;
        }
    }
    true
}
 
fn main() {
    println!("Welcome to KCTF 2025!");
    print!("请输入签到口令: ");
    io::stdout().flush().unwrap();
 
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    // 使用 trim() 去除前后空白(更保险)
    let s = s.trim();
 
    if check_input(s) {
        println!("签到成功!FLAG: {}", s);
    } else {
        println!("签到失败!");
    }
}

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-8-11 11:29 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回