Cracker初级教程之blowfish算法破解

一、Blowfish算法简介
Blowfish 加密算法是最早是由Bruce Schneier 于1993年11月发表的,目标是让人们可以用它来逐渐取代当时已经用了十几年并且已经被证明为“不太安全”的DES算法。Blowfish采用了 Feistel迭代结构(16圈), 64比特的输入分组,可变长度的密钥(最长为448bits),最吸引人的是它有非常快的加解密速度以及完全免费的使用许可。
Blowfish的快速是因为它在做加密和解密时主要利用了处理器的XOR和ADD,在实际测试中它比DES,IDEA,RC5等都要快很多。这样,它虽 然不是某些政府所标榜的加密标准,但却获得了自由软件业人士的喜爱,比如Linux下的SSH应用里面就包含了Blowfish算法(包括最新的2.6内 核)。
Blowfish的具体算法可参见/ 上的说明和各种语言实现的源代码(C,JAVA,VB…),这里比较推荐Paul Kocher于1997年用C实现的代码,虽然不是完整实现,但是非常简洁和流畅,适合分析和理解。
二、 blowfish加密算法基本知识
blowfish也是一个分组对称加密算法,Blowfish加密可以分为两部分:
1.密钥预处理:
BlowFish算法的源密钥pbox和sbox是固定的。我们要加密一个信息,需要自己选择一个key, 用这个key对pbox和sbox进行变换,得到下一步信息加密所要用的key_pbox和key_sbox ,由于是在内存中产生大量的子密钥,在加密时直接引用即可,所以在加密时速度非常快。
2.信息加密:
对于64位的明文,分为两部分,进行16轮的的置换等操作,然后输入64位的密文。另外解密过程和加密过程类似。
三、如何识别blowfish加密算法
由于blowfish有内置的初始化固定密钥,所以可以它内置的字符串如:pbox的串:886A3F24D308A385等。或者用peid的插件查看。据此可以判断有可能是用到blowfish密码算法,更精确的判断还得必须懂得一点blowfish的加解密过程。
Blowfish的算法的P盒和S盒非常有特点,它们是π的16进制小数位,比如P盒是:
0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, 0xa4093822L, 0x299f31d0L,
0x082efa98L, 0xec4e6c89L, 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, 0x9216d5d9L, 0x8979fb1bL
S盒共有4个256字(32bit)长的数组,可参考源代码。
四、Crackme实例分析
本实例是lordor[Nuke Group]编写的Blowfish算法的Crackme程序(已收录到光盘,文件是crackme3.rar)。这个Crackme另外使用了DES和 MD5,不是主要的,只是为了让大家熟悉这两种算法。这次我们重点来看一下其中注册流程及blowfish相关的应用。
由于程序没有加壳,可以用ollyDbg调试器载入程序分析。第一关,由于程序的check按键是灰的,看来程序对输入的注册码进行实时的运算并激活,那么就用EnableWindow函数名下断,可以定位下面的代码:
004027B2 PUSH crackme.0040A60C ; /String2 = "4002"
004027B7 LEA EAX,DWORD PTR SS:[ESP+F4] ; |
004027BE PUSH EAX ; |String1脚踩垃圾桶
004027BF MOV BYTE PTR SS:[ESP+FC],BL ; |
004027C6 CALL DWORD PTR DS:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA
004027CC TEST EAX,EAX
004027CE PUSH 3EB ; /ControlID = 3EB (1003.)
004027D3 PUSH EBP ; |hWnd
004027D4 JNZ SHORT crackme.004027FD ; |
004027D6 MOV ECX,DWORD PTR SS:[ESP+F8] ; |
004027DD MOV DWORD PTR DS:[40CDA8],ECX ; |
004027E3 MOV DWORD PTR DS:[40CDAC],EBX ; |
004027E9 CALL DWORD PTR DS:[<&USER32.GetDlgItem>] ; \GetDlgItem
004027EF PUSH 1 ; /Enable = TRUE
004027F1 PUSH EAX ; |hWnd
004027F2 CALL DWORD PTR DS:[<&USER32.EnableWindow>; \EnableWindow
可以发现程序对输入的注册码前面四位是否为4002,如果是,则激活check按键。现在输入4002654321,点击check按键,提示出错:注册码长度不够,这次用MessageBoxA下断,可以定位下面的代码:
0040282D MOV EBP,DWORD PTR DS:[<&KERNEL32.lstrlen>; KERNEL32.lstrlenA; Case 3EB of switch 00402818
00402833 PUSH crackme.0040C794 ; /String = "654321"
00402838 CALL EBP ; \lstrlenA
这里比较是否为16位注册码0040283A CMP EAX,10
0040283D JE SHORT crackme.00402856
0040283F PUSH EBX ; /Style
00402840 PUSH crackme.0040A604 ; |Title = "Error"
00402845 PUSH crackme.0040A5E4 ; |Text = "pls check the lenght of serial"
0040284A PUSH EBX ; |hOwner
0040284B CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00402851 JMP crackme.00402A82
00402856 MOV EDX,DWORD PTR DS:[40C794]
0040285C MOV EAX,DWORD PTR DS:[40C798]
从上面分析可以看到,程序取输入的第5-20位注册码,比较是否为16位,不是则出错。输入20位注册码接着分析注册流程,这次我们从出错的地方向上看:
00402A47 PUSH EBX ; /Style
00402A48 PUSH crackme.0040A5B8 ; |Title = "message"
00402A4D PUSH crackme.0040A598 ; |Text = "sorry,注册不成功,请再试一次!"
00402A52 PUSH EBX ; |hOwner
00402A53 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00402A59 INC DWORD PTR DS:[40CACC]
我们看一下从什么地方跳过来,分别为402935、402943、402a1e。现在我们看一下上面的代码,可以动态分析,如下:
00402861 PUSH 10
00402863 LEA ECX,DWORD PTR SS:[ESP+20]
00402867 PUSH EBX
输入的第5-12位注册码00402868 PUSH ECX
00402869 MOV DWORD PTR SS:[ESP+28],EDX
0040286D MOV DWORD PTR SS:[ESP+2C],EAX
00402871 MOV BYTE PTR SS:[ESP+30],BL
将8位注册码转成十六进制,在eax中会看到00402875 CALL crackme.0040337C
0040287A MOV CL,BYTE PTR DS:[40C79E]
00402880 MOV DL,BYTE PTR DS:[40C79C]
00402886 MOV DWORD PTR SS:[ESP+20],EAX
0040288A MOV AL,BYTE PTR DS:[40C79D]
0040288F MOV BYTE PTR SS:[ESP+2A],CL
00402893 MOV CL,BYTE PTR DS:[40C7A1]
00402899 MOV BYTE PTR SS:[ESP+28],DL
0040289D MOV DL,BYTE PTR DS:[40C79F]
004028A3 MOV BYTE PTR SS:[ESP+29],AL
004028A7 MOV AL,BYTE PTR DS:[40C7A0]
004028AC PUSH 10
004028AE MOV BYTE PTR SS:[ESP+31],CL
004028B2 MOV BYTE PTR SS:[ESP+2F],DL
004028B6 MOV DL,BYTE PTR DS:[40C7A2]
004028BC MOV BYTE PTR SS:[ESP+30],AL
004028C0 MOV AL,BYTE PTR DS:[40C7A3]
004028C5 LEA ECX,DWORD PTR SS:[ESP+2C]
004028C9 PUSH EBX
后面8位注册码004028CA PUSH ECX
004028CB MOV BYTE PTR SS:[ESP+3A],DL
004028CF MOV BYTE PTR SS:[ESP+3B],AL
004028D3 MOV BYTE PTR SS:[ESP+3C],BL
将8位注册码转成十六进制,在eax中会看到004028D7 CALL crackme.0040337C
004028DC PUSH 4
004028DE LEA EDX,DWORD PTR SS:[ESP+140]
004028E5 PUSH crackme.0040CDA8 ; ASCII "4002"
004028EA PUSH EDX
印花胶浆004028EB MOV DWORD PTR SS:[ESP+34],EAX
这个call非常复杂,对照blowfish算法可以确定是在初始化4002密钥。004028EF CALL crackme.004011F0
004028F4 LEA EAX,DWORD PTR SS:[ESP+34]
这里压入低13-20位注册码004028F8 PUSH EAX
004028F9 LEA ECX,DWORD PTR SS:[ESP+3C]
这里压入高5-12位注册码9547900004028FD PUSH ECX
004028FE LEA EDX,DWORD PTR SS:[ESP+150]
这个指向生成的密钥00402905 PUSH EDX
用blowfish解密00402906 CALL crackme.00401140 
0040290B MOV EAX,DWORD PTR DS:[40C760]
00402910 MOV ECX,DWORD PTR DS:[40C764]
00402916 LEA EDX,DWORD PTR SS:[ESP+4C]
0040291A PUSH EDX
0040291B MOV DWORD PTR SS:[ESP+50],EAX
0040291F MOV DWORD PTR SS:[ESP+54],ECX
00402923 MOV BYTE PTR SS:[ESP+58],BL
机器码转换为十六进制00402927 CALL crackme.004031CA
这是上面解密得到的32位0040292C MOV ECX,DWORD PTR SS:[ESP+48]
00402930 ADD ESP,34
这里与机器码作关键比较00402933 CMP ECX,EAX
不等,出错00402935 JNZ crackme.00402A47
解密的另32位与5397fb1(H)比较0040293B CMP DWORD PTR SS:[ESP+10],5397FB1
不等,则出错00402943 JNZ crackme.00402A47
00402949 PUSH 0A
0040294B PUSH crackme.0040CDA8 ; ASCII "4002"
柔性自动化生产线解密有另32位00402950 PUSH DWORD PTR SS:[ESP+18]
00402954 NOP
转化为字符串00402955 CALL crackme.0040820B
0040295A PUSH crackme.0040CDA8 ; ASCII "4002"
这里可以看到在初始化des密钥0040295F CALL crackme.00401CA0
从上面的分析可以看到,由于blowfish解出来的东西要比较两次,所以des的密钥应为第二次比较的值,即为5397fb1(H)。新型建筑模板
…(省略)….
004029F4 LEA ECX,DWORD PTR SS:[ESP+84]
004029FB CALL crackme.00401FF0
00402A00 LEA ECX,DWORD PTR SS:[ESP+DC]
00402A07 PUSH ECX ; /Arg1
00402A08 CALL crackme.00401000 ; \crackme.00401000
00402A0D ADD ESP,4
00402A10 PUSH crackme.0040A5C0 ;/String2= "0eb912e161dcbb916d0d7eb28797c409"
00402A15 PUSH EAX ; |String1
00402A16 CALL DWORD PTR DS:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA
00402A1C TEST EAX,EAX
00402A1E JNZ SHORT crackme.00402A3E
00402A20 PUSH EBX ; /Style
00402A21 PUSH crackme.0040A5B8 ; |Title = "message"
黑方糖00402A26 LEA EDX,DWORD PTR SS:[ESP+30] ; |
00402A2A PUSH EDX ; |Text
00402A2B PUSH EBX ; |hOwner
00402A2C CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
这上面是用des解密信息,再用md5检验成功的信息的md5值,如相等则显示成功。
至此已经分析完整个注册流程,如要注册成功,就要反推注册码:除了前面4位为4002外,后面的16位要这样逆推,用机器码的前面8位,及串 87654321 (即为上面十六进制的:5397fb1(H)),用blowfish密钥4002进行加密,得到的密文即为后面16位注册码。如机器 码:736525449,得到串:7365254487654321,用blowfish加密,得到:df6e7efa15774682。 所以注册码为:4002df6e7efa15774682
五、 blowfish加密算法总结
blowfish是一种对称的加密算法,一般是与公钥算法配合使用,主要用来加密程序运算的过程
中用到的密钥。由于本crackme是为了学习blowfish算法,这个过程是比较简单。实际使用可以对pbox及sbox作些变换,或者对加密算法作 些变形,这样再插入到软件的自己设计的算法中,往往会取得一定的算法强度,cracker要写出注册机,真要花点时间好好学学密码
算法。
六、 使用blowfish加密算法的典型软件
现在使用blowfish加密算法的共享程序非常多,学习了本文所讲的方法后,可能很多读者都想个实际的程序练手,不过需要声明的是:我们旨在提高国内加密解迷的整体水平,不能用本文所讲的技术做触犯法律的事,否则,所带来的一切法律责任自负,与作者和本杂志社无关。
常见的采用blowfish加密算法的程序很多,比如共享软件: Visual Assist.NET、SWF Browser、亿特代理服务器简易版(版本1.5 build0626)。这些软件一般是把blowfish算法插入到自己定义的算法中,以防止别人写出注册机。对付这些软件比较简单的做法是爆破,不过要 完美一点就是学习一下密码算法,写出注册机。

本文发布于:2024-09-21 17:46:08,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/105065.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:算法   加密   程序   加密算法   密钥   注册码
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议