AES算法破解

来源:互联网 发布:mysql查询一周内数据 编辑:程序博客网 时间:2024/05/21 11:41
AES算法基本知识
AES的全称是Advanced Encryption Standard,即高级加密标准。该项目由美国国家标准技术研究所(NIST)于1997年开始启动并征集算法,在2000年确定采用Rijndael 作为其最终算法,并于2001年被美国商务部部长批准为新的联邦信息加密标准(FIPS PUB 197)。
FIPS PUB 197中说明该标准的正式生效日期是2002年5月26日。该标准将被NIST每5年重新评估一次。
AES采用的Rijndael算法的设计者是Joan Daemen(Proton World Int.l)和Vincent Rijmen(Katholieke Universiteit Leuven, ESAT-COSIC),算法的名字来自两人名字中字母的组合。Rijndael是一个对称的分组加密算法,分组长度和密钥长度都可变,可分别单独指定为 128比特,192比特和256比特。但AES中的数据分组长度只采用了Rijndael中的128比特,而不使用192和256比特,密钥长度和 Rijndael的一致,也分别为128比特,192比特和256比特,并分别被称为AES-128,AES-192,AES-256。
AES和传统的分组密码算法不同的是它不采用Feistel结构(比如DES中采用的),而是采用了三个不同的可逆一致变换层:线性混合层、非线性层、密 钥加层。具体的算法数学基础和过程请祥见:http://csrc.nist.gov/publications/fips/fips197/fips- 197.pdf

 

AES算法的识别、跟踪技巧及Crackme实例分析
1 AES算法的判断识别
AES中有自己特殊的S盒与逆S盒,可以将此作为判别标志,比如:S盒开头为:
637C777BF26B6FC53001672BFED7AB76CA82C97DFA5947F0.....
解密过程使用的逆S盒开头为:
52096AD53036A538BF40A39E81F3D7FB7CE339829B2FFF87....
我们用16进制编辑器打开目标文件搜索,或在内存中搜索,如果找到的话就基本可以确定目标是采用AES的算法。
2 AES算法分析的基本技巧
若要跟踪如何加密或解密的过程,那是非常麻烦的。有一个偷懒的办法,一般C语言的实现AES算法都会在正式加密数据前进行初始化密钥,如果这个Call被你找到的话就可以了,因为这个Call会传递key字符串。找到key就意味着我们可以自己用程序来来计算。
3 实例分析
本实例是lordor[Nuke Group]编写的AES算法的Crackme程序(已收录到光盘,文件是crackme.rar)。
首先可以使用peid来检测crackme.exe,看是否加壳了,还好,Lordor特善良,没有加壳,另外peid有一个插件kanal,可以检查文件中是否有已知的加密手段,我们可以在kanal中明确看到该crackme的确使用了Rijndael。
我们用Softice的symbol loader载入并运行crackme.exe。
点击Help->Register,可以看到程序已经给出了一个code:718368679(注意:不同机器不同,我们称其为机器码)。
然后我们在Serial框内随意输入一个序列号,用Softice下一个断点bpx getdlgitemtexta,
然后点击Check,我们就会发现下面的代码:
:00401248 MOV ESI,[ESP+000004A4]
:0040124F PUSH 32
:00401251 PUSH 0040E374
:00401256 PUSH 000003E9
:0040125B PUSH ESI
:0040125C CALL [USER32!GetDlgItemTextA] ;这个Call后,我们在40E374就可以看到刚才随意输入的序列号!
:00401262 PUSH 00
:00401264 PUSH 00
:00401266 PUSH 000003E8
:0040126B PUSH ESI
:0040126C CALL [USER32!GetDlgItemInt] ;这个Call后,EAX返回的是0x2ad16fa7,即十进制的机器码718368679
:00401272 PUSH 10
:00401274 PUSH 0040E340
:00401279 PUSH EAX
:0040127A MOV [ESP+14],EAX
:0040127E CALL 004076E6 ;将机器码0x2ad16fa7转化为字符串形式,即在40E340处放置:"2ad16fa7"
:00401283 ADD ESP,0C
:00401286 PUSH 0040E304
:0040128B PUSH 0040E374
:00401290 LEA ECX,[ESP+24]
:00401294 CALL 004023B0 ;将我们刚才随意输入的序列号用AES加密,放到40E304处!
:00401299 PUSH 0040E304
:0040129E PUSH 0040E374
:004012A3 CALL 00401000 ;将刚才随意输入的序列号转化成16进制形式,又存放到40E304处!! 如果不足16个字节的话将和原来的内容混合;如果刚好16个字节的话将覆盖原来的内容!

:004012A8 XOR EAX,EAX
:004012AA MOV ECX,0000000C
:004012AF MOV EDI,0040E374
:004012B4 REPZ STOSD ;清空40E374处的内容
:004012B6 ADD ESP,08
:004012B9 PUSH 0040E374
:004012BE PUSH 0040E304
:004012C3 LEA ECX,[ESP+24]
:004012C7 STOSW
:004012C9 CALL 004026B0 ;将40E304处的数据用AES解密,得到内部注册码,存放到40E374处
:004012CE MOV EAX,0040E374
:004012D3 LEA EDX,[EAX+01]
:004012D6 MOV CL,[EAX]
:004012D8 INC EAX
:004012D9 TEST CL,CL
:004012DB JNZ 004012D6

:004012DD MOV CL,[0040E374]
:004012E3 SUB EAX,EDX
:004012E5 CMP CL,30 ;比较40E374处第一个字符是否是'0',不是则错误
:004012E8 JNZ 004013B1
:004012EE CMP BYTE PTR [EAX+0040E373],3D ;比较最后一个字符是否是'=',不是则错误
:004012F5 JNZ 004013B1
:004012FB CMP EAX,10 ;比较解密后的字符串长度是否为16,不是则错误
:004012FE JNZ 004013B1

