首页
社区
课程
招聘
加密算法练习(RSA)
发表于: 2006-8-8 16:49 9395

加密算法练习(RSA)

2006-8-8 16:49
9395

【破文标题】RSA算法初探
【破文作者】逍遥风
【破解工具】od,
【破解平台】winxp
----------------------------------------------------------------------
一个标准的RSA算法练习的CRACKME。没有加壳之类的保护措施,很容易分析

用OD载入这个CRACKME
在命令行下断点:bp GetDlgItemTextA:
任意输入注册信息后程序中断在这里:
004137FE  |.  FF15 10894200 call    [<&USER32.GetDlgItemTex>; \GetDlgItemTextA
00413804  |.  EB 13         jmp     short 00413819          ;  取注册码的位数
00413806  |>  FF75 10       push    dword ptr [ebp+10]
。。。
00413819  |> \5D            pop     ebp
0041381A  \.  C2 0C00       retn    0C
运行到这里返回,返回到这里
00402871   .  E8 720F0100   call    004137E8                ; \取输入的注册码
00402876   .  8D4C24 24     lea     ecx, [esp+24]           ;  使ECX等于输入的注册码
0040287A   .  51            push    ecx                     ; /Arg1
0040287B   .  8BCB          mov     ecx, ebx                ; |
0040287D   .  E8 2E010000   call    004029B0                ; \关键CALL跟进
00402882   .  85C0          test    eax, eax                ;  标志位检查
00402884   .  0F84 88000000 je      00402912                ;  相等就注册成功
跟进关键CALL
004029B0  /$  6A FF         push    -1                      ;  来到这里
004029B2  |.  68 189E4100   push    00419E18               
省略一些代码。。。
004029CD  |.  68 DC004200   push    004200DC                ;  9901
004029D2  |.  8D8C24 E40000>lea     ecx, [esp+E4]           ;  RSA计算的e
004029D9  |.  E8 52E7FFFF   call    00401130                ;  取数字9901
** 注意这里的数字9901就是后面RSA计算所需要的e **
004029DE  |.  68 D0004200   push    004200D0                ;  12790891
004029E3  |.  8D4C24 1C     lea     ecx, [esp+1C]           ;  RSA计算的n
004029E7  |.  C78424 640600>mov     dword ptr [esp+664], 0
004029F2  |.  E8 39E7FFFF   call    00401130                ;  取数字12790891
** 注意这里的数字12790891就是后面RSA计算所需要的n **
004029F7  |.  68 C8004200   push    004200C8                ;  8483678
004029FC  |.  8D8C24 740200>lea     ecx, [esp+274]          ;  将数字8483678设为A
00402A03  |.  C68424 640600>mov     byte ptr [esp+664], 1
00402A0B  |.  E8 20E7FFFF   call    00401130                ;  取数字8483678
00402A10  |.  68 C0004200   push    004200C0                ;  5666933
00402A15  |.  8D8C24 AC0100>lea     ecx, [esp+1AC]          ;  将数字5666933设为B
00402A1C  |.  C68424 640600>mov     byte ptr [esp+664], 2
00402A24  |.  E8 07E7FFFF   call    00401130                ;  取数字5666933

数字A,B与RSA计算无关,但另有它用。
现在得到了RSA计算最关键的e,n。下面就开始对注册信息进行处理:
------------------------------------------------------------
00402A29  |.  8B9424 680600>mov     edx, [esp+668]          ;  使EDX等于输入的注册码
00402A30  |.  83CE FF       or      esi, FFFFFFFF
00402A33  |.  8BFA          mov     edi, edx                ;  使EDI=EDX=输入的注册码
00402A35  |.  8BCE          mov     ecx, esi
00402A37  |.  33C0          xor     eax, eax
00402A39  |.  C68424 600600>mov     byte ptr [esp+660], 3
00402A41  |.  F2:AE         repne   scas byte ptr es:[edi]
00402A43  |.  F7D1          not     ecx
00402A45  |.  49            dec     ecx
00402A46  |.  83F9 0E       cmp     ecx, 0E                 ;  比较输入的注册码的位数是否等于14位
00402A49  |.  0F85 63010000 jnz     00402BB2                ;  注册码不等于14位就跳向失败
00402A4F  |.  33C9          xor     ecx, ecx                ;  清空ECX,开始格式检验
00402A51  |>  8A0411        /mov     al, [ecx+edx]          ;  取输入注册码的每一位进行格式检验
00402A54  |.  3C 30         |cmp     al, 30                 ;  与0比较/
00402A56  |.  0F8C 56010000 |jl      00402BB2               ;  小于0就错误
00402A5C  |.  3C 39         |cmp     al, 39                 ;  与9比较
00402A5E  |.  0F8F 4E010000 |jg      00402BB2               ;  大于9就错误
00402A64  |.  41            |inc     ecx                    ;  每检查一位ECX中的值加1
00402A65  |.  83F9 0E       |cmp     ecx, 0E                ;  检查14位
00402A68  |.^ 7C E7         \jl      short 00402A51         ;  循环检验输入的注册码的每一位都必须是数字
00402A6A  |.  8BC2          mov     eax, edx                ;  经过检验使EAX等于输入的注册码

检查输入的注册码。
输入的注册码必须满足两个条件:
1)注册码必须为14位。2)注册码的每一位必须是数字。
经过了格式验证,下面就要选取合适的信息进行加密了,就是说该选定加密对像了
文章作者逍遥风,写于看雪论坛呵呵!学nbw大哥的防盗版技术
注意:以下以注册码12345678901234为例进行说明。
------------------------------------------------------------
00402A6C  |.  C64424 17 00  mov     byte ptr [esp+17], 0
00402A71  |.  C64424 0F 00  mov     byte ptr [esp+F], 0
省略一些代码。。。
00402A8F  |.  884424 16     mov     [esp+16], al
00402A93  |.  8D42 07       lea     eax, [edx+7]            ;  使EAX等于注册码的后7位
00402A96  |.  8D4C24 10     lea     ecx, [esp+10]           ;  使ECX等于注册码的前7位

