CTF Reverse模块系列分享(四):核心实战!字符串加密还原,编写脚本直接拿Flag
上期我们学会了用IDA找主函数、看伪代码、定位加密逻辑,今天咱们就进入Reverse基础题型的核心实战:字符串加密与逻辑还原。
字符串加密是CTF Reverse中最基础、最高频的题型,90%的新手入门题都是这类。今天我会拆解3种最常见的加密类型(异或、移位、简单替换).
每种都按IDA分析加密逻辑→推导还原思路→编写Python还原脚本→验证结果的流程讲解,全程实战,看完就能上手写出自己的第一个Reverse解题脚本,直接拿到Flag!
加密和还原是“互逆操作”——只要搞懂加密时程序做了什么,反过来做就能还原出正确输入。新手不用怕写脚本,今天的脚本都很简单,复制修改关键参数就能用!
一、本期核心目标
今天我们的目标很清晰,学会这3件事,就能应对所有基础字符串加密题:
- 识别3种高频加密类型:异或加密、移位加密、简单替换加密(通过IDA伪代码快速判断)。
- 掌握“加密逻辑→还原思路”的推导方法:知道加密时程序做了什么,就知道还原该做什么。
- 编写Python还原脚本:用简单的代码实现还原逻辑,输出正确输入(Flag)。
今天的所有实战案例,都用真实Reverse题的简化版(Windows exe+Linux elf双版本),和CTF比赛题型完全一致,跟着操作就能积累实战经验!
二、高频加密类型实战:从分析到还原,一步到位
我们按难度从低到高的顺序,拆解3种高频加密类型。每种类型都先通过IDA分析加密逻辑,再推导还原思路,最后编写脚本——新手重点学逻辑推导,脚本只是工具,理解思路才是核心!
类型1:异或加密(最基础、最高频!)
异或加密是Reverse中最常见的加密方式,核心逻辑是“输入字符 XOR 密钥 = 加密字符”。记住一个关键特性:异或两次等于原数(a XOR key XOR key = a)——这是还原的核心原理!
步骤1:用IDA分析加密逻辑
我们先看一个异或加密程序的伪代码(通过IDA F5查看,和上期学的操作一致):
int main() { char input[20]; char key = 0x13; // 加密密钥 char target[] = "x5@G7#kM"; // 加密后的目标字符串(正确输入加密后的值) printf("请输入Flag:"); gets(input); // 输入要验证的字符串 // 加密逻辑:输入的每个字符和key异或 for (int i = 0; i < strlen(input); i++) { input[i] ^= key; // 核心加密操作:异或key } // 验证逻辑:加密后的输入和target一致,则输出正确 if (strcmp(input, target) == 0) { printf("Flag正确!\n"); } else { printf("Flag错误!\n"); } return0; }通过伪代码,我们能提取3个关键信息:
① 加密算法:异或(^运算符);
② 加密密钥:0x13(十六进制,转十进制是19); ③ 目标字符串:“x5@G7#kM”(正确输入加密后的结果)。
步骤2:推导还原思路
加密逻辑:输入字符 XOR 0x13 = 加密字符(target中的字符)。
还原逻辑(逆操作):加密字符 XOR 0x13 = 输入字符(正确Flag)。
原因:异或两次等于原数,加密时异或了一次key,还原时再异或一次key即可。
步骤3:编写Python还原脚本
脚本核心:遍历target中的每个字符,依次和key(0x13)异或,得到正确输入。脚本很简单,注释详细,新手直接复制修改即可:
# 异或加密还原脚本 key = 0x13 # 从IDA中提取的加密密钥 target = "x5@G7#kM" # 从IDA中提取的目标字符串(加密后的值) flag = "" # 遍历target的每个字符,异或key还原 for c in target: # ord(c):把字符转成ASCII码;chr():把ASCII码转回字符 flag += chr(ord(c) ^ key) # 输出还原后的正确Flag print("正确Flag:", flag)步骤4:验证结果
运行脚本,输出结果:正确Flag: flag{1234ab}(示例结果,实际以你的脚本运行为准)。把这个结果输入程序,就能看到“Flag正确!”——成功拿到Flag!
小技巧:如果密钥是字符串(比如key=“abc123”),还原时按“字符对应密钥的每个字符”依次异或(循环使用密钥),比如输入第1个字符对应key[0],第2个对应key[1],直到密钥用完再从头开始。
类型2:移位加密(循环移位/凯撒加密)
移位加密的核心逻辑是“输入字符的ASCII码,向左/向右移动n位”(比如’a’的ASCII码是97,向右移3位就是100,对应’d’),常见于凯撒加密、循环移位加密。
步骤1:用IDA分析加密逻辑
看一个“向右循环移位3位”的加密伪代码:
int main() { char input[20]; char target[] = "kL`f9]vM"; // 加密后的目标字符串 int shift = 3; // 移位位数:向右移3位 printf("请输入Flag:"); gets(input); // 加密逻辑:每个字符向右循环移位3位 for (int i = 0; i < strlen(input); i++) { // (input[i] >> 3):向右移3位;(input[i] << 5):向左移5位;|:按位或,实现循环 input[i] = (input[i] >> 3) | (input[i] << 5); } if (strcmp(input, target) == 0) { printf("Flag正确!\n"); } else { printf("Flag错误!\n"); } return0; }提取关键信息:
① 加密算法:向右循环移位3位;
② 移位位数:3位;
③ 目标字符串:“kL`f9]vM”。
步骤2:推导还原思路
循环移位的逆操作是“反向循环移位相同位数”:
加密逻辑:向右循环移位3位
还原逻辑:向左循环移位3位(或向右循环移位5位,因为8位字符的循环移位,移n位和移8-n位反向)。
步骤3:编写Python还原脚本
# 循环移位加密还原脚本(向右移3位 → 还原:向左移3位) target = "kL`f9]vM" # 从IDA提取的目标字符串 shift = 3 # 移位位数(和加密时一致) flag = "" for c in target: # 向左循环移位3位:(c << 3) | (c >> 5) # 先把字符转成ASCII码(ord(c)),再进行移位操作 original = (ord(c) << shift) | (ord(c) >> (8 - shift)) flag += chr(original) print("正确Flag:", flag)步骤4:验证结果
运行脚本,得到正确Flag,输入程序验证即可。如果是普通移位(非循环),还原时直接“反向移位”即可(比如加密时向右移3位,还原时向左移3位,用ord© - 3)。
类型3:简单替换加密(字符映射)
简单替换加密的核心逻辑是“用一个字符替换另一个字符”(比如’a’→’x’、‘b’→’y’),加密时会有一个“替换表”(字符映射表),还原时用“反向替换表”即可。
步骤1:用IDA分析加密逻辑
看一个简单替换加密的伪代码:
int main() { char input[20]; char target[] = "zqf72@"; // 加密后的目标字符串 // 替换表:key1中的字符 → 对应key2中的字符(加密映射) char key1[] = "abcdef1234@"; char key2[] = "xyzqrf7890#"; printf("请输入Flag:"); gets(input); // 加密逻辑:按替换表替换每个字符 for (int i = 0; i < strlen(input); i++) { // 找到input[i]在key1中的位置,替换成key2中对应位置的字符 for (int j = 0; j < strlen(key1); j++) { if (input[i] == key1[j]) { input[i] = key2[j]; break; } } } if (strcmp(input, target) == 0) { printf("Flag正确!\n"); } else { printf("Flag错误!\n"); } return0; }提取关键信息:
① 加密算法:简单替换;
② 加密映射表:key1→key2(比如’a’→’x’、‘b’→’y’);
③ 目标字符串:“zqf72@”。
步骤2:推导还原思路
加密逻辑:key1[i] → key2[i](输入字符是key1中的字符,替换成key2中的字符)。
还原逻辑:key2[i] → key1[i](目标字符是key2中的字符,替换成key1中的字符)——构建反向映射表即可。
步骤3:编写Python还原脚本
# 简单替换加密还原脚本 target = "zqf72@"# 从IDA提取的目标字符串 # 加密映射表:key1→key2 key1 = "abcdef1234@" key2 = "xyzqrf7890#" # 构建反向映射表:key2的字符 → key1的字符(还原用) replace_dict = {} for k1, k2 inzip(key1, key2): replace_dict[k2] = k1 flag = "" # 遍历target,按反向映射表替换 for c in target: flag += replace_dict[c] print("正确Flag:", flag)步骤4:验证结果
运行脚本得到Flag,输入程序验证即可。如果替换表是随机生成的,只要从IDA中找到完整的key1和key2,就能构建反向映射表还原。
三、实战小任务:综合加密程序还原(巩固练习)
光练单一加密类型不够,我们用一个“异或+移位”的综合加密程序,练习完整的还原流程:
用IDA分析综合加密程序的伪代码
int main() { char input[20]; char target[] = "pR$j3*"; char key = 0x0F; int shift = 2; printf("请输入Flag:"); gets(input); // 综合加密:先异或key,再向左移2位 for (int i = 0; i < strlen(input); i++) { input[i] ^= key; // 第一步:异或 input[i] <<= shift; // 第二步:向左移2位 } if (strcmp(input, target) == 0) { printf("Flag正确!\n"); } else { printf("Flag错误!\n"); } return0; }自己推导还原思路,编写脚本
提示:还原顺序要和加密顺序相反(先还原移位,再还原异或)——加密是“异或→移位”,还原是“反向移位→异或”。自己动手写脚本,再对照下面的参考脚本检查:
# 综合加密还原脚本(异或+移位) target = "pR$j3*" key = 0x0F shift = 2 flag = "" for c in target: # 第一步:还原移位(向左移2位 → 向右移2位) shift_back = ord(c) >> shift # 第二步:还原异或 original = shift_back ^ key flag += chr(original) print("正确Flag:", flag)四、还原过程中最容易踩的4个坑
坑1:还原顺序搞反——加密是“步骤A→步骤B”,还原必须是“还原步骤B→还原步骤A”(比如先异或再移位,还原要先移位再异或),顺序错了必出错。
坑2:密钥/移位位数搞反——比如加密时是“异或0x13”,还原时写成“异或0x31”,一定要从IDA中准确提取关键参数。
坑3:字符编码错误——忘记用ord()/chr()转换字符和ASCII码,直接对字符进行运算,导致脚本报错。
坑4:循环边界问题——还原时遍历的字符长度和加密时不一致(比如target长度是8,还原时少遍历1个),导致Flag缺失字符。
五、下期预告&福利时间
今天我们搞定了3种高频字符串加密的还原方法,还学会了编写Python还原脚本——这是Reverse基础题的核心,掌握后就能独立解大部分新手Reverse题了!下期我们将进入系列最后一期:实战技巧大整合——比赛答题策略+常见题型总结,帮你整合所有知识点,形成完整的解题思维,轻松应对CTF比赛中的Reverse题型!
如果今天的内容对你有帮助,别忘了点赞、在看,转发给一起学CTF的小伙伴
全套CTF学习资源,也可以在下面蓝色链接拿!
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
想要的兄弟,上面链接找助理拿哦,直接免费分享!前提是你得沉下心练,别拿了资料就吃灰,咱学技术,贵在坚持!
给大家准备了2套关于CTF的教程,一套是涵盖多个知识点的专题视频教程:
另一套是大佬们多年征战CTF赛事的实战经验,也是视频教程:
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源