【逆向】RC4编码解码及逆向识别

前言

RC4和DES算法一样,都是对称加密算法,密钥可以同时加密和解密数据。
不同的是DES将数据分组后加解密,而RC4则是以字节流的方式对数据每一个字节进行加解密。
RC4是恶意代码常用算法,因为它体积小易于实现,并且没有明显加密常量,很难使用插件进行识别。

原理

通过密钥(Key 1-256字节),计算得到一个256字节的数组(S盒),然后将S盒中的数据与明文或密文进行异或,以此进行加解密操作。
注意:加解密过程中S盒中的数据会发生改变,所以加密或解密之前需要使用密钥对S盒数据进行重新初始化。

加密过程

1、S盒初始化
2、S盒乱序
3、计算密钥流
4、异或加解密

示例代码

 1 #include "stdafx.h"
 2 #include "stdio.h"
 3 #include <windows.h>
 4 
 5 //初始化
 6 void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len)
 7 {
 8     int i = 0, j = 0;
 9     char t[256] = { 0 };
10     unsigned char tmp = 0;
11 
12     //填充S盒
13     for (i = 0; i < 256; i++)
14     {
15         s[i] = i;                //填充S盒
16         t[i] = key[i%Len];       //临时变量
17     }
18 
19     //S盒乱序
20     for (i = 0; i < 256; i++)
21     {
22         j = (j + s[i] + t[i]) % 256;
23         tmp = s[i];
24         s[i] = s[j];     
25         s[j] = tmp;
26     }
27 }
28 
29 //加解密
30 void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len)
31 {
32     int i = 0, j = 0, t = 0;
33     unsigned long k = 0;
34     unsigned char tmp;
35 
36     for (k = 0; k < Len; k++)
37     {
38         //计算密钥流
39         i = (i + 1) % 256;
40         j = (j + s[i]) % 256;
41 
42         tmp = s[i];
43         s[i] = s[j];      
44         s[j] = tmp;
45 
46         t = (s[i] + s[j]) % 256;
47 
48         // 异或加解密
49         Data[k] ^= s[t];
50     }
51 }
52 
53 //Main
54 int _tmain(int argc, _TCHAR* argv[])
55 {
56     char key[256] = { "123456789" };                    //密钥
57     char pData[512] = "AAAAAAAAA";                      //明文
58     unsigned char s1[256] = { 0 }, s2[256] = { 0 };     //S盒
59     unsigned long len = strlen(pData);                    
60 
61     printf("明文:%s\n", pData);
62 
63     //初始化
64     rc4_init(s1, (unsigned char*)key, strlen(key)); 
65     //加密
66     rc4_crypt(s1, (unsigned char*)pData, len);
67     printf("加密:%s\n", pData);
68     
69     //加密、解密过程中S盒中的数据会发生改变,所以需要2次初始化
70 
71     //初始化
72     rc4_init(s2, (unsigned char*)key, strlen(key)); 
73     //解密
74     rc4_crypt(s2, (unsigned char*)pData, len);
75     printf("解密:%s\n", pData);
76     
77     return 0;
78 }

逆向分析

识别重点
2个长度为256的For循环
S盒乱序时的数据交换
以及最后的异或加解密
使用示例代码生成Demo文件,逆向分析其加密过程。

进入401000初始化函数,查看第一个For循环
循环256次,分别对S盒与T盒(临时变量)进行填充
识别重点是:s盒与t盒的数据填充过程

S盒填充0-255

T盒填充密钥Key,如果密钥为256字节,则直接填充,否则循环填充

进入401000初始化函数,查看第二个For循环
循环256次,对s盒进行乱序(单纯互换数据位置,数值本身并没有改变)
识别重点是:s盒的数据交换过程

进入4010F0解密/解密函数,查看第三个For循环
循环n次,对数据进行加密或解密,其中n为数据长度
识别重点是:For循环结尾,s盒数据与Data数据的异或操作

总结

RC4算法本身实现并不复杂,只要熟悉其加密/解密流程,逆向分析过程中一般都能很好的进行识别。
分析其它标准加密算法基本也是同样的流程,对于自定义的一些加密算法就需要耐心的跟踪分析了。
另外对于标准加密算法,也可以借助PEID的“Krypto ANALyzer”插件,或者IDA的“FindCrypt2”插件进行识别,使用这些插件能够更好地提高工作效率。

posted @ 2020-01-31 22:31  SunsetR  阅读(2208)  评论(0编辑  收藏  举报