CTF逆向实战:从RC4到Base64,详解CTFshow萌新赛逆向题解
1. RC4加密算法在CTF逆向中的实战应用RC4算法作为CTF逆向题目中的常客经常出现在各类比赛中。这种流加密算法看似简单但在实际解题过程中往往会遇到各种变种和陷阱。记得我第一次遇到RC4加密的题目时完全不知道从何下手现在回头看才发现其实有章可循。标准的RC4加密流程主要分为两个阶段KSA密钥调度算法和PRGA伪随机生成算法。KSA阶段会根据密钥对S盒进行初始化PRGA阶段则生成密钥流与明文进行异或操作。在CTF题目中出题人常常会在这两个阶段做手脚比如修改S盒初始化方式、增加循环次数等。以CTFshow萌新赛中的re2题目为例题目给出了flag.txt和enflag.txt两个文件提示我们flag.txt被加密后写入了enflag.txt。用IDA静态分析主函数可以清晰地看到加密流程先读取flag.txt内容然后进行RC4加密最后写入enflag.txt。这里的难点在于密钥的获取题目使用了简单的异或操作对密钥进行了加密需要逆向分析才能还原。# RC4解密脚本示例 def rc4_decrypt(data, key): # KSA阶段 S list(range(256)) j 0 for i in range(256): j (j S[i] key[i % len(key)]) % 256 S[i], S[j] S[j], S[i] # PRGA阶段 i j 0 result [] for char in data: i (i 1) % 256 j (j S[i]) % 256 S[i], S[j] S[j], S[i] result.append(char ^ S[(S[i] S[j]) % 256]) return bytes(result)在实际解题时我建议先用CyberChef这类在线工具尝试标准RC4解密如果不行再考虑编写自定义脚本。对于密钥被加密的情况要仔细分析密钥处理部分的汇编代码常见的加密方式包括异或、加减固定值等简单运算。2. Base64变种算法的识别与破解Base64编码在CTF逆向题目中出现频率极高但出题人很少会直接使用标准Base64。在CTFshow萌新赛的签退题目中就遇到了一个典型的Base64变种。题目给出了一段Python逆向代码通过分析可以发现它实现了一个修改版的Base64编码。与标准Base64相比主要区别在于码表被修改为大写字母小写字母数字()编码后还进行了字符位移处理rend函数识别这类变种Base64的关键在于观察编码流程是否包含明显的64个字符的码表是否有将3字节转换为4字节的特征末尾是否可能出现填充字符对于这道题解题步骤应该是逆向rend函数的位移操作字母循环左移2位使用修改后的码表进行Base64解码得到原始flag# Base64变种解码示例 import base64 import string # 自定义码表 custom_b64table string.ascii_uppercase string.ascii_lowercase string.digits () std_b64table ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/ # 创建转换表 trans str.maketrans(custom_b64table, std_b64table) # 处理过的密文 encrypted BozjB3vlZ3ThBn9bZ2jhOH93ZaH9 # 逆向位移 def reverse_shift(s): result [] for c in s: if c.islower(): new_c chr((ord(c) - ord(a) - 2) % 26 ord(a)) elif c.isupper(): new_c chr((ord(c) - ord(A) - 2) % 26 ord(A)) else: new_c c result.append(new_c) return .join(result) # 完整解密流程 shifted reverse_shift(encrypted) b64_str shifted.translate(trans) flag base64.b64decode(b64_str ).decode() # 补全padding print(flag) # flag{c_t_f_s_h_0_w_!}在实际比赛中遇到Base64变种不要慌先分析码表和额外处理步骤然后分步逆向处理。CyberChef这类工具可以大大简化调试过程。3. 综合题型解析加密与编码的组合应用CTF逆向题目往往不会只考察单一算法而是会将多种加密编码技术组合使用。在CTFshow内部赛的批量生产的伪劣产品这道题中就结合了Base58编码和逐字节异或两种技术。题目给出的是一个APK文件使用JADX反编译后可以找到关键的校验逻辑。分析发现flag经过了以下处理流程使用自定义的Base58编码对编码结果逐字节与位置索引进行异或与硬编码的校验值比较这种组合型的题目解题关键在于理清处理流程的顺序找到每个步骤的特征逆向编写解密脚本# Base58异或组合解密示例 import base58 # 需要安装base58库 # 硬编码的校验值 check [A,5,q,O,g,q,d,\x7f,[,\x7f,s,{,G,A,x,,D,,K,c,-,c, ,G,,,|,x,},J,h,\\,l] # 第一步逆向异或操作 temp [] for i in range(len(check)): temp.append(chr(ord(check[i]) ^ i)) xor_result .join(temp) # A4sLctbxSvypKLvoTQYp9v6P32fcaWvCL # 第二步Base58解码 flag base58.b58decode(xor_result).decode() print(flag) # ctfshow{zhe_bu_shi_flag}对于这类组合题型我建议采用从后向前的分析方法先识别最后的比较操作然后逐步向前推导每个处理步骤。同时要注意中间结果的打印和验证确保每一步的逆向操作都是正确的。4. 高级技巧处理复杂加密逻辑的实战方法当遇到更复杂的加密逻辑时比如CTFshow七夕杯的屏幕裂开了这道题就需要更系统的分析方法。这道题使用了RC4加密但增加了两个难度点KSA阶段的循环次数增加到99999次加密流程中还加入了额外的处理面对这种题目直接静态分析可能会非常耗时。我的建议是先识别出核心加密算法这里是RC4分析加密参数和流程的变种点编写模拟加密过程的脚本通过动态调试验证中间结果# 复杂RC4变种解密示例 def complex_rc4_decrypt(encrypted): # 初始化S盒 s list(range(256)) k (bInfinityLoop*22)[:256] # 扩展密钥 # 重复99999次KSA for _ in range(99999): j 0 for i in range(256): j (s[i] j k[i]) % 256 s[i], s[j] s[j], s[i] # 生成密钥流 v10 v11 0 keystream [] for _ in range(len(encrypted)): v11 (v11 1) % 256 v10 (s[v11] v10) % 256 s[v11], s[v10] s[v10], s[v11] keystream.append(s[(s[v10] s[v11]) % 256]) # 解密 flag bytes([encrypted[i] ^ keystream[i] for i in range(len(encrypted))]) return flag # 密文 encrypted [0xA6,0x3D,0x54,0x0B0,0x74,0xCC,0xBD,0x2A,0x4A,0x0DE,0x0BD,0x35,0x0D1,0x1D,0x0x80,0x32,0x5F,0x64,0x2F,0x0C5,0x0DD,0x11,0x3E,0x95,0x0CC,0x17,0x13,0x0E5,0x5E,0x65,0x0CE,0x42,0x9E,0x47,0x0C8,0x0F3,0x4D,0x8A,0x0A6,0x1F,0x0F0,0x50,0x27,0x0A2,0x28,0x81,0x24,0x0A7,0x0B4,0x90,0x0FC,0x93,0x8A,0x0C1,0x77,0x0D5,0x16,0x1E,0x0FD,0x87,0x0C7,0x0BB,0x0B3] print(complex_rc4_decrypt(encrypted)) # bflag{i_hope_you_didnt_click_the_button_99999__justRE_in_Static}对于特别复杂的加密逻辑有时候静态分析结合动态调试会更高效。可以使用Frida框架hook关键函数观察参数和返回值或者使用GDB/LLDB在关键位置下断点。记住在CTF逆向中理解算法比盲目调试更重要。5. Python逆向工程的技巧与方法在CTF逆向中Python打包的二进制文件也是常见题型如CTFshow的来一个派森和好好学习天天向上两道题。这类题目通常使用PyInstaller打包解题流程有一定规律可循。基本解题步骤使用pyinstxtractor.py解包exe文件提取关键的pyc文件使用uncompyle6或在线工具反编译pyc分析还原的Python源代码以来一个派森为例题目实现了一个Base58编码加异或的校验逻辑。通过反编译得到了以下关键代码def b58encode(tmp): tmp list(map(ord, tmp)) temp tmp[0] base58 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz for i in range(len(tmp) - 1): temp temp * 256 tmp[i 1] tmp [] while True: tmp.insert(0, temp % 58) temp temp // 58 if temp 0: break temp for i in tmp: temp base58[i] tmp [] for i in range(len(temp)): tmp.append(chr(ord(temp[i]) ^ i)) check [A,5,q,O,g,q,d,\x7f,[,\x7f,s,{,G,A,x,,D,,K,c,-,c, ,G,,,|,x,},J,h,\\,l] if tmp check: return 1逆向这种代码时要注意识别出标准算法这里是Base58找出额外的处理步骤这里是逐字节异或逆向编写解密脚本使用中间输出来验证每一步的正确性对于Python逆向我常用的工具链是pyinstxtractor.py解包PyInstaller生成的exeuncompyle6反编译pyc文件Python在线反编译网站当本地工具失效时的备选方案010 Editor手动修复pyc文件头当反编译失败时6. 安卓逆向入门从APK分析到flag获取安卓逆向在CTF中也越来越常见如CTFshow内部赛的批量生产的伪劣产品就是一道典型的安卓逆向题。对于这类题目基本的分析流程是使用apktool解包APK使用JADX或Ghidra分析反编译的Java代码定位关键校验函数分析native层代码如果有在批量生产的伪劣产品这道题中解题过程相对简单解包APK后查看AndroidManifest.xml找到入口Activity在JADX中定位到关键校验类发现flag直接硬编码在代码中ctfshow{群主最爱36D}但更复杂的安卓逆向题可能会涉及JNI和native层加密动态加载dex文件代码混淆和反调试多线程校验对于初学者我建议从以下工具开始JADX强大的Java反编译器支持直接打开APK文件Android Studio内置的APK分析器很有用Frida动态hook和调试IDA Pro/Ghidra分析native层代码分析安卓应用时一个实用的技巧是搜索字符串flag{、ctfshow{等常见flag格式这往往能快速定位关键代码位置。另外注意观察网络请求、文件操作和加密相关API的调用这些地方常常隐藏着关键逻辑。7. 数学知识在逆向中的应用实例CTF逆向题目有时会考察数学知识如CTFshow萌新赛的数学不及格就涉及斐波那契数列和方程求解。这类题目要求选手识别题目中的数学概念将汇编/代码逻辑转化为数学表达式编写脚本求解以数学不及格为例题目逻辑可以简化为检查输入参数数量验证四个方程v9 - v10 0x233F0E151Cv9 - v11 0x1B45F81A32v9 - v12 0x244C071725v4 v12 v11 v10 0x19D024E75FF其中v9 fibonacci(v4)解题步骤分析发现v9是斐波那契数列的第v4项将方程组合并化简得到3*v9 v4 0x19D024E75FF编写脚本爆破寻找满足条件的v4# 数学题解题脚本 def solve_math(): # 计算斐波那契数列 def fibonacci(n): a, b 1, 1 for _ in range(n-1): a, b b, a b return a target 0x19D024E75FF # 1773860189695 for v4 in range(3, 100): v9 fibonacci(v4) if 3 * v9 v4 target: print(fFound v4: {v4}, v9: {v9}) # 计算其他变量 v10 v9 - 0x233F0E151C v11 v9 - 0x1B45F81A32 v12 v9 - 0x244C071725 # 拼接flag parts [ v10.to_bytes(8, big), v11.to_bytes(8, big), v12.to_bytes(8, big), (v4 0x6543).to_bytes(8, big) ] flag b.join(parts).decode(errorsignore) print(fFlag: {flag}) return solve_math() # Flag: flag{newbee_here}这类题目考察的是将代码逻辑转化为数学模型的能力。在实战中要注意识别出题目使用的数学概念斐波那契、素数、模运算等使用SymPy等数学库辅助求解复杂方程注意数据类型的转换和边界条件合理使用暴力破解当问题规模可控时8. 逆向工程中的小端序处理技巧在逆向工程中小端序Little-Endian数据的处理是一个常见考点。CTFshow七夕杯的逆向签到就考察了这一知识点。题目中出现了如下汇编代码mov rax, 7B776F6873667463h ; ctfshow{ mov rdx, 5F6E6769735F6572h ; re_sign_ mov rax, 5F797361655F7369h ; is_easy_ mov [rbpvar_18], 7Dh ; }这类题目解题的关键在于识别出代码中的数据段理解小端序的存储方式正确拼接和转换数据处理小端序数据的Python示例# 小端序数据处理 def parse_little_endian(): parts [ 0x7B776F6873667463, # ctfshow{ 0x5F6E6769735F6572, # re_sign_ 0x5F797361655F7369, # is_easy_ 0x7D # } ] flag b for num in parts[:-1]: flag num.to_bytes(8, little).rstrip(b\x00) flag parts[-1].to_bytes(1, little) print(flag.decode()) # ctfshow{re_sign_is_easy_} parse_little_endian()在实际逆向工程中小端序数据常见于字符串常量网络协议数据文件格式特定字段加密算法的初始向量或密钥处理技巧包括使用IDA的转换为字符串功能快捷键AltA在Python中使用int.from_bytes()和int.to_bytes()进行转换注意去除多余的零字节rstrip(b\x00)对于浮点数等复杂类型使用struct模块处理9. 常见加密算法的快速识别技巧在CTF逆向中快速识别加密算法可以大大提高解题效率。根据我的经验以下特征可以帮助识别常见算法RC4256字节的S盒初始化明显的交换操作swap密钥调度和伪随机生成两个阶段最终异或操作AES明显的S盒和逆S盒轮密钥加、字节替换、行移位、列混淆等操作常见的密钥长度128/192/256位Base6464个字符的码表每3字节输入转换为4字节输出末尾可能有填充MD5/SHA固定的初始化向量IV复杂的位运算和模加固定的输出长度MD5:16字节SHA1:20字节等异或加密简单的逐字节操作可能使用固定密钥或位置相关密钥在IDA中常表现为xor指令以屏幕裂开了为例识别RC4的特征有256字节的数组初始化明显的交换操作密钥扩展过程最终的异或操作快速识别算法后可以搜索标准实现进行对比找出出题人修改的点。同时要注意算法可能被多次调用或组合使用如先Base64再RC4等。10. CTF逆向中的实用工具与技巧在长期参加CTF比赛的过程中我积累了一些实用的逆向工具和技巧分享给大家静态分析工具IDA Pro功能最强大的反编译器GhidraNSA开源的替代品Binary Ninja用户友好的商业工具JADX安卓逆向必备动态分析工具GDB/LLDBLinux下的调试利器x64dbgWindows下的强大调试器Frida动态插桩框架Burp Suite网络流量分析脚本工具Python pwntools快速编写解密脚本CyberChef在线加密解密工具CAPA识别二进制文件功能实用技巧字符串搜索ShiftF12 in IDA交叉引用Xrefs分析修改Z标志位绕过校验使用angr等符号执行工具解决复杂约束资源网站CTFtime.org比赛日历和writeupLiveOverflow YouTube频道优质逆向教程看雪学院中文逆向技术社区以easy_magic为例题目给出一串16进制数据看起来像MD5哈希。使用在线解密网站可以轻松破解# 假设密文是7d66f3e5e7a7e5f3d6e5f3d6e5f3d6e5 # 使用在线MD5解密网站查询 # 得到原文7x_flag_is_here # 所以flag是ctfshow{7x_flag_is_here}记住在CTF逆向中工具只是辅助最重要的是理解程序逻辑和加密原理。不要过度依赖工具而应该培养独立分析的能力。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2503993.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!