能力值:
( LV6,RANK:80 )
101 楼
希望哪天国产的Winmount 取代WINRAR
能力值:
( LV2,RANK:10 )
102 楼
这里没有对错只有技术。楼主是个好同志。
能力值:
( LV2,RANK:10 )
103 楼
期待原理啊,大哥,跪求原理
能力值:
( LV12,RANK:1000 )
104 楼
Are you a good gay or a good lesbian ? Just kidding.Cracking winrar is just for fun! Once you have an idea,you must turn it into reallity.I have the idea and I do.
能力值:
( LV12,RANK:1000 )
105 楼
其实没一点技术含量,高手莫笑。前提是你要知道rar加密后文件的格式,我没找到现成的只好自己逆(见坛子里winrar加密分析一文);其次要知道加密格式中哪些地方可以隐藏密码信息。通过调试明确了salt的用途,它非常适合隐藏密码。那么如何隐藏呢?关键就是找到生成salt的地方,替换它的算法将密码信息赋予生成的salt。当然肯定还有别的地方可以隐藏密码信息,大家可以试试。本人非计算机从业人员,纯属业余爱好。鄙视看不起菜鸟的所谓“牛人”。
能力值:
( LV2,RANK:10 )
106 楼
太牛了.....小电影这下没办法收费了...
能力值:
( LV12,RANK:300 )
107 楼
看了楼主给的文件,再学习一下RAR文件头结构,算是明白楼主的意思:
RAR加密的原理,是将UNICODE格式的密码,与随机生成的一个8字节的SALT连在一起,根据它生成AES算法的密钥来进行加密。
而加密后的RAR中,除了加密后的原压缩内容之外,文件头结构还保存了这个SALT值用于解密。
原则上SALT的生成过程跟用户输入时的密码一点关系都没有,因此它本来不保存关于密码的显式信息,但是我们可以对WINRAR程序进行patch,使SALT跟密码发生直接联系,从而使这个SALT成为潜在的“后门”。
由于SALT只有8个字节,所以对于8个字节以内的密码,可以直接保存在SALT中(或者简单的XOR一下或其他,反正可以用很容易的可逆的算法处理)。
那么密码超出8字节怎么办?这里楼主分为两种方式处理,分别是实例一和实例二。
实例一应该是利用了把文件头的HEAD_SIZE字段改大 ,这样文件头多出来的地方(WINRAR读取文件头时是跳过这部分的)就可以保存密码8字节以后的内容。实例一中的65h-6ch内容就是SALT,而6dh-71h就属于把HEAD_SIZE改大之后多出来的部分了。
但是实例一这种方法应用的前提是文件头没加密。如果文件头被加密(这时MAIN_HEAD的HEAD_FLAGS包含0x0080),那么MAIN_HEAD后面紧跟着的就是SALT(实例二的14h-1bh内容),SALT后面则是被加密的所有内容(包括文件头)。那么怎么把密码8字节以后部分搞进去?实例二的做法,我猜是因为加密过程是16字节为一组,加密后的内容也应该是16字节的倍数,所以解密时也以16字节为单位读取,当文件内容最后跟着一段小于16字节的数据时,WINRAR解密时直接无视这段数据。于是就可以把密码的后半部分放在文件最后(但是不能超过16字节),这样用这种方法可以保存不超过23字节的密码。
按照这个思路,我调试了一下我电脑上的WINRAR 3.70。
我只考虑密码不超过8字节,实际上问题就是找到WINRAR程序操作压缩的过程,在程序把SALT和密码连在一起之前,把SALT改为和密码一样,这样压缩出来的就是那样的文件了。超过8字节的代码只要按照上述思路自己修改生成后的RAR就可以了。
具体步骤:
创建一个新RAR文件,OD载入WINRAR程序,F9跑起来,打开这个空RAR文件,往里面添加一个文件,这时WINRAR程序会弹出添加文件到压缩文件的对话框。第一步要做的是在这个对话框保存我们输入的密码时断下。
怎么定位这个并不难,因为当在添加文件的对话框中高级选项卡点击“设置密码”的时候,会弹出输入密码的框,就从拦截这个对话框入手,程序弹出这个子对话框采用的是DialogBoxParamA,只要在这个API上下断就可以断下:
77D3B144 > 8BFF mov edi, edi ; WinRAR.004BB5D0
看堆栈:
0012A404 00482A3B /CALL 到 DialogBoxParamA 来自 WinRAR.00482A36
0012A408 00400000 |hInst = 00400000
0012A40C 004AC73C |pTemplate = "GETPASSWORD2"
0012A410 00040714 |hOwner = 00040714 ('高级',class='#32770',parent=001B06FA)
0012A414 0047D78A |DlgProc = WinRAR.0047D78A
0012A418 0012A428 \lParam = 0012A428
进到调用来源00482A36,看一下调用过程:
00482A1E |. 8D95 7CFFFFFF lea edx, dword ptr [ebp-84]
00482A24 |. 52 push edx ; /lParam
00482A25 |. 68 8AD74700 push 0047D78A ; |DlgProc = WinRAR.0047D78A
00482A2A |. 53 push ebx ; |hOwner
00482A2B |. 68 3CC74A00 push 004AC73C ; |pTemplate = "GETPASSWORD2"
00482A30 |. FF35 48214B00 push dword ptr [4B2148] ; |hInst = 00400000
00482A36 |. E8 95F10100 call <jmp.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00482A3B |. 85C0 test eax, eax
00482A3D |. 0F95C1 setne cl
00482A40 |. 83E1 01 and ecx, 1
00482A43 |. 8BD9 mov ebx, ecx
00482A45 |. 84DB test bl, bl
00482A47 |. 74 15 je short 00482A5E
00482A49 |. 8D85 7CFFFFFF lea eax, dword ptr [ebp-84]
00482A4F |. 50 push eax
00482A50 |. 57 push edi
00482A51 |. E8 2A520100 call 00497C80 ; CopyString
由于对话框调用完后紧接着是一个字符串拷贝,因此可以推断传送给密码对话框的这个lParam参数就是让密码对话框保存密码的位置,对话框关闭之后又将密码Copy到一个全局数据区保存起来(对对话框窗口过程的调试证明这个推测是正确的),而此时的edi就是保存密码的全局数据区地址,这个值是004BB5D0。
在call DialogBoxParamA的下一句下断,F9让密码对话框出现,填写密码(不要超过8字节),按确定,断下了,然后F8观察CopyString的参数证实上面的推测是正确的。
现在仍然在对话框的窗口过程中:
00446AB4 |. E8 27BF0300 call 004829E0
00446AB9 |. 84C0 test al, al
00446ABB |. 74 47 je short 00446B04
00446ABD |. B8 E6000000 mov eax, 0E6
00446AC2 |. 803D D0B54B00>cmp byte ptr [4BB5D0], 0
00446AC9 |. 75 05 jnz short 00446AD0
00446ACB |. 05 F8020000 add eax, 2F8
00446AD0 |> E8 FBBAFCFF call 004125D0
显然后续代码证实了4BB5D0开始的全局数据区的确是在存取密码的。
于是下一步在WINRAR程序从这里取出密码进行加密操作的时候把它断下。
对4BB5D1下硬件访问断点(为什么要下在4BB5D1而不直接在4BB5D0,那是因为如果下在4BB5D0,将会断到大量的cmp byte ptr [4BB5D0], 0,而只有开始读取4BB5D1处才能说明是真正的在读取其内容而不是单独地比较密码是否为空),F9跑起来,完成添加文件对话框的设置点确定关闭这个对话框,OD断下:
00497C53 |. 2BC3 |sub eax, ebx
00497C55 |. 75 26 |jnz short 00497C7D
00497C57 |. 84DB |test bl, bl
00497C59 |. 74 22 |je short 00497C7D
00497C5B |. 8A41 02 |mov al, byte ptr [ecx+2]
00497C5E |. 8A5A 02 |mov bl, byte ptr [edx+2]
这是一个CompareString,Ctrl+F9
0041139D |> /FF75 FC /push dword ptr [ebp-4]
004113A0 |. |69C3 AA000000 |imul eax, ebx, 0AA
004113A6 |. |81C0 303F4A00 |add eax, 004A3F30 ; ASCII ".,];/[]"
004113AC |. |50 |push eax
004113AD |. |E8 82680800 |call 00497C34
004113B2 |. |83C4 08 |add esp, 8 ; 到这里
004113B5 |. |85C0 |test eax, eax
004113B7 |. |0F85 8F000000 |jnz 0041144C
在一个循环里,在下面F4跳出循环:
00411456 |> \807D EB 00 cmp byte ptr [ebp-15], 0
0041145A |. 0F85 0B020000 jnz 0041166B
00411460 |. 8D95 60FEFFFF lea edx, dword ptr [ebp-1A0] ; 保存UNICODE形式的密码
00411466 |. B9 7F000000 mov ecx, 7F
0041146B |. 8B45 FC mov eax, dword ptr [ebp-4] ; 004BB5D0,密码字符串指针
0041146E |. E8 41F0FFFF call 004104B4 ; ANSI转换成UNICODE
00411473 |. 66:C785 5EFFF>mov word ptr [ebp-A2], 0
0041147C |. 8D95 58FDFFFF lea edx, dword ptr [ebp-2A8]
00411482 |. 8D85 60FEFFFF lea eax, dword ptr [ebp-1A0]
00411488 |. B9 00000001 mov ecx, 1000000
0041148D |. E8 42F0FFFF call 004104D4 ; string copy
00411492 |. 8D85 60FEFFFF lea eax, dword ptr [ebp-1A0]
00411498 |. E8 CBF2FFFF call 00410768 ; 取UNICODE字符串长度
0041149D |. 03C0 add eax, eax
0041149F |. 85FF test edi, edi
004114A1 |. 8945 E4 mov dword ptr [ebp-1C], eax
004114A4 |. 74 19 je short 004114BF
004114A6 |. 6A 08 push 8
004114A8 |. 57 push edi
004114A9 |. 8D95 58FDFFFF lea edx, dword ptr [ebp-2A8]
004114AF |. 0355 E4 add edx, dword ptr [ebp-1C]
004114B2 |. 52 push edx
004114B3 |. E8 D8650800 call 00497A90 ; memcpy?
004114B8 |. 83C4 0C add esp, 0C
004114BB |. 8345 E4 08 add dword ptr [ebp-1C], 8
上面这段代码就很清楚了,就是把密码变为UNICODE并把SALT加在后面。因此此时的edi就是保存SALT的指针,数据窗口中观察:
02A32D6C EC D4 D1 4B 47 60 0F 6E 煸袺G`n?.
如果此时不修改这个SALT值,让WINRAR完成整个过程,再在RAR文件中观察文件头结构会发现SALT的确是这个内容。
现在在这里直接把这个位置用密码字符串代替(为了学习楼主,我把密码同样搞成几个标点符号):
02A32D6C 2E 2C 5D 3B 2F 5B 5D 00 .,];/[]
解除断点让WINRAR完成操作。
生成的RAR文件内容:
526172211A0700CF907300000D000000000000003A917424843000200000000800000002FA9EF760CB28553B1D3308002000000073686F772E7478742E2C5D3B2F5B5D007FAA3C3EB323E42592EE85B9EC80F2BAA3389C0C5733224118F8A872B9086EF3C43D7B00400700
WINHEX打开文件,在文件3ch-43h处正是SALT值,也正是我设的密码(只有7个字节,所以最后是00):
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000030 2E 2C 5D 3B .,];
00000040 2F 5B 5D 00 /[].
至此我成功在WINRAR3.70中通过OD调试WINRAR程序实践了楼主所说的内容,显然只剩下把这个过程转化成patch就可以实用化了。
能力值:
( LV9,RANK:610 )
108 楼
呵呵,膜拜小聪~
能力值:
( LV12,RANK:1000 )
109 楼
分析很详细,有个小地方需要注意:文件头加密时,salt是保存了两次,密码可以保存到32位以上。小聪前辈功力深厚,膜拜一下!
能力值:
( LV2,RANK:10 )
110 楼
同一个RAR,2 个文件,2个密码。不行。
能力值:
( LV3,RANK:20 )
111 楼
非常怀疑楼主用65h-71h一段的字符串做密码,然后仿造出来的rar文件。
能力值:
( LV2,RANK:10 )
112 楼
天易、小聪都是大牛啊,看了分析,不管怎么样,这种思想值得菜鸟学习
能力值:
( LV12,RANK:1000 )
113 楼
首先感谢大家的支持,本人其实很菜;其次声明“天易”和“天易love”是两个不同的ID。111楼的兄弟很有创意,如果算伪造那也是winrar自己伪造的,我只是PATCH了它几个字节。如果原版汉化时也顺手patch一下,那世界就乱了:-(没有做不到,只有想不到。我的一百贴就给我自己吧,祝看雪论坛越来越火!
能力值:
( LV2,RANK:10 )
114 楼
强啊,认真学习以下
能力值:
( LV2,RANK:10 )
115 楼
这个看着怎么那么不可思议,不是说不可能被破解吗?
能力值:
( LV2,RANK:10 )
116 楼
给那些喜欢用汉化版的朋友敲了一个警钟。
能力值:
( LV2,RANK:10 )
117 楼
从头看到尾,的确有些创意,后门和攻击可以无孔不入,让人防不胜防.
要对付象LZ所说的补丁,看来要自己写程序先验证原版hash再调用winrar才有些安全啊,必要时还要对winrar的验证数据文件进行加密,呵呵~
能力值:
( LV2,RANK:10 )
118 楼
LZ很牛啊 此帖价值很大 先学习一下
能力值:
( LV3,RANK:20 )
119 楼
测试失败。。。。。。。。。。。。。。。。。
能力值:
( LV12,RANK:1000 )
120 楼
难道是人品问题?
能力值:
( LV2,RANK:15 )
121 楼
能够秒破,那原来的密码是什么?
能力值:
( LV2,RANK:10 )
122 楼
总之一句话 此rar非彼rar 大多人是被标题误导而已
能力值:
( LV2,RANK:10 )
123 楼
回头试试。
能力值:
( LV8,RANK:130 )
124 楼
膜拜楼主,敬佩小聪!
看到小聪的分析,也学习了下!
秒破RAR这个说法不太同意,就是利用RAR加解密过程中的一个漏洞。
这里patch了一个RAR,有兴趣的可以看看。只处理了8位密码以下情况。有时间看看大于8位的情况。
上传的附件:
能力值:
( LV12,RANK:1000 )
125 楼
看来我的“引号”是白加了,如果对你造成了误导,我很遗憾。
“总之一句话 此rar非彼rar 大多人是被标题误导而已”,很认真的告诉你,你的认识完全是低层次的,并不需要动winrar一个字节。说多了又成了误导,实在是心寒!