首页
社区
课程
招聘
[原创]HappyTown的第29个CrackMe分析
2006-12-14 19:19 7448

[原创]HappyTown的第29个CrackMe分析

2006-12-14 19:19
7448
【文章标题】: HappyTown的第29个CrackMe分析
【文章作者】: HorstStein
【原贴地址】: http://bbs.pediy.com/showthread.php?s=&threadid=34166
--------------------------------------------------------------------------------
【详细过程】
  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函数比较有意思。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪论坛, 转载请注明作者并保持文章的完整, 谢谢!

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

上传的附件:
收藏
免费 7
打赏
分享
最新回复 (4)
雪    币: 342
活跃值: (318)
能力值: ( LV12,RANK:740 )
在线值:
发帖
回帖
粉丝
aalloverred 18 2006-12-18 19:23
2
0
学习。
我原来的分析思路也可以得到楼主的一个结果的,只不过我数学太差了。我当时得出hash=key^a mod b
(a=53AA4A5D47684616BD856ED3DB0F3899CDE3A052CE2B3011,b=A5DA242D7DD4EACD19819D83)
却解不出这个方程,后来看了ylp1332的Happytown的第35个crackme分析,
http://bbs.pediy.com/showthread.php?threadid=36414
发现只要算出d=b^-1 mod (a-1)就行,计算得到:
d=167E725333DE5002B3D50A1D
所以注册及只要计算key=hash^d mod b就行了。下面是我写的另一个
keygen.
上传的附件:
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
zcg 2006-12-18 21:10
3
0
感谢楼上两位的分享,我暂时还看不懂,留个记号,争取不久以后能学习的到算法。
雪    币: 926
活跃值: (367)
能力值: (RANK:500 )
在线值:
发帖
回帖
粉丝
humourkyo 12 2007-4-28 12:36
4
0
有意思的是这个 一个用户名却对应N个注册码
请大家验证用户名kyo327
sn=227DC4C8480F730CFB0714A55721FA98E3C71F745CC46648
sn=3E740466D7CF6374BA914295DB18E0F477EB1A6E130BB68D
sn=3FB4EAA1341010CB74809AB8B593E6973CCA3C408E7CD4CD
……
其实sn的取值还有无限个

只是源于此
因为要解一个方程
x mod x/a=p    (a,p都是已知的)

另x=(p+n)a+p  那么上面方程可成立
因此n 可取遍所有的自然数.每取一个自然数就对应一个SN   
呵呵比较有意思 !!!
一个用户名竟然有无穷多个注册码相对应.

不知道作者 happytown有没有想到 竟然这个CRACKEME却还有这样的小漏洞

也许这个不能叫漏洞吧!  有点好玩而已.
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
happytown 31 2007-4-28 16:40
5
0
建议你看看公钥加密方面的资料。呵呵
游客
登录 | 注册 方可回帖
返回