安全中国首页 > 文章中心 > 加密算法
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

HappyTown的第29个CrackMe分析

更新时间:2007-12-19 0:37:56
责任编辑:阿loosen
热 点:
【文章标题】: HappyTown的第29个CrackMe分析
【文章作者】: HorstStein
--------------------------------------------------------------------------------
【详细过程】
  aalloverred已经给出了一种解决方案,我现在从另外的角度分析一下。

  HappyTown的这个crackme有两个要点:
  (1)hash函数的hash_ctx结构填充0而不是0x80;
  (2)所采用的公钥加密算法;
  
  公钥算法描述:
  1.A选择两个数P和Q,它们与(P-1)和(Q-1)互素。
  2.A公布N=PQ作为它的公开密钥。
  3.A计算P’和Q’使得PP’≡1(mod Q-1)和QQ’≡1(mod P-1)成立。
  4.B加密报文M为C=M^N(mod N)。
  5.A通过解M≡C^P’(mod Q)和M≡C^Q’(mod P)求出M。
  
  HappyTown给出了N和Q,使得仅使用除法而不需要分解N即可算出P,方便了很多。
  
  00401610  sub     esp, 104
  00401616  push    ebx
  00401617  push    ebp
  00401618  push    esi
  00401619  push    edi
  0040161A  mov     ecx, 18
  0040161F  xor     eax, eax
  00401621  lea     edi, [esp+B1]
  00401628  mov     byte ptr [esp+B0], 0
  00401630  rep     stos dword ptr es:[edi]
  00401632  stos    word ptr es:[edi]
  00401634  stos    byte ptr es:[edi]
  00401635  mov     ecx, 18
  0040163A  xor     eax, eax
  0040163C  lea     edi, [esp+4D]
  00401640  mov     byte ptr [esp+4C], 0
  00401645  rep     stos dword ptr es:[edi]
  00401647  stos    word ptr es:[edi]
  00401649  stos    byte ptr es:[edi]
  0040164A  xor     eax, eax
  0040164C  push    10                               ;  0x10
  0040164E  mov     [esp+19], eax
  00401652  push    320                              ;  0x320
  00401657  mov     [esp+21], eax
  0040165B  mov     byte ptr [esp+1C], 0
  00401660  mov     [esp+25], eax
  00401664  mov     [esp+29], ax
  00401669  mov     [esp+2B], al
  0040166D  call    <mirsys>
  00401672  push    0
  00401674  mov     dword ptr [eax+234], 10
  0040167E  call    <_mirvar>
  00401683  push    0
  00401685  mov     [esp+38], eax
  00401689  call    <_mirvar>
  0040168E  push    0
  00401690  mov     ebp, eax
  00401692  call    <_mirvar>
  00401697  push    0
  00401699  mov     [esp+28], eax
  0040169D  call    <_mirvar>
  004016A2  push    0
  004016A4  mov     ebx, eax
  004016A6  call    <_mirvar>
  004016AB  mov     esi, [esp+134]
  004016B2  mov     edi, [<&USER32.GetDlgItemTextA>] ;  USER32.GetDlgItemTextA
  004016B8  add     esp, 1C
  004016BB  lea     ecx, [esp+B0]
  004016C2  mov     [esp+24], eax
  004016C6  push    65                               ; /Count = 65 (101.)
  004016C8  push    ecx                              ; |Buffer
  004016C9  push    3E8                              ; |ControlID = 3E8 (1000.)
  004016CE  push    esi                              ; |hWnd
  004016CF  call    edi                              ; \GetDlgItemTextA
  004016D1  cmp     eax, 2                           ;  name的长度不小于2
  004016D4  jnb     short 004016E3
  004016D6  pop     edi
  004016D7  pop     esi
  004016D8  pop     ebp
  004016D9  xor     eax, eax
  004016DB  pop     ebx
  004016DC  add     esp, 104
  004016E2  retn
  004016E3  lea     edx, [esp+4C]
  004016E7  push    65
  004016E9  push    edx
  004016EA  push    3E9
  004016EF  push    esi
  004016F0  call    edi
  004016F2  test    eax, eax                         ;  serial不能为空
  004016F4  jnz     short 00401701
  004016F6  pop     edi
  004016F7  pop     esi
  004016F8  pop     ebp
  004016F9  pop     ebx
  004016FA  add     esp, 104
  00401700  retn
  00401701  mov     al, [esp+4C]
  00401705  test    al, al
  00401707  je      short 0040174C
  00401709  lea     esi, [esp+4C]                    ;  sn
  0040170D  /cmp     dword ptr [40DF90], 1           ;  这个循环检查sn是否是十六进制字符
  00401714  |jle     short 0040172A
  00401716  |xor     eax, eax
  00401718  |push    80
  0040171D  |mov     al, [esi]
  0040171F  |push    eax
  00401720  |call    <__isctype>
  00401725  |add     esp, 8
  00401728  |jmp     short 0040173C
  0040172A  |mov     edx, [40DD84]                   ;  CrackMe_.0040DD8E
  00401730  |xor     ecx, ecx
  00401732  |mov     cl, [esi]
  00401734  |mov     al, [edx+ecx*2]
  00401737  |and     eax, 80
  0040173C  |test    eax, eax
  0040173E  |je      004017E9
  00401744  |mov     al, [esi+1]
  00401747  |inc     esi
  00401748  |test    al, al
  0040174A  \jnz     short 0040170D
  0040174C  lea     eax, [esp+2C]
  00401750  push    eax
  00401751  call    <Hash_Init>
  00401756  lea     edi, [esp+B4]                    ;  name
  0040175D  or      ecx, FFFFFFFF
  00401760  xor     eax, eax
  00401762  lea     edx, [esp+30]
  00401766  repne   scas byte ptr es:[edi]
  00401768  not     ecx
  0040176A  dec     ecx
  0040176B  push    ecx                              ;  name长度
  0040176C  lea     ecx, [esp+B8]
  00401773  push    ecx                              ;  name
  00401774  push    edx                              ;  hash_ctx
  00401775  call    <Hash_Update>
  0040177A  lea     eax, [esp+3C]
  0040177E  lea     ecx, [esp+24]
  00401782  push    eax
  00401783  push    ecx
  00401784  call    <Hash_Final>
  00401789  mov     edx, [esp+28]
  0040178D  lea     eax, [esp+2C]
  00401791  push    edx                              ;  h
  00401792  push    eax                              ;  Hash(name)
  00401793  push    0A                               ;  10位
  00401795  call    <bytes_to_big>                   ;  h=抓取Hash(name)的前10个字节
  0040179A  mov     edi, [esp+4C]
  0040179E  lea     ecx, [esp+70]
  004017A2  push    ecx                              ;  sn
  004017A3  push    edi
  004017A4  call    <_cinstr>
  004017A9  push    0040D0F0                         ;  ASCII "53AA4A5D47684616BD856ED3DB0F3899CDE3A052CE2B3011"
  004017AE  push    ebp                              ;  n
  004017AF  call    <_cinstr>
  004017B4  push    0040D0D4                         ;  ASCII "A5DA242D7DD4EACD19819D83"
  004017B9  push    ebx                              ;  q
  004017BA  call    <_cinstr>
  004017BF  mov     esi, [esp+60]
  004017C3  push    esi                              ;  m
  004017C4  push    ebp                              ;  n
  004017C5  push    ebp                              ;  n
  004017C6  push    edi                              ;  sn
  004017C7  call    <_powmod>                        ;  m=sn^n (mod n)
  004017CC  add     esp, 4C
  004017CF  push    ebx                              ;  q
  004017D0  push    ebx                              ;  q
  004017D1  push    esi                              ;  m
  004017D2  call    <_divide>                        ;  m=m (mod q)
  004017D7  mov     edx, [esp+1C]
  004017DB  push    esi                              ;  m
  004017DC  push    edx                              ;  h
  004017DD  call    <_compare>                       ;  m和h若相等则注册成功,否则失败
  004017E2  add     esp, 14
  004017E5  test    eax, eax
  004017E7  je      short 004017F6
  
  验证过程就是算法的第4步。注册机就更简单了,详见附件。
  给出两组可用的注册码:
  name:HorstStein
  serial:5BD25220B70AE77F47DDF01D
  
  name:pediy
  serial:5ACE4953EB892534B14D4D97
  
--------------------------------------------------------------------------------
【经验总结】
  这个CrackMe使用了障眼法,呵呵。再一就是这个hash函数比较有意思。
 
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪论坛, 转载请注明作者并保持文章的完整, 谢谢!

 
相关文章
一日一文章
 
一日一软件
一日一动画