:00401304 MOV EDX,[0040E379]
:0040130A XOR EAX,EAX
:0040130C MOV ECX,0000000C
:00401311 MOV EDI,0040E304
:00401316 REPZ STOSD ;清空40E304处内容
:00401318 MOV ECX,[0040E375]
:0040131E STOSW
:00401320 MOV EAX,[0040E37D]
:00401325 MOV [0040E308],EDX
:0040132B MOV DL,[0040E340]
:00401331 MOV [0040E30C],EAX
:00401336 CMP DL,[0040E308] ;!
:0040133C MOV [0040E304],ECX
:00401342 MOV CX,[0040E381] ;用softice看内存,可以发现这里的代码作用是
:00401349 MOV [0040E310],CX ;截取解密后字符串当中的14个,放置到40E304处.
:00401350 JNZ 004013B1 ;并比较机器码的第1位和16位注册码的第6位,
;不相等则错误
:00401352 PUSH 00
:00401354 PUSH 00408208
:00401359 PUSH 004081CC
:0040135E PUSH 00
:00401360 CALL [USER32!MessageBoxA] ;相等的话显示欢迎信息!
:00401366 MOV AL,[0040E343]
:0040136B CMP AL,[0040E309] ;接着比较机器码的第4位和16位注册码的第7位
:00401371 JNZ 0040138A ;不相等则错误

:00401373 MOV ECX,[0040E33C]
:00401379 PUSH 00000085
:0040137E PUSH ECX
:0040137F CALL [USER32!LoadBitmapA] ;相等的话则显示图片!
:00401385 MOV [0040E338],EAX
:0040138A PUSH ESI
:0040138B CALL [USER32!GetMenu]
:00401391 PUSH 01
注意到这个时候还是无法显示图片,有暗桩!

我们于是在16位注册码某些未确定部分上下断点:
经过多次尝试,使用了bpmd 40e308 r,我们发现在:
:004015EF MOV DL,[0040E344]
:004015F5 CMP DL,[0040E30A] ;将机器码的第5位和16位注册码的第8位比较
:004015FB JNZ 00401663 ;不相等则错误
:004015FD PUSH EBX
:004015FE CALL [USER32!GetDC] ;相等则正式申请显示DC
:00401604 MOV ESI,EAX
:00401606 PUSH ESI
:00401607 CALL [GDI32!CreateCompatibleDC]
这样才真正显示出图片!好正点的女人!


AES算法总结
下面是分析过程中所用的断点:
00) BPX USER32!GetDlgItemTextA
01) BPX 00401350 DO "r eip 401352"
02) BPX 00401371 DO "r eip 401373"
03) BPX 004012E8 DO "r eip 401304"
04) BPMD 40E308 R
05) BPX 004015FB DO "r eip 4015fd"
注册过程实际上是这样的流程:
1)取得用户输入的原始字符串(序列号),进行AES加密;
2)将原始字符串转化成16进制表示,和1)所的的结果重叠存放(如果位数正确的话将覆盖);
3)将2)的结果用AES解密,得到内部注册码。
内部注册码必须符合以下要求:
1) 长度为16字节
2) 开头为 '0',结尾为 '='
3) 第6位必须等于机器码的第1位
4) 第7位必须等于机器码的第4位
5) 第8位必须等于机器码的第5位
6) 其他位没有限制
我们知道AES的算法是对称的,我们就可以构造一个内部注册码,通过AES的加密得到一个原始的可用的序列号。
对于机器码为:718368679的情况,转化为16进制为2ad16fa7,即"2ad16fa7"。我们构造一个:
0^^^^216^^^^^^^= (其中^表示是任意字符)
采用
01234216ABCDEFA=
由于Lordor在编写这个Crackme的时候留了一个后门:
:00401294 CALL 004023B0
这是一个AES加密的呼叫,我们可以直接利用,在注册对话框中直接输入:
01234216ABCDEFA=
然后将断点设到00401294,看内存40E304处就是16进制的原始序列号,翻译成字符串就是:
C07FDE0FC24948F1EE245B28E362B317
AES的算法主要用于对数据的加密,密钥是必须保密的,但本Crackme为了介绍AES算法,而将密钥直接写在程序中,否则地话单纯的数据解密将不可行。
:00401230 PUSH EDI
:00401231 PUSH 10
:00401233 PUSH 10
:00401235 PUSH 00408210
:0040123A LEA EAX,[ESP+18]
:0040123E PUSH EAX ;注意这里
:0040123F LEA ECX,[ESP+2C]
:00401243 CALL 00401840 ;初始化AES
另外Lordor为了方便大家学习,故意留了后门(我也是他告诉我后才明白地。)
四、DES现在与AES将来
在 上一期我们看到了DES的介绍,对比一下,可以发现DES及AES都是属于明文分块加密术,加密与解密对称,但AES作为DES的替代者,解决了DES密 钥过短而存在攻破的可能,目前可以用AES长于256位的密钥来加密数据可以保证极强的安全性。目前在市面上看到较多的是采用DES算法软件注册算法,可 能由于AES刚出来,目前软件用AES当作注册算法一部分还未有大量普及(毕竟DES已经有20多年历史了),不过我们看到AES长密钥的优势会满足现在 加密数据,如与RSA、DSA等公钥算法结合,加密关键密钥,起到极强的安全性。希望大家通过这两期的加密算法的介绍,能够对分组密码术的原理、应用有一 个深入的认识

原创粉丝点击