能力值:
( LV2,RANK:10 )
51 楼
应该有关系的吧。
在服务器有个对照表,存放了所有的从客户端发回来的数据A与服务器返回给客户端的数据B的对照关系。只有这样,服务器才不用即时运算,而只是匹配数据A,得出数据B并返回给客户端就行了。
这个对照表有2的40次方条记录,也就是大概一千亿条记录。
能力值:
( LV2,RANK:10 )
52 楼
明白你的意思了。
从本地传给网站的数据中有5个字节(40比特),它不在那48字节的随机数之内。
从服务器传回本地有40比特的密钥。
你所说的A与B分别是上面的50比特,它们之间就是按照word/excel的加密机制建立的函数关系,你还没有弄明白啊?
能力值:
( LV2,RANK:10 )
53 楼
[QUOTE=lzype;123456]用抓包工具IRIS 4.07.1发现数据传输中与文档相关的内容为:
发送 engine_data 242个字符(应是121字节16进制数)
接收 key 20 个字符 (应是10字节16进制数,用于解密)
[/QUOTE]
说的是这个东东?
http://bbs.pediy.com/showthread.php?p=369640&highlight=word#post369640
能力值:
( LV2,RANK:10 )
54 楼
是的,我们在讨论联网破译的问题。论坛上曾经有人提到过,也给出了部分研究结果,但没有最终完成。
应该说到现在,问题基本都搞清楚了。
能力值:
( LV2,RANK:10 )
55 楼
必须在word文件中找到一段固定的5字节或全0处”,这5个字节怎么找?
能力值:
( LV2,RANK:10 )
56 楼
固定的5字节或全0的位置是在未加密之前来看的,你用UltraEdit打开几个没有加密的Word文档,放眼瞧去,这样的地方多得要死啊。
不过以我的观点来看,Word文件偏移0x400开始的8个字节固定为0x00,即可利用之。
但是,那几个网站不是利用的这个位置。
能力值:
( LV2,RANK:10 )
57 楼
哦,明白了。谢谢。
那么对照表的生成是不是这样。
//这是rc4加密算法
void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
{
unsigned char t;
unsigned char x;
unsigned char y;
unsigned char* state;
unsigned char xorIndex;
short counter;
x = key->x;
y = key->y;
state = &key->state[0];
for(counter = 0; counter < buffer_len; counter++)
{
x = (x + 1) % 256;
y = (state[x] + y) % 256;
swap_byte(&state[x], &state[y]);
xorIndex = (state[x] + state[y]) % 256;
buffer_ptr[counter] ^= state[xorIndex];
}
key->x = x;
key->y = y;
}
其中:
buffer_ptr:从服务器传回本地有40比特的密钥(范围是0x00 0x00 0x00 0x00 0x00-0xff 0xff 0xff 0xff 0xff)
key:从本地传给网站的数据中有5个字节(40比特)
buffer_len:值总是5
然后做一个2^40个循环(输入buffer_ptr,根据buffer_len来生成key)生成rc4的密钥。是这样吗?
能力值:
( LV2,RANK:10 )
58 楼
“但是,那几个网站不是利用的这个位置”那是利用哪个位置呢?
能力值:
( LV2,RANK:10 )
59 楼
大都看不懂 .
能力值:
( LV2,RANK:10 )
60 楼
To xiaoxinxx:
我认为你提供的rc4算法不完整,缺少了一个阶段。
如果你没意见的话,我可以简单表述一下rc4,并提供我在多个课题中使用过的rc4算法(肯定运算正确)。
如果学术化一点来说的话,rc4加密过程分为两个阶段,第一阶段是密钥调度阶段,将n字节的密钥搅乱成256字节的状态表(最典型的情况是这样);第二阶段是伪随机数(亦称密钥流)生产阶段,即以256字节的状态表为基础,不断交换输出1字节伪随机数(直至满足加密长度的需要)。
能力值:
( LV2,RANK:10 )
61 楼
我改造的rc4算法供参考:
/* rc4.h */
/*
This source code of RC4 algorithm is rewritten by Jeff Chen.
*/
#ifndef HEADER_RC4_H
#define HEADER_RC4_H
#ifdef __cplusplus
extern "C" {
#endif typedef unsigned int UINT4;
typedef unsigned char UCHAR;
/* internal structure used by RC4_KSA & RC4_PRGA */
typedef struct rc4_state
{
UCHAR S[256];
UCHAR i;
UCHAR j;
} RC4_STATE;
void RC4_KSA(UCHAR *rc4key, int KL, RC4_STATE *state);
void RC4_KSA_128(UCHAR *rc4key, RC4_STATE *state);
UCHAR RC4_PRGA(RC4_STATE *state);
void RC4(UCHAR *rc4key, int keylen, UCHAR *keystream, int kslen); #ifdef __cplusplus
}
#endif
#endif /* HEADER_RC4_H */
能力值:
( LV2,RANK:10 )
62 楼
/* rc4.c */
/*
* This source code of RC4 algorithm is rewritten by Jeff Chen.
*/
#include "rc4.h"
/*
* This source code of RC4 algorithm is rewritten by Jeff Chen.
*/
/* 密钥长度为KL字节 */
void RC4_KSA(UCHAR *rc4key, int KL, RC4_STATE *state)
{
/*
* 注意: i不能定义为UCHAR, 否则
* for (i = 0; i < 256; i++)是死循环
*/
int i;
UCHAR j, tmp;
UCHAR *s = state->S;
/* Initialization */
state->i = 0; state->j = 0;
for (i = 0; i < 256; i++) s[i] = i;
/* Scrambling */
j = 0;
for (i = 0; i < 256; i++)
{
j += s[i] + rc4key[i % KL]; // 自动丢弃j的高字节部分
tmp = s[i]; s[i] = s[j]; s[j] = tmp;
}
}
/* 密钥长度固定为16字节 */
void RC4_KSA_128(UCHAR *rc4key, RC4_STATE *state)
{
/*
* 注意: i不能定义为UCHAR, 否则
* for (i = 0; i < 256; i++)是死循环
*/
int i;
UCHAR j, tmp;
UCHAR *s = state->S;
/* Initialization */
state->i = 0; state->j = 0;
for (i = 0; i < 256; i++) s[i] = i;
/* Scrambling */
j = 0;
for (i = 0; i < 256; i++)
{
j += s[i] + rc4key[i & 0x0f]; // 自动丢弃j的高字节部分
tmp = s[i]; s[i] = s[j]; s[j] = tmp;
}
}
/* output one byte of keystream */
UCHAR RC4_PRGA(RC4_STATE *state)
{
UCHAR *s, *i, *j, tmp;
s = state->S;
i = &(state->i);
j = &(state->j);
++*i;
*j += s[*i];
tmp = s[*i]; s[*i] = s[*j]; s[*j] = tmp;
return s[(s[*i] + s[*j]) & 0xff]; // 注意: 必须加上 "& 0xff"
}
/*
Combine the two stage of rc4 algorithm.
output kslen bytes of keystream.
here keylen is the byte length of rc4 key.
*/
void RC4(UCHAR *rc4key, int keylen, UCHAR *keystream, int kslen)
{
int n;
RC4_STATE state;
if (keylen == 16) RC4_KSA_128(rc4key, &state);
else RC4_KSA(rc4key, keylen, &state);
for (n = 0; n < kslen; n++)
keystream[n] = RC4_PRGA(&state);
}
能力值:
( LV2,RANK:10 )
63 楼
现在再来回答你的问题。
word加密。你已基本知道Word的加密过程。给定40比特(5字节)密钥 key 后,经由md5得到128字节的rc4密钥,再通过rc4加密算法(注:包括两个阶段)生产出5字节的伪随机数 ks (密钥流)。
这样就定义出了一个函数关系f,即 5字节key(输入) 映射到 5字节ks(输出)。
按照全查表方式,如果我们事先计算好全部(2^40)个输入的输出结果,这样知道5字节的伪随机数(f的输出),只需一个查表操作就可知f的输入,计算时间为O(1)。
但是全查表方式需要O(2^40)的外存空间,有点大了。所以有人想出了彩虹链时空折衷方式,大大降低了存储空间,但是也增加了计算时间(不过相较于O(2^40)量级,还是要快得多)。这里你读过相关文章,应该了解了。
这样一来,要想快速破解Word密报,问题就归结为如何得到比如5字节的 f 函数的输出,所以进一步追问到Word密报中的固定底码,由它可以立即得到 f 函数的部分输出,通过全查表或者彩虹链查表即可快速得到 f 函数的输入,即5字节密钥。 有了5字节密钥,解密即可瞬间完成。
不知我说清楚了没有?
能力值:
( LV2,RANK:10 )
64 楼
word固定底码的位置问题,只需自己用UE或WinHEX之类的观察几个Word文件就可定出来,不存在啥问题。
那几个网站使用的固定位置在哪里呢?这个需要你去动手调试他们提供的客户端软件,容易搞清楚,我这里就不说了。
能力值:
( LV2,RANK:10 )
65 楼
学习,不错啊
能力值:
( LV2,RANK:10 )
66 楼
谢谢jeffcjh!说得非常清楚,都明白了。
能力值:
( LV2,RANK:10 )
67 楼
"给定40比特(5字节)密钥 key 后,经由md5得到128字节的rc4密钥,再通过rc4加密算法(注:包括两个阶段)生产出5字节的伪随机数 ks (密钥流)。这样就定义出了一个函数关系f,即 5字节key(输入) 映射到 5字节ks(输出)。"
这样的话,5字节key(输入)映射到5字节ks(输出)会不会有碰撞?如果有碰撞的话,怎样解决呢?
能力值:
( LV2,RANK:10 )
68 楼
提得有道理!
的确可能发生碰撞,因为这个函数一般并不是一一映射(双射),所以根据某个输出来查表可能会得到若干个输入。此时如果区分呢?当然有办法,因为Word/Excel中本身就设置了密钥验证条件。还记得那3个16字节的随机数吗?快速破译到目前为止,它们还没有派上用场呢,自然有其用处,即用求得的输入(5字节)派生出rc4密钥来解密第2个16字节和第3个16字节,再对解密结果进行判断,若md5(第2个16字节) == md5(第3个16字节)成立,则该输入正确,否则尝试其他输入。这就是区分方法。
上述分析涉及到的具体细节可以参考最早给你阅读的看雪帖子,里面对3个16字节随机数的作用说得非常清楚了。
能力值:
( LV2,RANK:10 )
69 楼
1、意思是说全查表中的5字节key(输入)A映射到5字节ks(输出)B的关系中,B发生碰撞是正常的,可以返回多个A值给客户端,然后客户端先验证A 值是否正确,如果正确则解密文件内容。是这样吗?
2、A值的范围是不是从0X00 0X00 0X00 0X00 0X00--0XFF 0XFF 0XFF 0XFF 0XFF,循环这个范围的A值,然后产生5字节ks(输出)B的全查表?
3、由于全查表有2^40条记录,大概是1兆条,如果全部放到某个文件或者放到数据库中都不合适,所以我想采用下面这种方法:
a、把这1兆条记录按照5字节ks(输出)B的区间范围分别存放到100万个文件中(此文件为txt文件压缩成rar文件,如果不压缩,那么1兆条记录所占用的磁盘空间大概是10T左右,压缩后占用的磁盘空间缩小为原来的近1/40);
b、把这100万个文件的信息(包括文路径和文件名,以及文件中100万条记录的5字节ks(输出)B的区间范围等信息)都存放到数据库某个表中(称为C表);
c、服务器接收客户端传递回来的5字节ks(输出)B,就查询C表,然后确认此5字节ks(输出)B对应的A所在的文件名和路径(如果做好了B数据的索引,那么查询速度应该是很快的,大概在1秒左右就可以查询出);
d、有了路径和文件名,直接解压并打开此文件,查询此文件中的100万条记录(时间大概是几秒)。
由于我需要的是首先考虑查询速度,其次才是占用的磁盘空间,所以采用此方法,而不采用彩虹链时空折衷方式,此方法有个不好的地方,就是前期要做大量的准备工作,比如对1兆条记录中的5字节ks(输出)B进行排序等。对于此方法,您能不能给点建议和意见?或者有没有其它更加好的方法。再次感谢!
能力值:
( LV2,RANK:10 )
70 楼
1、区分碰撞的工作是网站服务器来做的,所以客户端在提交Doc文件时,会将48字节的随机数发给服务器;
2、f函数的输入(A值)的范围是从0X00 0X00 0X00 0X00 0X00--0XFF 0XFF 0XFF 0XFF 0XFF;
3、记录数2^40不是1兆,而是1024G(即1T)。关于具体实施方法,你已经提出来了,大概差不多,我的意见是:
1)按照(f的输出)B将输入A分类,若存放到100万(2^20)个文件中,那每个文件存有2^20条记录。文件个数是否太多了? 我建议存放到2^16个文件中,每个文件存有2^24条记录比较合适。而每个文件不需以TXT方式保存数据,而是5字节5字节的写入。如果想节省空间,我倒认为可以将文件中的2^24个5字节作一下差分(即相临5字节相减),这样5字节减差的最高2字节绝大多数是0x00(原因你自己思考),不需保存,只需保存3字节;遇到极少数最高2字节不为0x00的,特别处理一下。综合考虑,可以自己设计一个数据结构来保存每个文件的差分序列,使解密时可以还原成原序列,应该不困难;
2)后面你提到的查询计算没啥问题。的确,前期是要做大量的准备工作,但这种工作只做一次,以后就再也不需要了,还是划得来的。
能力值:
( LV2,RANK:10 )
71 楼
1、2^40算出的结果是1099511627776,也就是大概1兆条记录啊。
2、“我建议存放到2^16个文件中,每个文件存有2^24条记录比较合适”-- 好的。
3、“而每个文件不需以TXT方式保存数据,而是5字节5字节的写入”--意思是没有文件类型,而只是有文件名?这样有什么好处呢?而5字节5字节的写入,是不是这种方式:
A B
000102030405 050403020100
A1B2C3D4E5F6 F6E5D4C3B2A1
......
......
4、“如果想节省空间,我倒认为可以将文件中的2^24个5字节作一下差分(即相临5字节相减),这样5字节减差的最高2字节绝大多数是0x00(原因你自己思考),不需保存,只需保存3字节;遇到极少数最高2字节不为0x00的,特别处理一下。”--文件还有没有压缩的必要呢?因为如果压缩的话,所占用的磁盘空间大大缩小了,而如果机器性能好的话,查询速度应该不会有多大的影响吧。
5、由于要对2^40条记录的字节ks(输出)B进行排序,所以事先要做好准备工作,这个准备工作有两种方法:
a、在完成全查表的生成之后再做进行排序;这样做的好处就是生成全查表的速度快,但是后面的工作就很麻烦了;
b、在生成全查表的过程中就开始做。比如事先约定好某条记录按照字节ks(输出)B的区间范围来确定它所属的文件,生成这条记录时就插入到所属的文件中。这种方法生成全查表的速度慢,但是一旦生成完,那么排序的工作就几乎完成了。
我打算选择第二中方法,您的建议呢?或者有没有其它更好的方法?
能力值:
( LV2,RANK:10 )
72 楼
1、通常所说的1兆是指2^20,你是否理解有误?
2、文件名信息不需要存入那2^16个纯数据文件中。每个这样的文件平均保存2^24个记录,这里的所谓记录其实就是(f函数的)输入A,每个都是5字节,所以我说是5字节5字节的写入,当然最后可以对每个文件中的2^24个A进行升序排列。 注意:这个文件中的2^24个A(f的输入)对应的是同一个输出B,所以我们将它们纠集在一个文件中,这样根据B查表的时候,只需在这个文件中进行遍历即可;
3、你所说的对每个文件进行压缩是可以的,具体要看压缩率。我所说的对每个文件的2^24个A(升序排列后)进行差分得到差分序列,序列中的每一项(除第1项外,因为它是原始的)基本上最高三个字节都为0x00(前面说的最高2字节为0x00,有点小错误),这样就只需保存低2字节了。
4、按照前面我说的思路,就不存在“事先就要对2^40个ks(输出)B进行快速排序”这个问题了,因为对2^40条记录已经被摊分到2^16个文件中去了,只需对每个文件中的2^24个A进行排序。当然这个计算有点花时间,不知你能否做得起,一般是要在集群机上才能完成的,单机跑的话时间有点长。
能力值:
( LV2,RANK:10 )
73 楼
1、哦。是我理解有误了。在没有压缩和其它任何处理的情况下,产生的全查表大概占多大的磁盘空间呢?
2、因为我还没有生成这个全查表,所以不清楚B记录的关系,按照您说的意思,B记录存在大量的碰撞,也就是说,同一个B值,会有2^24个A值(f的输入)的对应?在2^16个文件中,每个文件中的只需要存放A值就够了,因为这些A值所对应的B值都是一样的?如果这样的话,不会存在根据客户端传回的B值而查询不到A值的情况吧。
3、OK。
4、这样说的话,前期的主要准备工作就不是对B值进行排序,而是把相同的B值划分到同一个文件中了(有什么效率比较高的方法吗)?那么查询速度的瓶颈就在于查询这个有2^24个A的文件上了?
谢谢jeffcjh!如果没有您的帮助,估计我会走很多很多的弯路。而现在节约了非常多的时间!太感谢了!
能力值:
( LV2,RANK:10 )
74 楼
强烈建议LZ重新发一个新贴,因为我们现在讨论的问题与此帖标题“office二进制文件格式”严重不符了。建议以“对office加密的快速破译问题的研究”之类的名字发新贴,我们再讨论之。
能力值:
( LV2,RANK:10 )
75 楼
希望楼主在新贴中将你到目前为止的认识简要地按照步骤表述出来,对第一次出现的名词(术语)进行解释,以后就直接引用了。
强烈希望看雪论坛有更多的人能够参与此类讨论和分析。一天到晚谈破解,烦不烦啊。