首页
社区
课程
招聘
[原创][破]CrackMe.REVENGE Crew.WinASM.2006
2007-1-25 11:06 6410

[原创][破]CrackMe.REVENGE Crew.WinASM.2006

2007-1-25 11:06
6410
【文章标题】: [破]CrackMe.REVENGE Crew.WinASM.2006
【文章作者】: HappyTown
【作者主页】: www.pediy.com
【软件名称】: crackme
【软件大小】: 133KB(zip)
【下载地址】: 附件内
【加壳方式】: UPX 0.89.6 - 1.02 / 1.05 - 1.24
【保护方式】: RSA-64 + Base64 + MD5(modified)
【编写语言】: Win32ASM
【使用工具】: OD,IDA,RSATool
【操作平台】: WinXP
【软件介绍】: REVENGE Crew 在2006年的 Official Trial CrackMe
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  因为这是REVENGE Crew在2006年的Official Trial CrackMe,所以,一直没有把这个分析贴出来,现在已经是2007年,应该没事了吧。
  
  试练码:
  Name: happy
  Serial: 9876543210222222-222333333333!
  输入成这种格式的原因在下面。
  
  脱壳,运行来到解密后的关键代码处:
  
  00401DCF   >mov     ebx, 00408E2A                ; ASCII "9876543210222222-222333333333!"
  00401DD4   >add     ebx, 10
  00401DD7   >xor     eax, eax
  00401DD9   >mov     al, [ebx]
  00401DDB   >cmp     eax, 2D                      ; sn第17个字符是否是'-'
  00401DDE  ^>jnz     short 00401DBA
  00401DE0   >mov     ebx, 00408E2A                ; ASCII "9876543210222222-222333333333!"
  00401DE5   >mov     ecx, [408FA4]
  00401DEB   >dec     ecx
  00401DEC   >add     ebx, ecx
  00401DEE   >mov     al, [ebx]
  00401DF0   >cmp     eax, 21                      ; sn最后一个字符是否是'!'
  00401DF3  ^>jnz     short 00401DBA
  00401DF5   >push    11
  00401DF7   >lea     eax, [ebp-14]
  00401DFA   >push    eax
  00401DFB   >call    <jmp.&kernel32.RtlZeroMemory>
  00401E00   >push    0D
  00401E02   >lea     eax, [ebp-28]
  00401E05   >push    eax
  00401E06   >call    <jmp.&kernel32.RtlZeroMemory>
  00401E0B   >push    32
  00401E0D   >push    00408F2A
  00401E12   >call    <jmp.&kernel32.RtlZeroMemory>
  00401E17   >lea     esi, [408E2A]
  00401E1D   >push    10
  00401E1F   >lea     eax, [ebp-14]
  00401E22   >push    eax
  00401E23   >push    esi                          ; sn
  00401E24   >call    <lstrncpy>                         ;取得sn的前16个字符:sn_1
  00401E29   >pushad
  00401E2A   >lea     eax, [ebp-14]
  00401E2D   >push    eax
  00401E2E   >call    <jmp.&kernel32.lstrlen>
  00401E33   >mov     ecx, eax
  00401E35   >lea     ebx, [ebp-14]                ; sn_1
  00401E38   >xor     eax, eax
  00401E3A   >xor     edx, edx
  00401E3C   >mov     al, [ebx]
  00401E3E   >or      al, al                       ; //检测sn_1的字符是否属于0~9,A~F
  00401E40   >je      short 00401E59
  00401E42   >cmp     al, 30
  00401E44   >jb      short 00401E4D
  00401E46   >cmp     al, 39
  00401E48   >ja      short 00401E4D
  00401E4A   >inc     edx
  00401E4B   >jmp     short 00401E56
  00401E4D   >cmp     al, 41
  00401E4F   >jb      short 00401E56
  00401E51   >cmp     al, 46
  00401E53   >ja      short 00401E56
  00401E55   >inc     edx
  00401E56   >inc     ebx
  00401E57  ^>jmp     short 00401E3C
  00401E59   >cmp     edx, 10
  00401E5C  ^>jnz     00401DBA                     ; \\
  00401E62   >popad
  00401E63   >add     esi, 11
  00401E66   >push    0C                                 ; 12
  00401E68   >lea     eax, [ebp-28]
  00401E6B   >push    eax
  00401E6C   >push    esi                          ; sn_2(不包括最后的"!")
  00401E6D   >call    <lstrncpy>
  00401E72   >lea     esi, [ebp-28]
  00401E75   >push    esi                          ; sn_2
  00401E76   >push    0C                           ; 12
  00401E78   >lea     eax, [ebp-28]
  00401E7B   >push    eax                          ; sn_2
  00401E7C   >call    <Base64Decode>               ; sn_2' = Base64Decode(sn_2),只有跟进去才能识别出来
  00401E81   >push    0
  00401E83   >call    <_big_create@4>
  00401E88   >mov     [408F9C], eax
  00401E8D   >push    0
  00401E8F   >call    <_big_create@4>
  00401E94   >mov     [408F8C], eax
  00401E99   >push    0
  00401E9B   >call    <_big_create@4>
  00401EA0   >mov     [408F94], eax
  00401EA5   >push    dword ptr [408F9C]
  00401EAB   >lea     eax, [ebp-14]
  00401EAE   >push    eax                          ; sn_1
  00401EAF   >call    <_big_cinstr@8>
  00401EB4   >push    dword ptr [408F8C]
  00401EBA   >push    0040836D                     ; ASCII "80FCD59237BDF149"
  00401EBF   >call    <_big_cinstr@8>
  00401EC4   >push    dword ptr [408F94]
  00401ECA   >push    0040837E                     ; ASCII "10001"
  00401ECF   >call    <_big_cinstr@8>
  00401ED4   >push    dword ptr [408F9C]           ; sn_1
  00401EDA   >push    dword ptr [408F8C]           ; n
  00401EE0   >push    dword ptr [408F94]           ; e
  00401EE6   >push    dword ptr [408F9C]           ; sn_1
  00401EEC   >call    <_big_powmod@16>             ; sn_1=sn_1^e (mod n)=599420D7ACCA8EE5
  00401EF1   >push    00408F2A
  00401EF6   >push    dword ptr [408F9C]           ; sn_1
  00401EFC   >call    <_big_big_to_bytes@8>
  
  很明显的RSA算法,用RSATool分解n,结果如下:
  n=p*q:
  80FCD59237BDF149
  p:
  B05851CB
  q:
  BB4056BB
  d:
  17911A5C18507F99
  e:
  10001
  
  00401F01   >push    dword ptr [408F8C]
  00401F07   >call    <_big_destroy@4>
  00401F0C   >push    dword ptr [408F94]
  00401F12   >call    <_big_destroy@4>
  00401F17   >push    dword ptr [408F9C]
  00401F1D   >call    <_big_destroy@4>
  00401F22   >lea     eax, [ebp-28]
  00401F25   >push    eax                          ; sn_2'
  00401F26   >push    00408F2A                     ; sn_1 = sn_1 + sn_2'
  00401F2B   >call    <jmp.&kernel32.lstrcat>
  00401F30   >push    00408DF8                     ; name
  00401F35   >call    <jmp.&kernel32.lstrlen>
  00401F3A   >push    00408F5C
  00401F3F   >push    eax                          ; nameLen
  00401F40   >push    00408DF8                     ; name
  00401F45   >call    <MD5(modified)>              ; MD5(name)  ===>跟进去
  
  <MD5(modified)>
  {
    0040202E > >push    ebp
    ......
    00402082   >mov     dword ptr [esi], 4552205B  ; //这4个state常数被更改
    00402088   >mov     dword ptr [esi+4], 474E4556
    0040208F   >mov     dword ptr [esi+8], 72432045
    00402096   >mov     dword ptr [esi+C], 5D207765; \\
    ......
  }
  
  00401F4A   >mov     ecx, eax
  00401F4C   >mov     ebx, 00408DF8                ; ASCII "9062A7B02DF78E2"
  00401F51   >xor     eax, eax
  00401F53   >mov     al, [ebx]                    ; //MD5值小写转大写[MD5(name):"9062a7b02df78e22e50417eed97a3e02"]
  00401F55   >or      al, al                       ; MD5[i]
  00401F57   >je      short 00401F68
  00401F59   >cmp     al, 61
  00401F5B   >jb      short 00401F65
  00401F5D   >cmp     al, 7A
  00401F5F   >ja      short 00401F65
  00401F61   >sub     al, 20
  00401F63   >mov     [ebx], al
  00401F65   >inc     ebx
  00401F66  ^>jmp     short 00401F53               ; \\
  00401F68   >xor     ebx, ebx
  00401F6A   >mov     eax, 00408DF8                ; MD5
  00401F6F   >add     eax, 0F
  00401F72   >mov     byte ptr [eax], 0            ; MD5值第16字符置\null,即MD5值仅取前15位有效
  00401F75   >push    00408F2A                     ; sn_1 = sn_1 + sn_2'
  00401F7A   >push    00408DF8                     ; ASCII "9062A7B02DF78E2"
  00401F7F   >call    <jmp.&kernel32.lstrcmp>
  00401F84   >retn
  
  小总一下程序验证的思路:
  (1) sn_1 = sn_1^e (mod n);
  (2) sn_2'= Base64Decode(sn_2);
  (3) 串接 sn_1(8字节) 和 sn_2'(7字节),并与MD5(name)后的前15字节进行比较判断。
  
  那么注册算法就是:
  (1) 对MD5(name)前8字节进行RSA解密运算生成sn_1;
  (2) 对MD5(name)中间的7字节进行Base64编码生成sn_2;
  (3) 用'-'连接sn_1和sn_2,并在最末端添加一'!'即可。
  
  注册机源代码祥见附件,这里仅给出几组可用的注册码:
  Name:        happy
  Serial:        4B36C7C6B3A5D799-MkRGNzhFMg==!
  
  Name:        看雪学院
  Serial:        142F41BA4C9A496B-MTFCMURDRg==!
  
  因为编辑框背景和输入的字体颜色相同,所以,需要选中方能知道注册成功与否。
  
--------------------------------------------------------------------------------
【经验总结】
  没什么难度嘛,大家只要学习一些密码学的知识,我相信各位都可以加入这些组织。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年01月24日 19:20:42

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
打赏
分享
最新回复 (2)
雪    币: 313
活跃值: (250)
能力值: ( LV9,RANK:650 )
在线值:
发帖
回帖
粉丝
hbqjxhw 16 2007-1-25 21:42
2
0
happytown兄,下面最后一行编译不能通过“\\”

context->state[0] = 0x4552205B;//these state constants have been modified
  context->state[1] = 0x474E4556;
  context->state[2] = 0x72432045;
  context->state[3] = 0x5D207765;\\
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
happytown 31 2007-1-31 15:46
3
0
最初由 hbqjxhw 发布
happytown兄,下面最后一行编译不能通过“\\”

context->state[0] = 0x4552205B;//these state constants have been modified
context->state[1] = 0x474E4556;
context->state[2] = 0x72432045;
........

只是最后一行?我没遇到这问题。
游客
登录 | 注册 方可回帖
返回