RC4变种算法分析
RC4算法分析及其变种
链接:https://pan.baidu.com/s/1IBKy1mYugLxsoupbMGeXnA
提取码:4b1b
复制这段内容后打开百度网盘手机App,操作更方便哦
题目Main流程大致如下
sub_402690(*(_QWORD *)&argc, argv, envp);v10 = 'i esaelP';v11 = 'eht tupn';v12 = '\n:galf ';memset(&Size, 0, 0x68uLL);v17 = malloc((size_t)&v14);printf((const char *)&v14, argv, &v10, "%s");v6 = 0LL;v7 = 0LL;v8 = 0LL;v9 = 0LL;scanf((const char *)&v14, argv, &v6, "%32s");v3 = strlen((const char *)&v14);sub_401760((__int64)&v14, (__int64)argv, (__int64)&v10, v17, v3);v4 = strlen((const char *)&v14);sub_40188D((__int64)&v14, (__int64)argv, (__int64)&v6, v17, v4);strlen((const char *)&v14);v16 = sub_401530((__int64)&v14, (_DWORD)argv);v15 = "B4QrGVzkpZVeHssap5HEgWfSQQ0zmMAA";if ( !strcmp((const char *)&v14, (const char *)argv) )puts((const char *)&v14);elseputs((const char *)&v14);return 0;
}
rc4_init
首先查看401760函数,是一个很明显的RC4 s盒初始化,通过动态调试可知key为"Please input the flag\n"
*a4 = 0;a4[1] = 0;v7 = (signed __int64)(a4 + 2);for ( i = 0; i <= 255; ++i )*(_DWORD *)(v7 + 4LL * i) = i;//v8 = 0;result = 0;LOBYTE(v9) = 0;for ( j = 0; j <= 255; ++j ){v6 = *(_DWORD *)(4LL * j + v7);v9 = (unsigned __int8)(v9 + v6 + *(_BYTE *)(v8 + a3));*(_DWORD *)(v7 + 4LL * j) = *(_DWORD *)(4LL * v9 + v7);*(_DWORD *)(v7 + 4LL * v9) = v6;result = ++v8 >= a5;if ( v8 >= a5 )v8 = 0;}return result;
}
rc4变种
继续看40188D函数,便是RC4加密的核心部分,但是异或的数据偏移的部分加上了24
v10 = *a4;v9 = a4[1];v8 = (signed __int64)(a4 + 2);for ( i = 0; i < a5; ++i ){v10 = (unsigned __int8)(v10 + 1);v5 = *(_DWORD *)(4LL * v10 + v8);v9 = (unsigned __int8)(v9 + v5);v6 = *(_DWORD *)(4LL * v9 + v8);*(_DWORD *)(v8 + 4LL * v10) = v6;*(_DWORD *)(v8 + 4LL * v9) = v5;*(_BYTE *)(i + a3) ^= *(_BYTE *)(4LL * (unsigned __int8)(v5 + v6 + 24) + v8);//变种部分}*a4 = v10;result = a4;a4[1] = v9;return result;
}
变种base64
再分析一下函数401530是一个变种的base64
v14 = a4;v15 = a3;v13 = 0;v7 = 0LL;v10 = 0LL;v9 = 0;i = 0;v12 = a3 / 3;v11 = a3 % 3;if ( a3 % 3 > 0 )++v12;v12 = 4 * v12 + 1;v7 = malloc(a1);if ( !v7 )exit(a1);v10 = v7;while ( v9 < v15 ){v11 = 0;v13 = 0;while ( v11 <= 2 && v9 < v15 ){v4 = v9;v13 = (v13 << 8) | *(unsigned __int8 *)(v9++ + v14);++v11;}v13 <<= 8 * (3 - v11);for ( i = 0; i <= 3; ++i ){if ( v11 >= i ){v4 = (v13 >> 6 * (3 - i)) & 0x3F;v6[i] = (v13 >> 6 * (3 - i)) & 0x3F;}else{v6[i] = 64;}v4 = (unsigned __int8)aYrAoywcfben5lb[(char)sub_401711(a1, a2, v4, v6[i])];*v10++ = v4;}}*v10 = 0;return v7;
}
其中还有一个关键函数401711,该函数的作用将字母表向左循环移动了24位,从原先的
yr+aOYWCfBeN5lb8v7QdxZuAMq/J0tTI1RkSimKFwnczo2VXpPshL4_UgjH6DEG39
变成
Mq/J0tTI1RkSimKFwnczo2VXpPshL4_UgjH6DEG39yr+aOYWCfBeN5lb8v7QdxZuA
_int64 __fastcall sub_401711(__int64 a1, __int64 a2, __int64 a3, int a4)
{return (unsigned int)((a4 + 24) % 65);
}
解密算法
base64解密
解密字符为B4QrGVzkpZVeHssap5HEgWfSQQ0zmM==
import binascii
base64_table='Mq/J0tTI1RkSimKFwnczo2VXpPshL4_UgjH6DEG39yr+aOYWCfBeN5lb8v7QdxZu'
base_encode=str(raw_input(u"请输入解密字符"))
counter=base_encode.count("=")
length=len(base_encode)
encode=""
encode_re=""
if(counter==2):a=base64_table.find(base_encode[length-4:length-3])#取前六位a=a<<2b=base64_table.find(base_encode[length-3:length-2])#取2位b=b>>4encode_re=chr(a+b)
if(counter==1):a=base64_table.find(base_encode[length-4:length-3])#第一个字符前6位a=a<<2b=base64_table.find(base_encode[length-3:length-2])#第二个字符前2位b=b>>4encode_re1=chr(a+b)a=base64_table.find(base_encode[length-3:length-2])#第二个字符后4位a=(a&0xf)<<4b=base64_table.find(base_encode[length-2:length-1])#第三个字符前4位b=b>>2encode_re2=chr(a+b)encode_re=encode_re1+encode_re2
length=length-4
if(counter==0):length=length+4
for i in range(0,length,4):#以4个字符为一组a=base64_table.find(base_encode[i:i+1])#第一个字符6位a=a<<2b=base64_table.find(base_encode[i+1:i+2])#第二个字符前2位b=b>>4encode=encode+chr(a+b)a=base64_table.find(base_encode[i+1:i+2])#第二个字符后4位a=((a&0xf)<<4)b=base64_table.find(base_encode[i+2:i+3])#第三个字符前4位b=b>>2encode=encode+chr(a+b)a=base64_table.find(base_encode[i+2:i+3])#取第三个字符后2位a=(a&3)<<6b=base64_table.find(base_encode[i+3:i+4])#取第四个字符6位encode=encode+chr(a+b)
encode=encode+encode_re
print encode
print( binascii.b2a_hex(encode))
print('\n')
变种RC4解密
#include
#include
#include
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{int i = 0, j = 0;//char k[256]={0};unsigned char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i<256; i++) {s[i] = i;k[i] = key[i%Len];}for (i = 0; i<256; i++) {j = (j + s[i] + k[i]) % 256;tmp = s[i];printf("copy for dongdeng");s[i] = s[j];//交换s[i]和s[j]s[j] = tmp;}
}
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;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j];//交换s[x]和s[y]s[j] = tmp;t = (s[i] + s[j]+24)%256 ;Data[k] ^= s[t];}
}
int main()
{unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-boxchar key[256] = { "Please input the flag:\n" };/*BYTE pData[47] = {0x20, 0xC3, 0x1A, 0xAE, 0x97, 0x3C, 0x7A, 0x41, 0xDE, 0xF6, 0x78, 0x15,0xCB, 0x4B, 0x4C, 0xDC, 0x26, 0x55, 0x8B, 0x55, 0xE5, 0xE9, 0x55, 0x75, 0x40, 0x3D, 0x82, 0x13,0xA5, 0x60, 0x13, 0x3B, 0xF5, 0xD8, 0x19, 0x0E, 0x47, 0xCF, 0x5F, 0x5E, 0xDE, 0x9D, 0x14, 0xBD};*///填写加密数据BYTE pData[47] = { 0xc9, 0xde, 0xea, 0x99, 0x64, 0xca, 0x63, 0xe5, 0xb3, 0x89, 0xa6, 0xac, 0x63, 0x58, 0xa5, 0x82, 0xfc, 0x4b, 0xef, 0xb1, 0x13, 0x34};unsigned long len = strlen((char *)pData);int i;printf("pData=%s\n", pData);printf("key=%s,length=%d\n\n", key, strlen(key));rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化printf("完成对S[i]的初始化,如下:\n\n");for (i = 0; i<256; i++){printf("%02X", s[i]);if (i && (i + 1) % 16 == 0)putchar('\n');}printf("\n\n");for (i = 0; i<256; i++)//用s2[i]暂时保留经过初始化的s[i],很重要的!!!{s2[i] = s[i];}//printf("已经初始化,现在加密:\n\n");//rc4_crypt(s, (unsigned char*)pData, len);//加密//printf("pData=%s\n\n", pData);//printf("已经加密,现在解密:\n\n");//rc4_init(s,(unsigned char*)key,strlen(key));//初始化密钥rc4_crypt(s2, (unsigned char*)pData, len);//解密printf("pData=%s\n\n", pData);system("pause");return 0;
}
得到 flag{RC4_4Nd_Ba5E64?!}
总结
这题一开始没有仔细分析RC4没有注意到其为变种,后面分析RC4算法与其异或的数据并不是正常RC4的数据,迫于做出题目没有好好分析,只是将每次异或的数据给获取出来,后面分析了一下异或的偏移和base64字母表的偏移一样为24。用解密代码也解密出来。之前只见过base64,这次也见识了一下变种的RC4。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
