首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
逆向工程
发新帖
1
4
[原创]RC4算法逆向分析
发表于: 2025-11-9 18:49
12405
[原创]RC4算法逆向分析
南行
3
2025-11-9 18:49
12405
## 简介 在密码学中,RC4 是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4 是有线等效加密(WEP)中采用的加密算法,也曾经是 TLS 可采用的算法之一。 流密码也属于对称密码,但与分组加密算法不同的是,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密,加解密使用相同的密钥。也就是说,RC4不是对明文进行分组处理,而是字节流的方式依次加密明文中的每一个字节。 ## 加解密原理 RC4 由伪随机数生成器和异或运算组成(由于异或运算的对合性,RC4 加密解密使用同一套算法)。RC4 的密钥长度可变,范围是`1~255`。给定一个密钥,伪随机数生成器接受密钥并产生一个 S 盒。S 盒用来加密数据,而且在加密过程中 S 盒会变化。 ## 加密流程 1. 先初始化状态向量`S`(256 个字节,用来作为密钥生成的种子)按照升序,给每个字节赋值。 2. 初始密钥(由用户输入),长度任意,如果输入长度小于 256 个字节,则进行轮转,直到填满。例如填入密钥的是1 2 3 4 5 ,那么填入的是1,2,3,4,5,1,3,4,5,1,2,3,4,5 由上述轮转过程得到 256 个字节的向量`T`(用来作为密钥流生成的种子) 3. 最后是根据向量`S`和`T`生成`T`生成密钥流与明文进行加密 - 伪代码: ```c //1.初始化S和T for(int i=0;i<255;i++){ S[i]=i; T[i]=K[i%keylen] } //2.初始排列S j=0; for(int i=0;i<255;i++){ j=(j+S[i]+T[i])%256; swap(S[i],S[j]); //交换S[i]和S[j] } //3.产生密钥流,利用密钥流和明文进行加密 i,j=0; for(int r=0;r<len;r++){ i=(i+1)%256; j=(j+S[i])%256; swap(S[i],S[j]);//swap交换 t=(S[i]+S[j])%256; k[r]=S[t]; data[r]^=k[r]; } ``` ## C代码表示 几个基本变量: - `S-Box`也就是所谓的`S`盒,是一个 256 长度的`char`型数组,每个单元都是一个字节,算法运行的任何时候,`S`都包括 0-255 的 8 比特数的排列组合,只不过值的位置发生了变换。 - 密钥`char key[256]`密钥的长度`keylen`与明文长度、密钥流的长度没有必然关系。 - 临时向量`k`长度也为 256,每个单元也是一个字节。如果密钥的长度是 256 字节,就直接把密钥的值赋给`k`,否则,轮转地将密钥的每个字节赋给`k`。 ### 初始化部分 - 参数 1 是一个 256 长度的`char`型数组,定义为:`unsigned char sBox[256]` - 参数 2 是密钥,其内容可以随便定义:`char key[256]` - 参数 3 是密钥的长度,`Len=strlen(key)` ```c /*初始化函数*/ void rc4_init(unsigned char*s,unsigned char*key, unsigned long Len) { int i=0,j=0; char k[256]={0}; unsigned char tmp=0; for(i=0;i<256;i++) { s[i]=i; //0-255赋值给s k[i]=key[i%Len]; //将k重新计算 } for(i=0;i<256;i++) { //对s进行初始置换 j=(j+s[i]+k[i])%256; //给j赋值 tmp=s[i]; s[i]=s[j]; //交换s[i]和s[j] s[j]=tmp; } } ``` 初始化长度为 256 的`S`盒。第一个`for`循环将 0 到 255 的互不重复的元素装入`S`盒。第二个`for`循环根据密钥打乱`S`盒,`i`确保`S-box`的每个元素都得到处理,`j`保证`S-box`的搅乱是随机的。 ### 加密部分 - 参数1 是上边`rc4_init`函数中,被搅乱的`S-box` - 参数2 是需要加密的数据`data` - 参数3 是`data`的长度 ```c /*加解密*/ void rc4_crypt(unsigned char*s,unsigned char*data,unsigned long len) { int i=0,j=0,t=0; unsigned long k=0; unsigned char tmp; for(k=0;k<len;k++) { i=(i+1)%256; //固定方式生成的i j=(j+s[i])%256; //固定方式生成的j tmp=s[i]; s[i]=s[j]; //交换s[x]和s[y],第二次置换 s[j]=tmp; t=(s[i]+s[j])%256; //固定方式生成的t data[k]^=s[t]; //异或运算 } } ``` 每收到一个字节,就进行循环。通过一定的算法定位`S-box`中的一个元素,并与输入字节异或,得到`k`。循环中还改变了`S-box`。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。 ### 主函数 ```c #include<stdio.h> #include<string.h> int main() { unsigned char s[256] = {0}; char key[256] = {"hello_ctfer"}; unsigned char data[] = "hello_world"; unsigned long key_len = strlen(key); // 初始化s盒 rc4_init(s, (unsigned char*)key, key_len); // 解密数据 rc4_crypt(s, (unsigned char*)data, 42); // 打印解密后的数据 for (int i = 0; i < 42; i++) { printf("%02x", (data[i]) & 0xff); } return 0; } ``` ## 逆向分析 ### 特征识别 RC4 算法主要通过加密算法特征来进行识别。 1. 反编译后可以看见多个循环次数为 256 的循环,以及存在一些`%256`的运算。 2. 会根据密钥打乱`S`盒 3. 最后处理输入数据的是异或。 ### 魔改RC4 RC4 常见的魔改方法: 1. 魔改初始化算法,可以将`S`盒初始化值并不设置成 0-255,也可以设置成其它的,也可以在`S`的初始置换过程中添加可逆运算。 2. 由于最后加密 flag 是利用密钥流来单字节加密的,也有人会在这个地方添加一些可逆运算来进行魔改。 例:  总之算法需要遵循对称加密性质: - `enc_data=RC4(flag)` - `flag=RC4(enc_data)` ## 例题 ### 标准RC4 >2024Moectf RC4 题目存在花指令,我们先进行去除。去除后我们分析代码。 根据题目中的`RC4`字样我们就可以判断程序为 RC4 算法。 ida 反编译程序直接看到了一串包含`RC4`字样疑似密钥的字符,可以猜测这段字符就是密钥。 然后我们找密文尝试解密,上面的三个字符串都是一样的,我们可以尝试一下它们是不是密文。  假定程序是一个标准 RC4,编写解密脚本,然后成功解密。 - exp ```python from Crypto.Cipher import ARC4 key = b"RC4_1s_4w3s0m3" enc = bytes.fromhex("A7 1A 68 EC D8 27 11 CC 8C 9B 16 15 5C D2 67 3E 82 AD CE 75 D4 BC 57 56 C2 8A 52 B8 6B D6 CC F8 A4 BA 72 2F E0 57 15 B9 24 11") rc4 = ARC4.new(key) dec = rc4.decrypt(enc) print(dec) #moectf{why_Rc4_haS_The_Rev32sabl3_pr0ceSS} ``` - exp 写加密脚本最好还是用 python,一个是快,另一个是可以避免类型错误。 ### 动态调试解RC4 >2024极客大挑战 让我康康你的调试 - 分析 分析代码,程序第输入进行了异或加密,然后将加密后的输入内容作为参数传入了`sub_14A6`,接下来我们跟进分析。  很明显就可以看出来这是一个 rc4 加密算法,我们这里通过动态调试的方法来解这道题。  - exp 首先我们将程序动态调试起来,然后输入一段符号输入要求长度的测试数据。 本题代码中输入要求为 33 字节,我们构造一个 33 字节的字符串,将程序动态调试起来然后输入。 ``` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ``` 输入完成后,我们让程序运行到执行完加密逻辑后的代码部分。  然后我们提取加密后的密文,即`v5[9]`。  这里我们可以通过插件 Lazyida 快速提取。  然后我们再次动态调试程序将 33 个`a`输入程序来占位,然后我们在加密逻辑之前下断点让运行到这里停下。 之后使用我们的 Lazyida 插件的 Paste data 功能将提取出的密文粘贴到占位的`a`中,直接选中头字符即可。  我们让程序走过加密逻辑后再次查看密文,可以看到已经变成了我们最初输入的明文`a`。这里我们已经可以判断程序的加解密是对称的,也就意味着我们只要把程序的密文输入到程序中经过加密逻辑解密就会被解密成明文。  我们可以猜测这这个被数据初始化的数组就是我们的密文。  我们动态调试运行然后通过 lazyida 提取初始化后的密文数据。  然后我们和上面的逻辑一样将程序输入足够的字符占位,然后再把密文复制进去之后再运行程序解密。 运行之后可以看到我们已经成功解出了 flag。  ### 魔改RC4 >YLCTF xorplus - 分析 ida 反编译,从函数名称就可以判断为 rc4 加密,接下来我们寻找密钥。  在主函数中找到密钥,然后分析 rc4 算法是否是标准 rc4。  分析发现在 rc4 初始化部分存在魔改,即`v8 = (v8 + *(k + a1) + v9[k] + 1300) % 256;`。 接下来分析一下加密部分。  算法加密部分同样存在魔改,`*(a2 + i) = (*(v8 + a1) ^ *(a2 + i)) + 20;`。  最后我们获取平台给的密文,然后根据魔改后的加密代码逻辑编写解密代码。 - exp ```python enc=[0x91,0x86,0x1b,0x2d,0x9e,0x6f,0x58,0x31,0x46,0xf0,0xed,0xa2,0xcc,0x90,0x22,0x15,0x8d,0xa2,0x61,0x2d,0x80,0x5a,0x74,0x16,0x6c,0x75,0x81,0x46,0x7e,0x26,0xb5,0x9f,0x85,0x76,0x5d,0xfe,0xb7,0x52,0x54,0xc8,0x4,0x35,0xa6] s=[0]*256 key="welcometoylctf" for i in range(256): s[i]=i v6 = 0 for j in range(256): v6=(ord(key[j%len(key)])+v6+s[j] + 1300)%256 s[j],s[v6]=s[v6],s[j] v7 = 0 v8 = 0 for k in range(len(enc)): v8 = (v8 + 1) % 256 v7 = (v7 + s[v8]) % 256 s[v8],s[v7]=s[v7],s[v8] enc[k] = (enc[k] - 20) & 0xff enc[k] ^= s[(s[v7] + s[v8]) % 256] print(bytes(enc)) ``` ## 参考 ><a href="elink@c71K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3e0h3!0G2L8h3W2F1i4K6u0r3M7q4)9J5c8U0p5#2x3o6t1K6y4U0l9I4i4K6u0W2K9s2c8E0L8q4)9J5x3#2)9J5y4f1f1&6i4K6t1#2z5o6m8Q4x3U0f1^5y4W2)9J5y4f1f1#2i4K6t1#2z5e0m8Q4x3U0f1&6x3g2)9J5y4f1f1#2i4K6t1#2z5o6S2Q4x3U0f1^5y4W2)9J5y4f1f1$3i4K6t1#2z5f1g2Q4x3U0f1&6x3l9`.`.">RC4加密算法与逆向方法分析</a> >CTF 从0到1
登录后可查看完整内容
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
上传的附件:
rc4.zip
(33.69kb,19次下载)
收藏
・
1
点赞
・
4
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
0xEA
感谢你分享这么好的资源!
2025-11-11 15:39
马来
你的帖子非常有用,感谢分享!
2025-11-11 10:32
huangjw
+1
谢谢你的细致分析,受益匪浅!
2025-11-11 09:09
我的小拇指啊
感谢你的贡献,论坛因你而更加精彩!
2025-11-9 20:47
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
1
)
huangjw
雪 币:
6679
活跃值:
(11862)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
510
粉丝
2
关注
私信
huangjw
2
楼
算法目前是想进阶的
2025-11-11 09:10
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
南行
3
6
发帖
5
回帖
140
RANK
关注
私信
他的文章
[原创]Linux内核modprobe_path覆盖利用技术
19219
[原创]RC4算法逆向分析
12405
[原创]SMC自修改代码
12802
花指令分析
13355
[原创Linux程序保护机制
7236
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
谁下载
×
huangyalei
SnowRen
startion
智童
softCracker
青峰s
wx_Lebron
ONewTach
mb_aicedybu
mb_birmgglx
npc0vo
jyotidwi
mb_hltizgkc
mb_pkglkcrb
mb_wwemgfqm
mb_lthgjpwj
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部