返回列表 发新帖

【ctf逆向分析】腾讯2026安全竞赛-Android 初赛分析

  [复制链接]

240

主题

2281

回帖

1万

积分

版主

沐雨阁

Rank: 7Rank: 7Rank: 7

金币
2055
好评
100
信誉
98

MT论坛最佳新人MT论坛帅哥考神MT论坛新人MT论坛活跃会员MT论坛侠客MT论坛灌水老大

发表于 2026-4-14 01:43:20 | 显示全部楼层 | 阅读模式  来自 广东
本帖最后由 你的沐公子 于 2026-4-14 17:53 编辑

该帖子为定时发布 编写2026-4-11


一、题目理解


这个题表面上是一个 Godot 小游戏,场景里有黄色方块和绿色方块。黄色方块只是演示,向前开过去就能触发;真正计分的是绿色方块。题目要求不只是拿到绿色方块的flag,还要把 flag 的生成算法和逆算法都写出来,而且必须是 C/C++ 实现。



二、整体思路

1. 先把 Godot 脚本侧的逻辑摸清楚,确认绿色分支到底调了什么。
2. 再去跟原生 GDExtension,直接把生成 flag 的那个 `Process` 方法调用起来。

最后事实证明,绿色 flag 的计算被拆成了两层:
  1. 1.第一层在 GDScript 里,先对 token 做一轮 `xor_enc`
  2. 2.第二层在 native 里,再和一个固定 8 字节 key 异或
复制代码
右上角显示的那串内容,本质上就是最终 8 字节结果的大写十六进制。

三、先解决 token 从哪里来
题目左上角会显示一个随机 token,我注意到 token 对应的脚本会直接把内容打印到 Godot 日志里,所以最稳的方法其实是直接读 logcat:
  1. 04-11 04:32:52.144  6682  6726 I godot   : Token: 37b8c7e2
复制代码
所以当前这一局的 token 是:
  1. 37b8c7e2
复制代码
后面所有动态验证,我都以这个 token 为主样本。
四、绿色分支并不是单纯的 GDScript
静态看资,可以确认绿色方块的触发逻辑不是直接在脚本里把 flag 算完,而是走到了一个原生扩展对象。关键关系可以概括成下面这句:
  1. flag1 = obj.Process(xor_enc(token))
复制代码
最后界面显示的是:
  1. flag{sec2026_PART1_<flag1>}
复制代码
这里有两个关键点:
  1. xor_enc 是脚本层做的预处理
复制代码
所以分析重点自然就变成了:Process 到底是谁、怎么注册、具体做了什么。
五、定位原生类和方法
这个题是 Godot + GDExtension 结构,native 逻辑不是直接暴露在 Java 层,而是通过 Godot 的扩展接口注册进来的。我的处理方式是用 Frida 在运行时 hook 它的注册过程。
做法比较直接:
  1. hook extension_init
  2. hook module_init
  3. hook classdb_register_extension_class5
  4. hook classdb_register_extension_class_method
  5. 把类名、方法名、对象地址、方法调用入口都记下来
复制代码
实际抓到的 native 类名是:
GameEx
父类是:
Node
真正要的 native 方法是:
Process
动态抓到的关键参数如下:
  1. get_proc         = 0x7542e187bc
  2. object           = 0xb4000076b7c077d0
  3. method_userdata  = 0xb400007627d07050
  4. call_func        = 0x7535e6fde4
  5. ptrcall_func     = 0x7535e6fe3c
复制代码

这些值本身不是答案,但它们证明了一件事:Process 不是伪线索,确实是运行时注册出来并被正常调用的 native 方法。到这里,就可以跳过“碰到绿色方块”这件事,直接模拟绿色分支的调用过程。
六、脚本层算法:xor_enc
Process 的输入不是原始 token,而是 xor_enc(token) 的结果。
这个预处理不复杂,输入是 token 的 8 个 ASCII 字节,处理规则如下:
  1. out = bytes(token)
  2. for i = 0..6:
  3.     out = out ^ out[i + 1]
  4. out[7] = out[7] ^ out[0]
