前言
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”插件进行识别,使用这些插件能够更好地提高工作效率。