ROR's KeygenMe逆向分析及注册机
ROR's Official KeygenMe是Team ROR在2004年发布的一个正式CrackMe,曾有好事者将它转载到
PEDIY论坛,正好当时被我看到,就收下了。不过一直都没有时间去碰它,直到去年暑假,大概花
了两周的时间认真研究,顺便也学习了不少密码学知识。 可惜的是,当我即将最终搞定它的时候,
我无意中找到了jB的个人主页
,发现这位牛人早在一年之前已经搞定并且将所有资料发布于他的
个人主页。当时十分失望,就没有继续下去。
现在回过头来看,发现这个CrackMe还是挺经典的,它使用了Base24编码、RSA、ECC、SHA
等加密
算法。当时研究这个
CrackMe时所积累的知识,对于我后来逆向ZWT的Windows Keygen帮助非常大。
所以我觉得详细的分析
过程对于新手入门可能会
有一些的帮助,
这正是我今天花这么多时间将详
细过程写下来的主要原因。
我所做的工作有:脱壳、分析、逆向、注册。附件中包含所有代码和资料。以下是详细过程:
1、
PEiD检查
UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
2、脱壳
UPX的壳手脱最快。OD加载,运行到入口点0041086A,然后右键dump之,搞定!
3、
PEiD检查
脱壳后的文件
编译工具
:Microsoft Visual C++ 7.0
用Krypt ANAlyzer插件检查密码学算法:
SHA1 [Compress] :: 000078C2 :: 004078C2
3、IDA加载
在IDA中载入,并加载常用的密码学库的sig。没有发现使用密码学库。不过在
IDA的string窗口中却发现无数的miracl字符串,于是推断使用了miracl库。
通过查找字符串可找到注册算法的实现部分,分析后的汇编代码如下:
rr01:00402A9B align 10h
rr01:00402AA0
rr01:00402AA0 loc_402AA0: ; CODE XREF: rr01:004031D0j
rr01:00402AA0 mov eax, large fs:0
rr01:00402AA6 push 0FFFFFFFFh
rr01:00402AA8 push offset loc_4253FF
rr01:00402AAD push eax
rr01:00402AAE mov large fs:0, esp
rr01:00402AB5 sub esp, 0E0h
rr01:00402ABB push edi
rr01:00402ABC mov edi, ecx
rr01:00402ABE push 256
rr01:00402AC3 push offset UserName ; 用户名放在这里,最长256个字符
rr01:00402AC8 lea ecx, [edi+0C0h]
rr01:00402ACE call sub_4208FF
rr01:00402AD3 push 256
rr01:00402AD8 push offset serial ; 注册码放在这里,最长256个字符
rr01:00402ADD lea ecx, [edi+70h]
rr01:00402AE0 call sub_4208FF
rr01:00402AE5 mov eax, dword_42FF98
rr01:00402AEA mov failed, 0
rr01:00402AF4 mov dword ptr [eax+234h], 10h ; mip->IOBASE = 0x10;
rr01:00402AFE mov eax, offset UserName
rr01:00402B03 lea edx, [eax+1]
rr01:00402B06
rr01:00402B06 loc_402B06: ; CODE XREF: rr01:00402B0Bj
rr01:00402B06 mov cl, [eax]
rr01:00402B08 inc eax
rr01:00402B09 test cl, cl
rr01:00402B0B jnz short loc_402B06
rr01:00402B0D sub eax, edx
rr01:00402B0F mov [esp+4], eax ; 用户名长度,不能为0
rr01:00402B13 jnz short loc_402B3E
rr01:00402B15 push 0
rr01:00402B17 push offset aEnterAName ; "Enter a Name"
rr01:00402B1C push offset aYouNeedAName ; "You need a name!~"
rr01:00402B21 mov ecx, edi
rr01:00402B23 call _MessageBox
rr01:00402B28 pop edi
rr01:00402B29 mov ecx, [esp+0E0h]
rr01:00402B30 mov large fs:0, ecx
rr01:00402B37 add esp, 0ECh
rr01:00402B3D retn
rr01:00402B3E ; ---------------------------------------------------------------------------
rr01:00402B3E
rr01:00402B3E loc_402B3E: ; CODE XREF: rr01:00402B13j
rr01:00402B3E mov eax, offset serial
rr01:00402B43 lea edx, [eax+1]
rr01:00402B46
rr01:00402B46 loc_402B46: ; CODE XREF: rr01:00402B4Bj
rr01:00402B46 mov cl, [eax]
rr01:00402B48 inc eax
rr01:00402B49 test cl, cl
rr01:00402B4B jnz short loc_402B46
rr01:00402B4D sub eax, edx
rr01:00402B4F mov [esp+4], eax ; 注册码的长度,不能为0
rr01:00402B53 jnz short loc_402B7E
rr01:00402B55 push 0
rr01:00402B57 push offset aTryKgMe ; "Try KG me"
rr01:00402B5C push offset aYouNeedAValidS ; "You need a valid SN, keep going!~"
rr01:00402B61 mov ecx, edi
rr01:00402B63 call _MessageBox
rr01:00402B68 pop edi
rr01:00402B69 mov ecx, [esp+0E0h]
rr01:00402B70 mov large fs:0, ecx
rr01:00402B77 add esp, 0ECh
rr01:00402B7D retn
rr01:00402B7E ; ---------------------------------------------------------------------------
rr01:00402B7E
rr01:00402B7E loc_402B7E: ; CODE XREF: rr01:00402B53j
rr01:00402B7E mov eax, offset serial ; 输入的注册码
rr01:00402B83 lea edx, [eax+1]
rr01:00402B86
rr01:00402B86 loc_402B86: ; CODE XREF: rr01:00402B8Bj
rr01:00402B86 mov cl, [eax] ; 以下检查注册码格式
rr01:00402B88 inc eax
rr01:00402B89 test cl, cl
rr01:00402B8B jnz short loc_402B86
rr01:00402B8D sub eax, edx
rr01:00402B8F cmp eax, 29 ; 注册码长度应该是29个字符
rr01:00402B92 push ebx
rr01:00402B93 jnz loc_403122
rr01:00402B99 mov al, byte_42FD8D
rr01:00402B9E mov bl, '-'
rr01:00402BA0 cmp al, bl
rr01:00402BA2 jnz loc_403122
rr01:00402BA8 cmp byte_42FD93, bl
rr01:00402BAE jnz loc_403122
rr01:00402BB4 cmp byte_42FD99, bl
rr01:00402BBA jnz loc_403122
rr01:00402BC0 cmp byte_42FD9F, bl
rr01:00402BC6 jnz loc_403122
rr01:00402BCC push esi
rr01:00402BCD push 0
rr01:00402BCF lea ecx, [esp+18h]
rr01:00402BD3 call sub_402470 ; Big(0);
rr01:00402BD8 mov eax, offset serial
rr01:00402BDD mov dword ptr [esp+0F4h], 0
rr01:00402BE8 xor esi, esi
rr01:00402BEA lea edx, [eax+1]
rr01:00402BED lea ecx, [ecx+0]
rr01:00402BF0
rr01:00402BF0 loc_402BF0: ; CODE XREF: rr01:00402BF5j
rr01:00402BF0 mov cl, [eax]
rr01:00402BF2 inc eax
rr01:00402BF3 test cl, cl
rr01:00402BF5 jnz short loc_402BF0
rr01:00402BF7 sub eax, edx
rr01:00402BF9 mov [esp+0Ch], eax
rr01:00402BFD jz short loc_402C72
rr01:00402BFF nop
rr01:00402C00
rr01:00402C00 loc_402C00: ; CODE XREF: rr01:00402C70j
rr01:00402C00 cmp serial[esi], bl ; 以下对注册码进行Base24解码
rr01:00402C06 jz short loc_402C5C
rr01:00402C08 push 24
rr01:00402C0A lea ecx, [esp+18h]
rr01:00402C0E call sub_4024B0 ; Big::*
rr01:00402C13 movzx ecx, serial[esi]
rr01:00402C1A push ecx
rr01:00402C1B push offset aBcdfghjkmpqrtv ; "BCDFGHJKMPQRTVWXY2346789"
rr01:00402C20 call _strchr
rr01:00402C25 add esp, 8
rr01:00402C28 test eax, eax
rr01:00402C2A jz short loc_402C52
rr01:00402C2C movzx edx, serial[esi]
rr01:00402C33 push edx
rr01:00402C34 push offset aBcdfghjkmpqrtv ; "BCDFGHJKMPQRTVWXY2346789"
rr01:00402C39 call _strchr
rr01:00402C3E add esp, 8
rr01:00402C41 sub eax, offset aBcdfghjkmpqrtv ; "BCDFGHJKMPQRTVWXY2346789"
rr01:00402C46 push eax
rr01:00402C47 lea ecx, [esp+18h]
rr01:00402C4B call Big__incr
rr01:00402C50 jmp short loc_402C5C
rr01:00402C52 ; ---------------------------------------------------------------------------
rr01:00402C52
rr01:00402C52 loc_402C52: ; CODE XREF: rr01:00402C2Aj
rr01:00402C52 mov failed, 1
rr01:00402C5C
rr01:00402C5C loc_402C5C: ; CODE XREF: rr01:00402C06j
rr01:00402C5C ; rr01:00402C50j
rr01:00402C5C mov eax, offset serial
rr01:00402C61 inc esi
rr01:00402C62 lea edx, [eax+1]
rr01:00402C65
rr01:00402C65 loc_402C65: ; CODE XREF: rr01:00402C6Aj
rr01:00402C65 mov cl, [eax]
rr01:00402C67 inc eax
rr01:00402C68 test cl, cl
rr01:00402C6A jnz short loc_402C65
rr01:00402C6C sub eax, edx
rr01:00402C6E cmp esi, eax
rr01:00402C70 jb short loc_402C00
rr01:00402C72
rr01:00402C72 loc_402C72: ; CODE XREF: rr01:00402BFDj
rr01:00402C72 push 1
rr01:00402C74 lea eax, [esp+6Ch]
rr01:00402C78 push eax
rr01:00402C79 lea ecx, [esp+1Ch]
rr01:00402C7D push 16
rr01:00402C7F push ecx
rr01:00402C80 call Big__to_binary
rr01:00402C85 push offset dword_42677C ; N
rr01:00402C8A lea edx, [esp+68h]
rr01:00402C8E push 8
rr01:00402C90 push edx
rr01:00402C91 call Big__from_binary
rr01:00402C96 lea eax, [esp+8Ch]
rr01:00402C9D push eax
rr01:00402C9E lea ecx, [esp+6Ch]
rr01:00402CA2 push 8
rr01:00402CA4 push ecx
rr01:00402CA5 mov byte ptr [esp+11Ch], 1
rr01:00402CAD call Big__from_binary
rr01:00402CB2 push offset dword_426784 ; E
rr01:00402CB7 mov ebx, 4
rr01:00402CBC lea edx, [esp+70h]
rr01:00402CC0 push ebx
rr01:00402CC1 push edx
rr01:00402CC2 mov byte ptr [esp+128h], 2
rr01:00402CCA call Big__from_binary
rr01:00402CCF lea eax, [esp+88h]
rr01:00402CD6 push eax
rr01:00402CD7 lea ecx, [esp+7Ch]
rr01:00402CDB push ecx
rr01:00402CDC lea edx, [esp+88h]
rr01:00402CE3 push edx
rr01:00402CE4 lea eax, [esp+7Ch]
rr01:00402CE8 push eax
rr01:00402CE9 mov byte ptr [esp+138h], 3
rr01:00402CF1 call Big__pow
rr01:00402CF6 add esp, 44h
rr01:00402CF9 lea ecx, [esp+78h]
rr01:00402CFD mov [esp+0F4h], bl
rr01:00402D04 call ??0CRectTracker@@QAE@XZ ; sha1_init_modified
rr01:00402D09 mov eax, offset UserName
rr01:00402D0E mov byte ptr [esp+0F4h], 5
rr01:00402D16 lea edx, [eax+1]
rr01:00402D19 pop esi
rr01:00402D1A lea ebx, [ebx+0]
rr01:00402D20
rr01:00402D20 loc_402D20: ; CODE XREF: rr01:00402D25j
rr01:00402D20 mov cl, [eax]
rr01:00402D22 inc eax
rr01:00402D23 test cl, cl
rr01:00402D25 jnz short loc_402D20
rr01:00402D27 sub eax, edx
rr01:00402D29 push eax
rr01:00402D2A push offset UserName
rr01:00402D2F lea ecx, [esp+7Ch]
rr01:00402D33 call shs_process
rr01:00402D38 push 0Dh
rr01:00402D3A push offset aTeamRor2004 ; "TEAM ROR 2004"
rr01:00402D3F lea ecx, [esp+7Ch]
rr01:00402D43 call shs_process
rr01:00402D48 lea ecx, [esp+74h]
rr01:00402D4C call sha_hash
rr01:00402D51 lea ecx, [esp+20h]
rr01:00402D55 push ecx
rr01:00402D56 lea ecx, [esp+78h]
rr01:00402D5A call sha_hash_out
rr01:00402D5F lea edx, [esp+20h]
rr01:00402D63 push edx
rr01:00402D64 lea eax, [esp+34h]
rr01:00402D68 push 8
rr01:00402D6A push eax
rr01:00402D6B call Big__from_binary
rr01:00402D70 lea ecx, [esp+44h]
rr01:00402D74 push ecx
rr01:00402D75 lea edx, [esp+40h]
rr01:00402D79 push edx
rr01:00402D7A mov byte ptr [esp+104h], 6
rr01:00402D82 call sub_4024F0 ; Big::==
rr01:00402D87 add esp, 14h
rr01:00402D8A test eax, eax
rr01:00402D8C jz short loc_402D98
rr01:00402D8E mov failed, 1
rr01:00402D98
rr01:00402D98 loc_402D98: ; CODE XREF: rr01:00402D8Cj
rr01:00402D98 lea eax, [esp+68h]
rr01:00402D9C push eax
rr01:00402D9D lea ecx, [esp+30h]
rr01:00402DA1 push ebx
rr01:00402DA2 push ecx
rr01:00402DA3 call Big__from_binary
rr01:00402DA8 lea edx, [esp+70h]
rr01:00402DAC push edx
rr01:00402DAD lea eax, [esp+2Ch]
rr01:00402DB1 push ebx
rr01:00402DB2 push eax
rr01:00402DB3 mov byte ptr [esp+108h], 7
rr01:00402DBB call Big__from_binary
rr01:00402DC0 push (offset loc_426767+1) ; p
rr01:00402DC5 lea ecx, [esp+7Ch]
rr01:00402DC9 push ebx
rr01:00402DCA push ecx
rr01:00402DCB mov byte ptr [esp+114h], 8
rr01:00402DD3 call Big__from_binary
rr01:00402DD8 add esp, 24h
rr01:00402DDB push 1 ; a
rr01:00402DDD lea ecx, [esp+48h]
rr01:00402DE1 call sub_402470
rr01:00402DE6 push 0Dh ; b
rr01:00402DE8 lea ecx, [esp+58h]
rr01:00402DEC call sub_402470
rr01:00402DF1 push (offset loc_42676A+2) ; gx
rr01:00402DF6 lea edx, [esp+2Ch]
rr01:00402DFA push ebx
rr01:00402DFB push edx
rr01:00402DFC mov byte ptr [esp+0FCh], 0Bh
rr01:00402E04 call Big__from_binary
rr01:00402E09 push offset dword_426770 ; gy
rr01:00402E0E lea eax, [esp+6Ch]
rr01:00402E12 push ebx
rr01:00402E13 push eax
rr01:00402E14 mov byte ptr [esp+108h], 0Ch
rr01:00402E1C call Big__from_binary
rr01:00402E21 push offset dword_426774 ; kx
rr01:00402E26 lea ecx, [esp+50h]
rr01:00402E2A push ebx
rr01:00402E2B push ecx
rr01:00402E2C mov byte ptr [esp+114h], 0Dh
rr01:00402E34 call Big__from_binary
rr01:00402E39 push offset dword_426778 ; ky
rr01:00402E3E lea edx, [esp+74h]
rr01:00402E42 push ebx
rr01:00402E43 push edx
rr01:00402E44 mov byte ptr [esp+120h], 0Eh
rr01:00402E4C call Big__from_binary
rr01:00402E51 push 0 ; MR_PROJECTIVE 0
rr01:00402E53 lea eax, [esp+94h]
rr01:00402E5A push eax
rr01:00402E5B lea ecx, [esp+8Ch]
rr01:00402E62 push ecx
rr01:00402E63 lea edx, [esp+80h]
rr01:00402E6A push edx
rr01:00402E6B mov byte ptr [esp+130h], 0Fh
rr01:00402E73 call Big__ecurve
rr01:00402E78 add esp, 40h
rr01:00402E7B lea eax, [esp+5Ch]
rr01:00402E7F push eax
rr01:00402E80 lea ecx, [esp+2Ch]
rr01:00402E84 push ecx
rr01:00402E85 lea ecx, [esp+60h]
rr01:00402E89 call ecn_epoint_set
rr01:00402E8E lea edx, [esp+4Ch]
rr01:00402E92 push edx
rr01:00402E93 lea eax, [esp+38h]
rr01:00402E97 mov byte ptr [esp+0F4h], 10h
rr01:00402E9F push eax
rr01:00402EA0 lea ecx, [esp+44h]
rr01:00402EA4 call ecn_epoint_set
rr01:00402EA9 call epoint_init
rr01:00402EAE mov [esp+0Ch], eax
rr01:00402EB2 lea ecx, [esp+3Ch]
rr01:00402EB6 push ecx
rr01:00402EB7 lea edx, [esp+20h]
rr01:00402EBB push edx
rr01:00402EBC lea eax, [esp+10h]
rr01:00402EC0 push eax
rr01:00402EC1 mov byte ptr [esp+0FCh], 12h
rr01:00402EC9 call sub_40C4F0 ; ECn::mul
rr01:00402ECE add esp, 0Ch
rr01:00402ED1 push eax
rr01:00402ED2 lea ecx, [esp+10h]
rr01:00402ED6 call sub_402550
rr01:00402EDB mov ecx, [esp+8]
rr01:00402EDF push ecx
rr01:00402EE0 call sub_40ADB0
rr01:00402EE5 lea edx, [esp+5Ch]
rr01:00402EE9 push edx
rr01:00402EEA lea eax, [esp+34h]
rr01:00402EEE push eax
rr01:00402EEF lea ecx, [esp+14h]
rr01:00402EF3 push ecx
rr01:00402EF4 call sub_40C4F0
rr01:00402EF9 add esp, 10h
rr01:00402EFC push eax
rr01:00402EFD lea ecx, [esp+10h]
rr01:00402F01 call sub_402570
rr01:00402F06 mov edx, [esp+8]
rr01:00402F0A push edx
rr01:00402F0B call sub_40ADB0
rr01:00402F10 push 0
rr01:00402F12 call sub_408750
rr01:00402F17 mov [esp+1Ch], eax
rr01:00402F1B push 0
rr01:00402F1D call sub_408750
rr01:00402F22 mov [esp+24h], eax
rr01:00402F26 mov eax, [esp+18h]
rr01:00402F2A push eax
rr01:00402F2B mov byte ptr [esp+100h], 14h
rr01:00402F33 call sub_40B1B0
rr01:00402F38 add esp, 10h
rr01:00402F3B lea ecx, [esp+18h]
rr01:00402F3F push ecx
rr01:00402F40 lea edx, [esp+18h]
rr01:00402F44 push edx
rr01:00402F45 lea ecx, [esp+14h]
rr01:00402F49 call ECn__get
rr01:00402F4E push 1
rr01:00402F50 lea eax, [esp+24h]
rr01:00402F54 push eax
rr01:00402F55 lea ecx, [esp+1Ch]
rr01:00402F59 push ebx
rr01:00402F5A push ecx
rr01:00402F5B call Big__to_binary
rr01:00402F60 push 1
rr01:00402F62 lea edx, [esp+38h]
rr01:00402F66 push edx
rr01:00402F67 lea eax, [esp+30h]
rr01:00402F6B push ebx
rr01:00402F6C push eax
rr01:00402F6D call Big__to_binary
rr01:00402F72 add esp, 20h
rr01:00402F75 lea ecx, [esp+74h]
rr01:00402F79 call shs_init_modified
rr01:00402F7E mov eax, offset UserName
rr01:00402F83 lea ecx, [eax+1]
rr01:00402F86
rr01:00402F86 loc_402F86: ; CODE XREF: rr01:00402F8Bj
rr01:00402F86 mov dl, [eax]
rr01:00402F88 inc eax
rr01:00402F89 test dl, dl
rr01:00402F8B jnz short loc_402F86
rr01:00402F8D sub eax, ecx
rr01:00402F8F push eax
rr01:00402F90 push offset UserName
rr01:00402F95 lea ecx, [esp+7Ch]
rr01:00402F99 call shs_process
rr01:00402F9E push 8
rr01:00402FA0 lea ecx, [esp+24h]
rr01:00402FA4 push ecx
rr01:00402FA5 lea ecx, [esp+7Ch]
rr01:00402FA9 call shs_process
rr01:00402FAE lea ecx, [esp+74h]
rr01:00402FB2 call sha_hash
rr01:00402FB7 lea edx, [esp+20h]
rr01:00402FBB push edx
rr01:00402FBC lea ecx, [esp+78h]
rr01:00402FC0 call sha_hash_out
rr01:00402FC5 mov eax, [esp+20h]
rr01:00402FC9 and eax, 3FFFFh
rr01:00402FCE push eax
rr01:00402FCF lea ecx, [esp+0Ch]
rr01:00402FD3 call sub_402470 ; mirvar
rr01:00402FD8 lea ecx, [esp+8]
rr01:00402FDC push ecx
rr01:00402FDD lea edx, [esp+20h]
rr01:00402FE1 push edx
rr01:00402FE2 mov byte ptr [esp+0F8h], 15h
rr01:00402FEA call sub_4024D0 ; Big::==
rr01:00402FEF add esp, 8
rr01:00402FF2 test eax, eax
rr01:00402FF4 jz short loc_40300D
rr01:00402FF6 mov eax, failed
rr01:00402FFB test eax, eax ; 检查标志
rr01:00402FFD jnz short loc_40300D
rr01:00402FFF push 30h
rr01:00403001 push offset aCongratulation ; "Congratulations!~"
rr01:00403006 push offset aYouDidItSendTh ; "You did it, send the keygen and src to "...
rr01:0040300B jmp short loc_403019
rr01:0040300D ; ---------------------------------------------------------------------------
rr01:0040300D
rr01:0040300D loc_40300D: ; CODE XREF: rr01:00402FF4j
rr01:0040300D ; rr01:00402FFDj
rr01:0040300D push 0
rr01:0040300F push offset aKeepGoing ; "Keep going!~"
rr01:00403014 push offset aYouAlmostThere ; "You almost there, check it carefully"
rr01:00403019
rr01:00403019 loc_403019: ; CODE XREF: rr01:0040300Bj
rr01:00403019 mov ecx, edi ; 以下是清理现场,可以不管了。。。
该CrackMe使用了miracl库,不过不是直接调用C API,而是使用其C++ Wrapper(参见附件中的代码)。
这样带来的问题就是,常用的API都不能被IDA识别出来,只能自己手动分析。
关于miracl库API的手动识别,blackeye曾经写过一片文章,介绍了一种非常有效的方法。
(见附件:快速地识别MIRACL库函数.TXT)
另一个难点是局部变量的识别。由于这里的变量主要是通过esp寻址,静态分析基本无法确定,只能
先猜测,然后动态分析验证和确认。
4、代码逆向
分析完以后,就是逆向的过程。逆向出来的代码见附件,已经调试通过,验证无误。
5、注册算法
软件验证过程如下:
1、读入用户名和注册码
2、对注册码进行Base24解码,得到一个大数,将大数的hex输出到一个16字节的数组sn中。
3、将sn的后8个字节转换为大数s3,RSA加密后得到大数m,将shs_modified(用户名+
"Team ROR 2004")的前8个字节转化为大数h,如果h与m不等则注册失败,否则继续下一步。
4、将sn的前0-3共4个字节转化为大数s1,将4-7共4个字节转化为大数s2,计算椭圆曲线点
R=s1*K+s2*G,将R的坐标x、y转化为4字节的hex串rx、ry,将shs_modified(用户名+
rx + ry)的结果的前4字节转换为32位整数,与0x3FFFF按字节与,得到的结果转化为大数H。
如果H与s1相同,且前面3中也相等,则注册成功。否则注册失败。
所使用的SHA算法是经过修改过的SHA1算法,只改了几个初始化参数。
不知道说清楚了没有?最好看我逆向出来的代码,会更好懂一些。
已知上面的验证过程,那么生成注册码的过程就清楚了:
1、读入用户名,将shs_modified(用户名+"Team ROR 2004")的前8个字节转化为大数h。
2、RSA解密:c = h^d mod n。将c转化为8字节的hex串放入sn的8-16字节。
3、取随机数r,R = r*G,将R的坐标x、y转化为4字节的hex串rx、ry,将shs_modified(用户名+
rx + ry)的结果的前4字节转换为32位整数,与0x3FFFF按字节与,得到的结果转化为大数h1。
4、h2 = ( r - h1*k ) % q,将h1、h2分别转化为4字节hex串,放入sn的前8个字节中。
5、将16字节的sn转化为大数,然后对该大数进行base24编码,即得到注册码。
具体实现过程进附件中的代码。
6、RSA参数
RSA-64:
P: 0xFFAE8E6F
Q: 0xFFADA3AD
N: 0xFF5C4C4FBFA9EE03
D: 0xEE10742A803F7811
E: 0x00010001
这里的RSA是64位的,相当简单。已知RSA的公钥求私钥,用RSATool2可以轻松搞定。
7、ECC参数
ECC-32:
p: 0xFFAE8E6F
a: 0x1
b: 0xD
gx: 0x0BCBBEC6
gy: 0x48074670
kx: 0x0ADC597B
ky: 0x5EF435E2
k: 0xFCC4D43B
q: 0xFFADA3AD
这里的ECC是32位的。需要求ECC的私钥k和阶q。
我当时用的是穷举法,首先用miracl里面的工具schoof.exe求得q,然后用穷举法求k。
在P4的计算机上,几小时内可以穷举出k。
在《Guide to Elliptic Curve Cryptography》的第4章讲了ECC的Pollard’s rho攻击方法。
不过我没有机会去实现这一算法。
总结:这个CrackMe的难点有3个,首先是库函数的手动识别,其次是变量的定位,最后是
公钥密码学算法的理解。修改过的SHA算法虽然也会给新手带来一些麻烦,不过只要稍微
分析一下,问题也不大。
附件中给出了CrackMe和KeyGen的全部代码。
[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!