复制代码

如果把 token 记成 t0..t7,输出记成 x0..x7,那么它们之间的关系是:
  1. x0 = t0 ^ t1
  2. x1 = t1 ^ t2
  3. x2 = t2 ^ t3
  4. x3 = t3 ^ t4
  5. x4 = t4 ^ t5
  6. x5 = t5 ^ t6
  7. x6 = t6 ^ t7
  8. x7 = t7 ^ x0
复制代码
拿当前 token 37b8c7e2 去算,得到:
  1. xor_enc("37b8c7e2") = 04 55 5A 5B 54 52 57 36
复制代码
这里我的思路是直接在动态调用 Process 之前,把传进去的 8 字节也打印了出来,和脚本推导完全一致。
七、直接调用 Process
有了 GameEx 的实例地址和 Process 的调用入口后,直接在 Frida 里构造 Godot 的参数对象,然后原地调用 Process。
对 token 37b8c7e2 的调用结果如下:
  1. token   = 37b8c7e2
  2. xor_enc = [04,55,5A,5B,54,52,57,36]
  3. result  = 7E4A09122764744A
复制代码
于是当前绿色 flag 就直接出来了:
  1. flag{sec2026_PART1_7E4A09122764744A}
复制代码
八、算法还原
我接着喂了几组不同 token 给同一个 native Process,得到下面这些样本:
  1. 00000000 -> 7A1F53497336234C
  2. ffffffff -> 7A1F53497336231A
  3. 12345678 -> 791E544870372C47
  4. 37b8c7e2 -> 7E4A09122764744A
  5. 37b8c7e3 -> 7E4A09122764754B
  6. deadbeef -> 7B1B564F7436201B
复制代码
这些样本放在一起看,规律非常明显:native 不是在做复杂加密,而是对 xor_enc(token) 的每个字节又做了一次固定异或。
把 key 反推出来以后,得到:
  1. K = [7A, 1F, 53, 49, 73, 36, 23, 7C]
复制代码
所以 Process 的真实逻辑其实很简单:
  1. y = x ^ K
  2. flag_suffix = HEX_UPPER(y[0..7])
复制代码
也就是说,Part1 的正向算法就是:
  1. flag_suffix = HEX_UPPER(xor_enc(token) XOR K)
复制代码
完整 flag 格式为:
  1. flag{sec2026_PART1_<flag_suffix>}
复制代码

九、逆算法
既然正向算法已经拆成两层,那么逆向也按相反顺序来做就行。
1. 先去掉 native 固定异或
把 flag 后缀的 16 个十六进制字符解成 8 字节 y0..y7,然后:
  1. x = y ^ K
复制代码
这样就恢复出了 xor_enc(token) 的结果。
2. 再反解 xor_enc
前面已经知道:
  1. x0 = t0 ^ t1
  2. x1 = t1 ^ t2
  3. x2 = t2 ^ t3
  4. x3 = t3 ^ t4
  5. x4 = t4 ^ t5
  6. x5 = t5 ^ t6
  7. x6 = t6 ^ t7
  8. x7 = t7 ^ x0
复制代码
把这组关系整理一下,可以写出一个很干净的恢复公式:
  1. t0 = x7 ^ x1 ^ x2 ^ x3 ^ x4 ^ x5 ^ x6
  2. t = t[i - 1] ^ x[i - 1], i = 1..7
复制代码
恢复完 8 个字节后,再检查它们是不是合法十六进制字符。如果是,就得到了原始 token。
拿当前样本验证:
  1. 7E4A09122764744A -> 37b8c7e2
复制代码
和日志完全吻合


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

10

主题

598

回帖

5539

积分

硕士生

Rank: 6Rank: 6

金币
303
好评
1
信誉
100

MT论坛新人考神

