吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 19445|回复: 31
上一主题 下一主题
收起左侧

[原创] RC4加密算法及逆向方法初探

  [复制链接]
跳转到指定楼层
楼主
kabeo 发表于 2018-9-24 15:19 回帖奖励
本帖最后由 kabeo 于 2018-9-24 15:21 编辑

这里说的逆向仍旧是CTF逆向

RC4加密算法及逆向方法初探

如有转载,请注明出处,博客地址: https://kabeor.cn

加上这篇已经三篇了,看来可以写一个系列了

之前的两篇
CRC校验算法及逆向方法初探
Base-N算法及逆向初探

算法分析

基本介绍

RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一。 ----wiki https://zh.wikipedia.org/zh-hans/RC4

加密(解密)原理

RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。

由于异或运算的对合性,RC4加密解密使用同一套算法。

C代码表示

先来看内部的几个基本变量

  1. S-Box 也就是所谓的S盒,是一个256长度的char型数组,每个单元都是一个字节,算法运行的任何时候,S都包括0-255的8比特数的排列组合,只不过值的位置发生了变换。

  2. 密钥K char key[256] 密钥的长度keylen与明文长度、密钥流的长度没有必然关系

  3. 临时向量k 长度也为256,每个单元也是一个字节。如果密钥的长度是256字节,就直接把密钥的值赋给k,否则,轮转地将密钥的每个字节赋给k

1. 初始化

包含三个参数

参数1是一个256长度的char型数组,定义为: unsigned char sBox[256];

参数2是密钥,其内容可以随便定义:char key[256];

参数3是密钥的长度,Len = strlen(key);

初始化长度为256的S盒。第一个for循环将0到255的互不重复的元素装入S盒。第二个for循环根据密钥打乱S盒。

i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。

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;
        k[i]=key[i%Len];
    }

    for(i=0;i<256;i++)
        {
        j=(j+s[i]+k[i])%256;
        tmp=s[i];
        s[i]=s[j];     //交换s[i]和s[j]
        s[j]=tmp;
    }
}
2. 加解密

包含三个参数

参数1是上边rc4_init函数中,被搅乱的S-box;

参数2是需要加密的数据data;

参数3是data的长度.

每收到一个字节,就进行while循环。通过一定的算法定位S盒中的一个元素,并与输入字节异或,得到k。循环中还改变了S盒。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。

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])%256;
        Data[k]^=s[t];
    }
}
3. 主函数
int main()
{
    unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-box
    char key[256] = { "justfortest" };
    char pData[512] = "这是一个用来加密的数据Data";
    unsigned long len = strlen(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,(unsignedchar*)key,strlen(key));//初始化密钥
    rc4_crypt(s2, (unsigned char*)pData, len);//解密
    printf("pData=%s\n\n", pData);
    return 0;
}

逆向分析

拿今年九月安恒杯 NewDriver这道来看

栈平衡一下,然后f5

限制输入33位
base64加密
rc4加密

base64改了密码表,但结构很清晰,具体识别方法看我上一篇

rc4共有两个函数 sub_E41000,sub_E410E0
下面来具体分析这两个函数,具体解释都放在图里了,看图即可。

sub_E41000 初始化

函数头如下,三个值
sub_E41000(&v6, &v10, strlen(&v10));
对应上面源码
void rc4_init(unsigned char *s,unsigned char *key, unsigned long Len)

伪代码

反汇编

将0到255的互不重复的元素装入S盒

打乱S盒

sub_E410E0 加密

sub_E410E0(&v6, v3, strlen(v3));
对应上面源码
void rc4_crypt(unsigned char *s,unsigned char *Data,unsigned long Len)

