看雪2016CTF第五题WP

这是看雪CTF 2016(原:CrackMe攻防大赛)的第五题。
链接

试运行了,只要输入不对就没有反应,也不知道正确是什么样。
OD载入,试了下GetDlgItemTextA等获取文本框数据的api下断无效。看了下导入函数,然后决定在GetDlgItem附近下断,幸好没有好多处调用这个API。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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的过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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写了个脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from Crypto.Cipher import ARC4
c = 'F4129D6045F8206A6F670471C09B0C5A1D186C9669011CF47F285AFB2907408BD3E1B112FB\
CA7C89B95A30709D952B953C8D2E45EF70C6A3B9B25A635F0333B8644A8FBCF791696A562ED46E\
8293E976DCA36C5E6B726437E71517AC6478D54A602DF054A6F3E8E0E0B98F8590E4EAD6BBB715\
9E2A44E73163AC806C3482E9CF'.decode('hex')
for i in xrange(0,1000000):
skey = '{:0>6}'.format(i)
lkey = list(skey)
sum = 0
ls = []
for j in xrange(256):
ls.append(j)
index = 0
for k in xrange(256):
temp_index = (ls[k] + ord(lkey[k%6])) & 0xFF
index += temp_index
temp = ls[k]
ls[k] = ls[index%256]
ls[index%256] = temp
text_a = []
# print ls
for m in xrange(128):
num = ord(c[m])^(ls[255-m]+ls[m])&0xFF
text_a.append('{:0>2X}'.format(num))
sum += num
# print text_a
if sum == 10617:
print skey
break

本人新手,大神莫笑。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
,