发表于 2026-4-14 01:53:09 来自手机  | 显示全部楼层  来自 四川
回复看看隐藏
回复

使用道具 举报

165

主题

5613

回帖

1万

积分

博士生

嘻嘻●‿●

Rank: 7Rank: 7Rank: 7

金币
168
好评
167
信誉
105

考神MT论坛帅哥MT论坛最佳新人MT论坛活跃会员MT论坛侠客MT论坛新人MT论坛灌水老大

发表于 2026-4-14 01:58:00 来自手机  | 显示全部楼层  来自 广东
看看隐藏
回复

使用道具 举报

14

主题

693

回帖

2100

积分

大学生

Rank: 5Rank: 5

金币
1174
好评
0
信誉
68

MT论坛新人考神

QQ
发表于 2026-4-14 02:42:26 来自手机  | 显示全部楼层  来自 四川
看看
回复

使用道具 举报

118

主题

2441

回帖

6641

积分

硕士生

Rank: 6Rank: 6

金币
316
好评
53
信誉
25

MT论坛最佳新人MT论坛新人考神MT论坛帅哥

发表于 2026-4-14 02:59:24 来自手机  | 显示全部楼层  来自 河南
这个还能玩
回复

使用道具 举报

1

主题

3040

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
4527
好评
1
信誉
103
发表于 2026-4-14 03:31:59 来自手机  | 显示全部楼层  来自 江苏
看看隐藏
回复

使用道具 举报

5

主题

327

回帖

1982

积分

高中生

Rank: 4

金币
663
好评
3
信誉
100

MT论坛新人

发表于 2026-4-14 05:34:30 来自手机  | 显示全部楼层  来自 河北
看看
回复

使用道具 举报

44

主题

3170

回帖

8020

积分

硕士生

Rank: 6Rank: 6

金币
6336
好评
1
信誉
92
发表于 2026-4-14 06:02:16 来自手机  | 显示全部楼层  来自 安徽
牛逼克拉斯
回复

使用道具 举报

341

主题

2339

回帖

7972

积分

硕士生

Rank: 6Rank: 6

金币
1050
好评
9
信誉
101
发表于 2026-4-14 06:37:02 来自手机  | 显示全部楼层  来自 浙江
看看
回复

使用道具 举报

67

主题

7589

回帖

2万

积分

博士后

Rank: 8Rank: 8

金币
12032
好评
28
信誉
86

考神MT论坛帅哥MT论坛活跃会员

发表于 2026-4-14 06:37:58 | 显示全部楼层  来自 北京
看看隐藏
回复

使用道具 举报

61

主题

925

回帖

3845

积分

大学生

Rank: 5Rank: 5

金币
301
好评
13
信誉
100
发表于 2026-4-14 06:44:50 来自手机  | 显示全部楼层  来自 湖南
看看隐藏
回复

使用道具 举报

0

主题

1083

回帖

3174

积分

大学生

Rank: 5Rank: 5

金币
2624
好评
0
信誉
100
发表于 2026-4-14 06:49:20 来自手机  | 显示全部楼层  来自 广西
谢谢分享
回复

使用道具 举报

10

主题

3391

回帖

1万

积分

博士生

小小白

Rank: 7Rank: 7Rank: 7

金币
3622
好评
9
信誉
96

考神MT论坛帅哥MT论坛最佳新人MT论坛活跃会员MT论坛新人

发表于 2026-4-14 06:50:56 来自手机  | 显示全部楼层  来自 陕西
看看
回复

使用道具 举报

97

主题

2854

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
4640
好评
5
信誉
100

MT论坛新人MT论坛帅哥

发表于 2026-4-14 07:09:52 来自手机  | 显示全部楼层  来自 广东
看看隐藏
回复

使用道具 举报

87

主题

3214

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
1076
好评
22
信誉
105

考神MT论坛最佳新人MT论坛帅哥

发表于 2026-4-14 07:10:39 来自手机  | 显示全部楼层  来自 广西
看看
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表