-
-
[原创]2016CTF大赛第五题简单分析
-
发表于: 2016-11-10 20:57 2684
-
试运行了,只要输入不对就没有反应,也不知道正确是什么样。
OD载入,试了下GetDlgItemTextA等获取文本框数据的api下断无效。看了下导入函数,然后决定在GetDlgItem附近下断,幸好没有好多处调用这个API。
上面是程序的输入处理与比较总体流程。先通过message获取文本,检查输入为数字,再检查位数为6位。然后进行输入作为KEY进行RC4加解密。加解密处理前后的字串都在0x406030。下面看RC4的过程:
然后就是进行验证,验证是将加密或解密后的128字节字串ascii相加与10617即0x2979比较。
程序流程就这样。跟是跟不出注册码的,只有两种方法一是利用现有程序爆破;一是根据算法过程自己写过程枚举。我先用了第一种方法:UI爆破,太慢了,后又想调用程序接口,无奈没写过,就放弃了。最后用第二种方法,用python写了个脚本。
本人新手,大神莫笑。
OD载入,试了下GetDlgItemTextA等获取文本框数据的api下断无效。看了下导入函数,然后决定在GetDlgItem附近下断,幸好没有好多处调用这个API。
00401146 . 8D7C24 21 lea edi,dword ptr ss:[esp+0x21]
0040114A . F3:AB rep stos dword ptr es:[edi]
0040114C . 8BB424 240100>mov esi,dword ptr ss:[esp+0x124]
00401153 . 8B1D A0504000 mov ebx,dword ptr ds:[<&USER32.GetDlgIte> ;user32.GetDlgItem
00401159 . 66:AB stos word ptr es:[edi]
0040115B . 8D4424 20 lea eax,dword ptr ss:[esp+0x20]
0040115F . BF 01000000 mov edi,0x1
00401164 . 50 push eax ; /lParam = 0x80
00401165 . 68 FF000000 push 0xFF ; |wParam = 0xFF
0040116A . 6A 0D push 0xD ; |Message = WM_GETTEXT
0040116C . 68 E9030000 push 0x3E9 ; |/ControlID = 3E9 (1001.)
00401171 . 56 push esi ; ||hWnd = 0018F689
00401172 . FFD3 call ebx ; |\GetDlgItem
00401174 . 8B2D A4504000 mov ebp,dword ptr ds:[<&USER32.SendMessa>; |user32.SendMessageA
0040117A . 50 push eax ; |hWnd = 0x80
0040117B . FFD5 call ebp ; \SendMessageA
0040117D . 33C9 xor ecx,ecx
0040117F . 85C0 test eax,eax
00401181 . 76 17 jbe short CrackMe.0040119A
00401183 > 8A540C 20 mov dl,byte ptr ss:[esp+ecx+0x20] ;检查输入在0-9之间
00401187 . 80FA 30 cmp dl,0x30
0040118A . 7C 0C jl short CrackMe.00401198
0040118C . 80FA 39 cmp dl,0x39
0040118F . 7F 07 jg short CrackMe.00401198
00401191 . 41 inc ecx
00401192 . 3BC8 cmp ecx,eax
00401194 .^ 72 ED jb short CrackMe.00401183
00401196 . EB 02 jmp short CrackMe.0040119A
00401198 > 33FF xor edi,edi
0040119A > 83F8 06 cmp eax,0x6 ;输入为6位
0040119D . 75 56 jnz short CrackMe.004011F5
0040119F . 85FF test edi,edi
004011A1 . 74 52 je short CrackMe.004011F5
004011A3 . 8D4C24 20 lea ecx,dword ptr ss:[esp+0x20]
004011A7 . 50 push eax
004011A8 . 51 push ecx
004011A9 . E8 52FEFFFF call CrackMe.00401000 ;RC4加密或解密处理
004011AE . 83C4 08 add esp,0x8
004011B1 . E8 0AFFFFFF call CrackMe.004010C0 ;关键比较
004011B6 . 85C0 test eax,eax
004011B8 . 74 2C je short CrackMe.004011E6 ;错就跳
004011BA . 6A 00 push 0x0
004011BC . 68 E9030000 push 0x3E9
004011C1 . 56 push esi
004011C2 . FFD3 call ebx ; user32.7588F39A
004011C4 . 8B3D A8504000 mov edi,dword ptr ds:[<&USER32.EnableWin>; |user32.EnableWindow
004011CA . 50 push eax ; |hWnd = 00000080
004011CB . FFD7 call edi ; \EnableWindow
004011CD . 6A 00 push 0x0
004011CF . 68 EA030000 push 0x3EA
004011D4 . 56 push esi
004011D5 . FFD3 call ebx ; user32.7588F39A
004011D7 . 50 push eax
004011D8 . FFD7 call edi
004011DA . 55 push ebp
004011DB . 56 push esi
004011DC . BA 30604000 mov edx,CrackMe.00406030
004011E1 . FFD2 call edx
004011E3 . 83C4 08 add esp,0x8
004011E6 > 8D4424 20 lea eax,dword ptr ss:[esp+0x20]
004011EA . 6A 06 push 0x6
004011EC . 50 push eax
004011ED . E8 0EFEFFFF call CrackMe.00401000
004011F2 . 83C4 08 add esp,0x8
004011F5 > 5F pop edi ; Default case of switch 0040110A
004011F6 . 5E pop esi
004011F7 . 5D pop ebp
004011F8 . 33C0 xor eax,eax
004011FA . 5B pop ebx ; user32.7588F39A
004011FB . 81C4 10010000 add esp,0x110
00401201 . C2 1000 retn 0x10
上面是程序的输入处理与比较总体流程。先通过message获取文本,检查输入为数字,再检查位数为6位。然后进行输入作为KEY进行RC4加解密。加解密处理前后的字串都在0x406030。下面看RC4的过程:
0040100C |. B9 3F000000 mov ecx,0x3F
00401011 |. 33C0 xor eax,eax
00401013 |. 8D7C24 19 lea edi,dword ptr ss:[esp+0x19]
00401017 |. 885424 18 mov byte ptr ss:[esp+0x18],dl
0040101B |. F3:AB rep stos dword ptr es:[edi]
0040101D |. 66:AB stos word ptr es:[edi]
0040101F |. AA stos byte ptr es:[edi]
00401020 |. 8D7C24 18 lea edi,dword ptr ss:[esp+0x18]
00401024 |. 33C0 xor eax,eax
00401026 |> 884404 18 /mov byte ptr ss:[esp+eax+0x18],al ;0-255 S盒
0040102A |. 40 |inc eax
0040102B |. 3D 00010000 |cmp eax,0x100
00401030 |.^ 7C F4 \jl short CrackMe.00401026
00401032 |. 8BAC24 200100>mov ebp,dword ptr ss:[esp+0x120]
00401039 |. 33C0 xor eax,eax
0040103B |. C74424 10 000>mov dword ptr ss:[esp+0x10],0x100
00401043 |> 8BB424 1C0100>/mov esi,dword ptr ss:[esp+0x11C] ;输入key 进行密钥生成
0040104A |. 8A0F |mov cl,byte ptr ds:[edi]
0040104C |. 8A1C30 |mov bl,byte ptr ds:[eax+esi]
0040104F |. 02D9 |add bl,cl
00401051 |. 02D3 |add dl,bl
00401053 |. 40 |inc eax
00401054 |. 885424 14 |mov byte ptr ss:[esp+0x14],dl
00401058 |. 8B7424 14 |mov esi,dword ptr ss:[esp+0x14]
0040105C |. 81E6 FF000000 |and esi,0xFF
00401062 |. 3BC5 |cmp eax,ebp
00401064 |. 8A5C34 18 |mov bl,byte ptr ss:[esp+esi+0x18]
00401068 |. 8D7434 18 |lea esi,dword ptr ss:[esp+esi+0x18]
0040106C |. 881F |mov byte ptr ds:[edi],bl
0040106E |. 880E |mov byte ptr ds:[esi],cl
00401070 |. 75 02 |jnz short CrackMe.00401074 ;key循环输入构造T
00401072 |. 33C0 |xor eax,eax
00401074 |> 8B4C24 10 |mov ecx,dword ptr ss:[esp+0x10]
00401078 |. 47 |inc edi
00401079 |. 49 |dec ecx
0040107A |. 894C24 10 |mov dword ptr ss:[esp+0x10],ecx
0040107E |.^ 75 C3 \jnz short CrackMe.00401043
00401080 |. 33C0 xor eax,eax
00401082 |. 8D8C24 170100>lea ecx,dword ptr ss:[esp+0x117]
00401089 |> 8A5404 18 /mov dl,byte ptr ss:[esp+eax+0x18] ;加密或解密
0040108D |. 8A19 |mov bl,byte ptr ds:[ecx]
0040108F |. 02D3 |add dl,bl
00401091 |. 8A98 30604000 |mov bl,byte ptr ds:[eax+0x406030]
00401097 |. 32DA |xor bl,dl
00401099 |. 8898 30604000 |mov byte ptr ds:[eax+0x406030],bl
0040109F |. 40 |inc eax
004010A0 |. 49 |dec ecx
004010A1 |. 3D 80000000 |cmp eax,0x80
004010A6 |.^ 7C E1 \jl short CrackMe.00401089
004010A8 |. 5F pop edi
004010A9 |. 5E pop esi
004010AA |. 5D pop ebp
004010AB |. 5B pop ebx ;user32.7588F39A
004010AC |. 81C4 08010000 add esp,0x108
004010B2 \. C3 retn
然后就是进行验证,验证是将加密或解密后的128字节字串ascii相加与10617即0x2979比较。
004010C0 /$ 56 push esi
004010C1 |. 57 push edi
004010C2 |. 33FF xor edi,edi
004010C4 |. 33F6 xor esi,esi
004010C6 |. 33C9 xor ecx,ecx
004010C8 |> 33C0 /xor eax,eax
004010CA |. 8A81 30604000 |mov al,byte ptr ds:[ecx+0x406030]
004010D0 |. 99 |cdq
004010D1 |. 03F8 |add edi,eax
004010D3 |. 13F2 |adc esi,edx
004010D5 |. 41 |inc ecx
004010D6 |. 81F9 80000000 |cmp ecx,0x80 ;128字节
004010DC |.^ 7C EA \jl short CrackMe.004010C8
004010DE |. 81FF 79290000 cmp edi,0x2979 ;关键比较
004010E4 |. 75 0C jnz short CrackMe.004010F2
004010E6 |. 85F6 test esi,esi
004010E8 |. 75 08 jnz short CrackMe.004010F2
004010EA |. 5F pop edi
004010EB |. B8 01000000 mov eax,0x1
004010F0 |. 5E pop esi
004010F1 |. C3 retn
程序流程就这样。跟是跟不出注册码的,只有两种方法一是利用现有程序爆破;一是根据算法过程自己写过程枚举。我先用了第一种方法:UI爆破,太慢了,后又想调用程序接口,无奈没写过,就放弃了。最后用第二种方法,用python写了个脚本。
本人新手,大神莫笑。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: