2025赣银杯CTFr2.exeReverseWriteup

admin 2026-03-18 00:31:00 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档详述了2025赣银杯CTF逆向题r2.exe的解题过程。程序为x64架构并采用OLLVM混淆,作者定位核心函数后识别出非标准参数的XXTEA加密算法,提取了密文与密钥。通过编写Python脚本逆向解密,成功还原出Flag。文章涵盖了从反混淆定位到算法识别及脚本实现的完整流程,对CTF逆向选手具有参考价值。 综合评分: 90 文章分类: 逆向分析,CTF,实战经验


cover_image

2025赣银杯CTF r2.exe Reverse Writeup

ListSec

2026年3月2日 20:17 江西

2025 赣银杯 CTF: r2.exe Reverse Writeup

一、 题目基本信息

  • • 文件名r2.exe
  • • 文件格式: x64 可执行程序 (Windows PE 格式)
  • • 保护机制: 存在较为明显的 OLLVM (Obfuscator-LLVM) 控制流平坦化混淆。

二、 逆向分析过程

1. 入口与字符串初步定位

通过查壳工具查看程序无额外压缩壳,或者直接拖入 IDA Pro 9.0 中进行分析。 在 Strings 选项卡中检索通常的 CTF 关键字符,例如 “flag”,“wrong”,“correct” 等。如果检索不到明显线索,可以找一些诸如 “flag!” 的可疑格式化字符串。

利用 IDA 的交叉引用 (Xrefs) 找到了核心校验函数 main 函数,地址位于 0x1400020e0

2. OLLVM 混淆与常量还原

查看 main 的反汇编和伪代码发现,代码被拆分成了诸多利用状态机 switch-case 跳转的代码块(控制流平坦化)。在这个被拉伸的伪代码中,存在大量的状态流转与字节数组操作:

  • • 通过分析某一个分支处的常量拼接逻辑(或运行时 dump),能够找到硬编码的目标密文数组:前 6 个字节实际上是用数字的转码形式,与后续拼凑出的字节常量一起构成了一个 32 字节长的验证数组:
cipher_bytes = [92, 48, 135, 133, 200, 107, 126, 102, 179, 245, 80, 205, 181, 96, 6, 202, 94, 87, 102, 157, 187, 52, 50, 64, 235, 213, 130, 241, 244, 219, 13, 243]
  • • 从上文变量初始化中发现了长度为 DWORD[4] 的密钥:
  key = [15000, 89894, 17, 223123]

3. 用户输入与核心加密算法识别

在平坦化的块里藏着对用户的输入读取,通常为带安全隐蔽性的 scanf,程序吸取了长 32 的用户字符串流转给接下来的核心算法 sub_140001250

双击研究 sub_140001250,伪代码中包含以下明显的位运算特征:

z >>&nbsp;5&nbsp;^ y <<&nbsp;2
y >>&nbsp;3&nbsp;^ z <<&nbsp;4
sum ^ y
key[(p &&nbsp;3) ^ e] ^ z
......

这是典型的 XXTEA (微型加密算法) 的加密运算。进一步观察到外层循环次数(通过 DELTA 处理的轮数计算),确认为:

  • • 加密轮数12 轮
  • • 加密 Delta0x33445566 (XXTEA 非标常见固定常量,一般标准为 0x9E3779B9)

程序将 32 字节(划分为 8 个 DWORD 四字节块)的用户明文通过 XXTEA 算法加密后,拿结果和之前还原的目标 cipher_bytes 进行逐字节的比较判断,如果全部一致则会导向输出成功(或者直接对齐组装并显示输出 right flag)。

三、 解题思路与解密脚体

基于上述分析,我们只需要将获得的 XXTEA 算法逻辑反转(解密操作),以常量 cipher_bytes (密文表)作为输入,利用同样的 keyDelta 及 rounds 进行逆向还原即可。

这里使用 Python 编写解密脚本:

import&nbsp;struct

defdecrypt(cipher_bytes, key, rounds=12, delta=0x33445566):
# 将密文字节数组转换为长度为 8 的 32位无符号整数数组
&nbsp; &nbsp; v =&nbsp;list(struct.unpack("<IIIIIIII",&nbsp;bytes(cipher_bytes)))
&nbsp; &nbsp; n =&nbsp;len(v)

# 获取加密时的最终 sum (加解密对称)
sum&nbsp;= (delta * rounds) &&nbsp;0xffffffff
&nbsp; &nbsp; y = v[0]

while&nbsp;rounds >&nbsp;0:
&nbsp; &nbsp; &nbsp; &nbsp; e = (sum&nbsp;>>&nbsp;2) &&nbsp;3
# 逆序遍历
for&nbsp;p&nbsp;inrange(n -&nbsp;1,&nbsp;0, -1):
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; z = v[p -&nbsp;1]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v[p] = (v[p] - (((z >>&nbsp;5&nbsp;^ y <<&nbsp;2) + (y >>&nbsp;3&nbsp;^ z <<&nbsp;4)) ^ ((sum&nbsp;^ y) + (key[(p &&nbsp;3) ^ e] ^ z)))) &&nbsp;0xffffffff
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = v[p]

&nbsp; &nbsp; &nbsp; &nbsp; p =&nbsp;0
&nbsp; &nbsp; &nbsp; &nbsp; z = v[n -&nbsp;1]
&nbsp; &nbsp; &nbsp; &nbsp; v[0] = (v[0] - (((z >>&nbsp;5&nbsp;^ y <<&nbsp;2) + (y >>&nbsp;3&nbsp;^ z <<&nbsp;4)) ^ ((sum&nbsp;^ y) + (key[(0&nbsp;&&nbsp;3) ^ e] ^ z)))) &&nbsp;0xffffffff
&nbsp; &nbsp; &nbsp; &nbsp; y = v[0]

# 递减 sum 并减少轮次
sum&nbsp;= (sum&nbsp;- delta) &&nbsp;0xffffffff
&nbsp; &nbsp; &nbsp; &nbsp; rounds -=&nbsp;1

# 解包重组回字符串
return&nbsp;struct.pack("<IIIIIIII", *v)

if&nbsp;__name__ ==&nbsp;'__main__':
&nbsp; &nbsp; key = [15000,&nbsp;89894,&nbsp;17,&nbsp;223123]
&nbsp; &nbsp; cipher_bytes = [92,&nbsp;48,&nbsp;135,&nbsp;133,&nbsp;200,&nbsp;107,&nbsp;126,&nbsp;102,&nbsp;179,&nbsp;245,&nbsp;80,&nbsp;205,&nbsp;181,&nbsp;96,&nbsp;6,&nbsp;202,
94,&nbsp;87,&nbsp;102,&nbsp;157,&nbsp;187,&nbsp;52,&nbsp;50,&nbsp;64,&nbsp;235,&nbsp;213,&nbsp;130,&nbsp;241,&nbsp;244,&nbsp;219,&nbsp;13,&nbsp;243]

# Python3 输出解码结果
print("Flag:", decrypt(cipher_bytes, key).decode('utf-8'))

四、 最终 Flag 结果

运行解密脚本输出的结果即为答案本体:

f8fd708c923817076dc3ff56c535ec7b


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:ListSec 《2025赣银杯CTF r2.exe Reverse Writeup》

WindowsETW攻击 网络安全文章

WindowsETW攻击

文章总结: 文档阐述了通过破坏ETW机制致盲EDR的技术。主要手段包括利用logman禁用提供者阻断遥测,及修补ntdll中EtwEventWrite函数阻止事
评论:0   参与:  0