这里将输入的14位注册码按7位一组分成了2组
1~7位第一组,8~14位第2组。
可以想到程序是对这2组数据分别进行加密的,当然这只是猜测。到底是如何
计算的还得看后面的代码
-------------------------------------------------------------
00402AB2  |.  E8 79E6FFFF   call    00401130                ;  取数字12790891
00402AB7  |.  8D5424 18     lea     edx, [esp+18]           ;  使EDX等于12790891
00402ABB  |.  8D8424 E00000>lea     eax, [esp+E0]           ;  使EAX等于数字9901
00402AC2  |.  52            push    edx                     ; /取n=12790891准备计算
00402AC3  |.  8D8C24 040400>lea     ecx, [esp+404]          ; |
00402ACA  |.  50            push    eax                     ; |取e=9901准备计算
00402ACB  |.  51            push    ecx                     ; |Arg1
00402ACC  |.  8D8C24 9C0500>lea     ecx, [esp+59C]          ; |取注册码前7位1234567准备计算
00402AD3  |.  C68424 6C0600>mov     byte ptr [esp+66C], 4   ; |
00402ADB  |.  E8 30F8FFFF   call    00402310                ; \进行RSA计算
00402AE0  |.  8D5424 08     lea     edx, [esp+8]            ;  计算结果设为C1=821602

先分别取出了埋藏已久的e(9901)和n(12790891),又取了注册码的第一部分(前七位1234567)
进行了RSA计算,并得到了结果C1
C1=1234567^9901(mod 12790891)=821602
-----------------------------------------------------------------
00402AF4  |.  E8 37E6FFFF   call    00401130                ;  取注册码的后7位8901234
00402AF9  |.  8D4424 18     lea     eax, [esp+18]           ;  使EAX=12790891
00402AFD  |.  8D8C24 E00000>lea     ecx, [esp+E0]           ;  使ECX=9901
00402B04  |.  50            push    eax                     ; /取n=12790891准备计算
00402B05  |.  8D9424 CC0400>lea     edx, [esp+4CC]          ; |
00402B0C  |.  51            push    ecx                     ; |取e=9901准备计算
00402B0D  |.  52            push    edx                     ; |取注册码后7位8901234准备计算
00402B0E  |.  8D8C24 440300>lea     ecx, [esp+344]          ; |
00402B15  |.  C68424 6C0600>mov     byte ptr [esp+66C], 6   ; |
00402B1D  |.  E8 EEF7FFFF   call    00402310                ; \进行RSA计算
00402B22  |.  8D8424 700200>lea     eax, [esp+270]          ;  结果设为C2=5041268