伪代码
int __usercall sub_E410E0@<eax>(int result@<eax>, int a2, unsigned int a3)
{
  int v3; // ecx
  int v4; // esi
  unsigned int v5; // edi
  unsigned __int8 v6; // dl

  v3 = 0;
  v4 = 0;
  v5 = 0;
  if ( a3 )
  {
    do
    {
      v3 = (v3 + 1) % 256;
      v6 = *(v3 + result);
      v4 = (v6 + v4) % 256;
      *(v3 + result) = *(v4 + result);
      *(v4 + result) = v6;
      *(v5++ + a2) ^= *((v6 + *(v3 + result)) % 256 + result);  //   Data[k]^=s[t];
    }
    while ( v5 < a3 );
  }
  return result;
}

伪代码看的就很清晰了,IDA分析时将数组按指针形式显示

反汇编

0FFFFFF00h取负就是256

魔改RC4

其实RC4魔改还是比较难的,稍有改变,整个算法就完全不同了。因此,大多数赛题将rc4与其他算法进行组合来加密flag

常见变化位置

  1. 密钥经过上一步的其他加密后传入
  2. s盒内部数据固定
  3. rc4加密后数据进行重加密

总结

个人感觉rc4重点理解算法即可,并且对内部多次限制256次循环,mod256,以及对数据strlen的读取的特点注意即可


参考网址:
https://zh.wikipedia.org/zh-hans/RC4
https://zh.wikipedia.org/wiki/S%E7%9B%92
https://ctf-wiki.github.io/ctf-wiki/crypto/streamcipher/special/rc4/

免费评分

参与人数 10威望 +2 吾爱币 +19 热心值 +9 收起 理由
solly + 1 + 1 我很赞同!
寅儿啊啊啊 + 1 + 1 谢谢@Thanks!
0x指纹 + 1 多谢大佬分析rc加解密算法,很详细,学习了
fanghongjian + 1 + 1 我很赞同!
sunnylds7 + 1 + 1 热心回复!
Ouyang520 + 1 + 1 谢谢@Thanks!
quleilei889 + 1 + 1 热心回复!
ytfrdfiw + 1 + 1 谢谢@Thanks!
Hmily + 2 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zz048xx + 1 + 1 感谢 分享 既然要出系列可以RSA 哦

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| kabeo 发表于 2021-3-20 20:28 |楼主
masa1chi 发表于 2021-3-15 22:38
萌新一时间看不太懂,收藏慢慢研究。请教大佬们这个和wincrypt.h是同样原理的么

就是一种加密算法而已,如果wincrypt.h用了rc4那就是一样的
推荐
 楼主| kabeo 发表于 2018-9-25 12:23 |楼主
ytfrdfiw 发表于 2018-9-25 12:21
楼主功力了得。学习。这个逆向是可以,但解密算法本身,应该不行吧?即常见的4种密码分析方法来达到目标。

rc4 128bit及以上现在还没有攻击方法,因为我分析的是ctf赛题,所以一般直接异或密钥拿flag就行了
3#
.·.·. 发表于 2018-9-24 16:16
RC4
就记得有一个ABABA bias
可以在特殊环境,使用72小时时间,破解通信时候使用的密码
4#
gunxsword 发表于 2018-9-24 19:59
不错不错,感谢分享,好好学学,虽然有用过这个算法,不过对算法的原理,并不是很清楚!
5#
szk 发表于 2018-9-24 20:03
路过  顶礼膜拜ing
6#
hackerxj 发表于 2018-9-24 20:10
rc4 加密的文件 破解难度。。。。
7#
chenjingyes 发表于 2018-9-24 23:57
顶礼膜拜楼主  谢谢分享
头像被屏蔽
8#
sstm 发表于 2018-9-25 09:57
提示: 作者被禁止或删除 内容自动屏蔽
9#
ytfrdfiw 发表于 2018-9-25 12:21
楼主功力了得。学习。这个逆向是可以,但解密算法本身,应该不行吧?即常见的4种密码分析方法来达到目标。
10#
jimo 发表于 2018-9-25 12:22
伪代码这块没怎么太明白,希望可以更详细一点,
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 10:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表