CRC32算法逆向分析 秒破解 1-6 文明(全覆盖) 具体实现思路加程序c#
Posted _UYU_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CRC32算法逆向分析 秒破解 1-6 文明(全覆盖) 具体实现思路加程序c#相关的知识,希望对你有一定的参考价值。
前言
书接上文,因为我目前的工作就是审计查看各种代码,再加上多年的开发习惯,所以遇到感兴趣的源码总会多看几眼。经过了几个小时的整理,终于把程序做出来,效果也是比较符合我的预期的。但是因为时间太仓促了,所以代码也是没有做什么美化,完全是随着我的思路一路飘出来的,话不多说先上图看一下效果_,
计算3字节及以下长度明文的时间:
计算4字节长度明文的时间
计算5字节长度明文的时间:
计算6字节长度明文的时间:
按照理论我可以一直写下去 起码到8,9的长度时间也还是在预期之内,甚至再往后可以配合 上一篇的多线程 分段(这次的代码没有使用多线程,也没有对数据进行分段)去处理更长的字符,也是可行的,但是由于这几天确实比较忙,目前仅仅写到明文6的 爆破 就先告一段落了。下面我会详细讲解我的实现思路。
一、crc32的加密算法
首先我们先拿一段查表法的crc32加密代码做一下分析
其中比较核心的就是生成表 与计算两个位置
生成码表:(其中的决定因素是)0xedb88320)
计算CRC32
看完这两个核心的点之后 ,基本上代码逻辑我们就很清楚了,初始crc为0xFFFFFFFF。
0、输入的内容首先 异或(^)0xFFFFFFFF。
1、遍历待加密的每一个字节。
2、将遍历到的字节与上一个crc值 异或^。
3、将异或后的值 与& 0xFF 取8 位 。
4、将上边得的值用作角标 在码表内寻找值。
5、将找到的值与 前一个 crc右移8后的 值进行异或得到。
6、最后将输出的值与 0xFFFFFFFF做异或。
二、分析加密算法 反推算法
1、任意输入字符串 X0, X1, X2, X3, X4…Xn,
都有 CRC32(Xn) ^ 0xFFFFFFFF=(CRC32(Xn-1) >>8 ) ^ crc32[CRC32(Xn-1) &0xff ^ Xn] n>1
接下来我们看一下都有什么操作
异或(^) 这个无关紧要 毕竟是可逆的
右移(>>) 这个会损失 0x12345678 >>8 = 》 0x123456
与(&) 别的代码内可能有影响 但是这里没有什么影响 0x12345678 &0xFF=》0x78
到这里基本上我们就很清楚代码为什么说很难反推了…
因为其中有 右移 操作 >>存在,具体就是每循环一次会舍弃8位,
那么就会在这一级别 增加 0x00 到 0xFF 也就 256 种可能性,那么我么的反推需要计算 256的N次方吗…目前看是的,
但其实实应该是 从 明文长度为4开始 才变成了 256的1次方可能性,明文长度为5时 变为 256的2次方可能性…等等
因为随着分析的深入 我们发现 长度为3字节以内的可能性仅仅为1 也就是说长度为3字节的明文crc32我们是可以直接反推计算的。如何计算呢?
下面就涉及到我们的码表了,首先码表是确定的吗?
是确定的!
那么里面的值重复吗?
不重复!
全篇文字太多 怕大家遗忘我把上面的图引用下来
我们看到加密是通过 下标(上一个 crc值 & 0xFF ^ 当前内容) 来找的 码值,
反推的话 我们就需要根据 码值 来找到对应的 下标。
为了更好理解 我们来拿一个实例解释一下
char 1 的CRC32 值为 0x83DCEFB7
反推的话 首先 0x83DCEFB7 ^ 0xFFFFFFFF =0x7c231048
然后是
value= (value>>8) 异或 …
value >>8 我们知道吗 我们知道一部分 那就是value>> 8 ==0x00???
ok 到这里就不用我再去分析异或的操作了吧~
crc32Table[index] 其实就等与 value ^ 0x00???
起码我们可以知到8位的内容
也就是 0x7c231048 ^ 0x00??? =0x7c???;
然后关键点就来了 我放上一张crc32Table输出的图片
其实根据码表输出函数也可以看出来 ,但是图片更加直观一些,
所有的数据不重复,并且 crcTable[n] >> 24 位 之后 也是不重复的
右移 >>24 0x12345678 >>24 ==>0x12
多么激动!! 我们完全可以制作一张 map 根据我们 仅知道 的 8位来得到 下标 index的值
终于开始写代码了(写代码才是我的强项)我的习惯一般是c# >java >python >c/c++ 所以这套代码还是优先使用c#实现
C#`
//首先定义一个类用来存放 稍后获取到的下标 和 码值
public class index_value
public int index_ get; set;
public ulong value get; set;
public index_value(ulong value, int index_)
this.index_ = index_;
this.value = value;
static Hashtable crc32Map = new Hashtable() ;//创建一个hashTable 用来存放
public void GetCRC32Table()
ulong Crc;
int i,j;
for (i = 0 ;i < 256 ; i ++ )
Crc = ( ulong )i;
for (j = 8 ; j > 0 ; j -- )
if ((Crc & 1 ) == 1 )
Crc = (Crc >> 1 ) ^ 0xEDB88320 ;
else
Crc >>= 1 ;
crc32Map.Add(Crc >> 24, new index_value(Crc, i)) ;
如果这个看着不直观 ,下面还有一个直观的
#region 码值
static Hashtable crc32Map = new Hashtable()
0x0,new index_value(0x0,0),
0x77,new index_value(0x77073096,1),
0xEE,new index_value(0xEE0E612C,2),
0x99,new index_value(0x990951BA,3),
0x7,new index_value(0x76DC419,4),
0x70,new index_value(0x706AF48F,5),
0xE9,new index_value(0xE963A535,6),
0x9E,new index_value(0x9E6495A3,7),
0xE,new index_value(0xEDB8832,8),
0x79,new index_value(0x79DCB8A4,9),
0xE0,new index_value(0xE0D5E91E,10),
0x97,new index_value(0x97D2D988,11),
0x9,new index_value(0x9B64C2B,12),
0x7E,new index_value(0x7EB17CBD,13),
0xE7,new index_value(0xE7B82D07,14),
0x90,new index_value(0x90BF1D91,15),
0x1D,new index_value(0x1DB71064,16),
0x6A,new index_value(0x6AB020F2,17),
0xF3,new index_value(0xF3B97148,18),
0x84,new index_value(0x84BE41DE,19),
0x1A,new index_value(0x1ADAD47D,20),
0x6D,new index_value(0x6DDDE4EB,21),
0xF4,new index_value(0xF4D4B551,22),
0x83,new index_value(0x83D385C7,23),
0x13,new index_value(0x136C9856,24),
0x64,new index_value(0x646BA8C0,25),
0xFD,new index_value(0xFD62F97A,26),
0x8A,new index_value(0x8A65C9EC,27),
0x14,new index_value(0x14015C4F,28),
0x63,new index_value(0x63066CD9,29),
0xFA,new index_value(0xFA0F3D63,30),
0x8D,new index_value(0x8D080DF5,31),
0x3B,new index_value(0x3B6E20C8,32),
0x4C,new index_value(0x4C69105E,33),
0xD5,new index_value(0xD56041E4,34),
0xA2,new index_value(0xA2677172,35),
0x3C,new index_value(0x3C03E4D1,36),
0x4B,new index_value(0x4B04D447,37),
0xD2,new index_value(0xD20D85FD,38),
0xA5,new index_value(0xA50AB56B,39),
0x35,new index_value(0x35B5A8FA,40),
0x42,new index_value(0x42B2986C,41),
0xDB,new index_value(0xDBBBC9D6,42),
0xAC,new index_value(0xACBCF940,43),
0x32,new index_value(0x32D86CE3,44),
0x45,new index_value(0x45DF5C75,45),
0xDC,new index_value(0xDCD60DCF,46),
0xAB,new index_value(0xABD13D59,47),
0x26,new index_value(0x26D930AC,48),
0x51,new index_value(0x51DE003A,49),
0xC8,new index_value(0xC8D75180,50),
0xBF,new index_value(0xBFD06116,51),
0x21,new index_value(0x21B4F4B5,52),
0x56,new index_value(0x56B3C423,53),
0xCF,new index_value(0xCFBA9599,54),
0xB8,new index_value(0xB8BDA50F,55),
0x28,new index_value(0x2802B89E,56),
0x5F,new index_value(0x5F058808,57),
0xC6,new index_value(0xC60CD9B2,58),
0xB1,new index_value(0xB10BE924,59),
0x2F,new index_value(0x2F6F7C87,60),
0x58,new index_value(0x58684C11,61),
0xC1,new index_value(0xC1611DAB,62),
0xB6,new index_value(0xB6662D3D,63),
0x76,new index_value(0x76DC4190,64),
0x1,new index_value(0x1DB7106,65),
0x98,new index_value(0x98D220BC,66),
0xEF,new index_value(0xEFD5102A,67),
0x71,new index_value(0x71B18589,68),
0x6,new index_value(0x6B6B51F,69),
0x9F,new index_value(0x9FBFE4A5,70),
0xE8,new index_value(0xE8B8D433,71),
0x78,new index_value(0x7807C9A2,72),
0xF,new index_value(0xF00F934,73),
0x96,new index_value(0x9609A88E,74),
0xE1,new index_value(0xE10E9818,75),
0x7F,new index_value(0x7F6A0DBB,76),
0x8,new index_value(0x86D3D2D,77),
0x91,new index_value(0x91646C97,78),
0xE6,new index_value(0xE6635C01,79),
0x6B,new index_value(0x6B6B51F4,80),
0x1C,new index_value(0x1C6C6162,81),
0x85,new index_value(0x856530D8,82),
0xF2,new index_value(0xF262004E,83),
0x6C,new index_value(0x6C0695ED,84),
0x1B,new index_value(0x1B01A57B,85),
0x82,new index_value(0x8208F4C1,86),
0xF5,new index_value(0xF50FC457,87),
0x65,new index_value(0x65B0D9C6,88),
0x12,new index_value(0x12B7E950,89),
0x8B,new index_value(0x8BBEB8EA,90),
0xFC,new index_value(0xFCB9887C,91),
0x62,new index_value(0x62DD1DDF,92),
0x15,new index_value(0x15DA2D49,93),
0x8C,new index_value(0x8CD37CF3,94),
0xFB,new index_value(0xFBD44C65,95)CRC32 参数逆向工程可以访问多个示例