同上:取e与n后再取注册码的后7位,进行RSA计算。并得到C2
C2=8901234^9901(mod 12790891)=5041268
经过两步计算,已经得到了加密的结果,但是又进行怎样的验证呢
--------------------------------------------------------------------
00402B29  |.  8D8C24 000400>lea     ecx, [esp+400]          ;  ECX等于C1=821602
00402B30  |.  50            push    eax                     ;  取数字A=8483678
00402B31  |.  C68424 640600>mov     byte ptr [esp+664], 7
00402B39  |.  E8 82F2FFFF   call    00401DC0                ;  将A与C1进行比较
00402B3E  |.  85C0          test    eax, eax                ;  标志位检查
00402B40  |.  0F84 BF000000 je      00402C05                ;  A与C1相等就跳向成功
00402B46  |.  8D8C24 A80100>lea     ecx, [esp+1A8]          ;  使ECX等于数字B=5666933
00402B4D  |.  51            push    ecx
00402B4E  |.  8D8C24 CC0400>lea     ecx, [esp+4CC]          ;  使ECX等于计算结果C2
00402B55  |.  E8 66F2FFFF   call    00401DC0                ;  将B与C2进行比较
00402B5A  |.  85C0          test    eax, eax                ;  标志位检查
00402B5C  |.  0F84 A3000000 je      00402C05                ;  B与C2相等就跳向成功

原来这个CRACKME的最后验证过程是
用C1与定值A=8483678,进行比较。用C2与定值B=5666933,进行比较
如果比较的结果满足C1=A,C2=B就注册成功了。

由于A和B已知即C1,C2已知。
要求出加密前的值就要用到RSA的解密算法了。
加密:c=m^e mod n;
解密:m=c^d mod n.
目前已知条件还有e=9901,n=12790891。
先分解n
得到:p = 1667 和q = 7673。
再求出d
ed=mod((p-1)(q-1)),用工具得到d=10961333
现在根据解密算法:
可以得到:m= c^d (mod n)
m1=8483678^10961333 (mod 12790891) = 7167622
所以注册码的前7位就是7167622
同理
m2=5666933^10961333 (mod 12790891)= 3196885
所以:正确的注册码就是71676223196885,与注册名无关。
(相关的工具论坛都有下载)
----------------------------------------------------------------------
注意:CRACKME有个小BUG,作者的本意可能是
计算结果满足C1=A,C2=B才能注册成功了,但实际上只要C1=A,且满足14位就可以了
也就是说注册码第一部分必须是7167622但后面7位任意
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
刚刚看好RSA加密算法,找个实例看看,感谢楼主
2006-8-9 10:39
0
雪    币: 333
活跃值: (11)
能力值: ( LV12,RANK:770 )
在线值:
发帖
回帖
粉丝
3
学习学习
2006-8-9 18:13
0
雪    币: 338
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
精彩文章!!
2006-8-9 21:50
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
下下来看看,学一下.
2006-8-17 20:18
0
雪    币: 347
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
非常感谢楼主分享心得!!
下来自己练习下
2006-8-19 19:44
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
7
好像楼主的话有问题

最初由 逍遥风 发布
注意:CRACKME有个小BUG,作者的本意可能是
计算结果满足C1=A,C2=B才能注册成功了,但实际上只要C1=A,且满足14位就可以了
也就是说注册码第一部分必须是7167622但后面7位任意


实际上,只要第一部分的是7167622或者第二部分的是3196885均可,而不是第一部分必须是7167622。
2006-8-22 20:40
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
8
最初由 happytown 发布
好像楼主的话有问题



实际上,只要第一部分的是7167622或者第二部分的是3196885均可,而不是第一部分必须是7167622。


恩!・!~大哥说的确实没错
我考虑的不全面
2006-8-23 10:27
0
游客
登录 | 注册 方可回帖
返回
//