od加载crackme,通过main函数跟踪发现如下:
00403551 |> /33C0 /xor eax, eax
00403553 |. |8BCF |mov ecx, edi
00403555 |> |83F8 20 |/cmp eax, 20
00403558 |. |7D 1C ||jge short 00403576
0040355A |. |8B56 14 ||mov edx, dword ptr [esi+14]
0040355D |. |8A12 ||mov dl, byte ptr [edx]
0040355F |. |3A11 ||cmp dl, byte ptr [ecx]
00403561 |. |74 08 ||je short 0040356B
00403563 |. |83C0 01 ||add eax, 1
00403566 |. |83C1 08 ||add ecx, 8
00403569 |.^|EB EA |\jmp short 00403555
0040356B |> |8B44C6 1C |mov eax, dword ptr [esi+eax*8+1C]
0040356F |. |55 |push ebp
00403570 |. |56 |push esi
00403571 |. |FFD0 |call eax
00403573 |. |83C4 08 |add esp, 8
00403576 |> |8B4E 14 |mov ecx, dword ptr [esi+14]
00403579 |. |8039 A3 |cmp byte ptr [ecx], 0A3
0040357C |.^\75 D3 \jnz short 00403551
这里是个switch循环,循环到A3结束,case地址如下:
0019FDA8 A0 00 00 00 C0 34 40 00 A1 00 00 00 C0 33 40 00 ?..?@.?..?@.
0019FDB8 A2 00 00 00 D0 33 40 00 A4 00 00 00 40 34 40 00 ?..?@.?..@4@.
0019FDC8 A5 00 00 00 70 34 40 00 A3 00 00 00 30 34 40 00 ?..p4@.?..04@.
0019FDD8 A6 00 00 00 00 34 40 00 A7 00 00 00 80 34 40 00 ?...4@.?..�4@.
0019FDE8 A8 00 00 00 A0 34 40 00 A9 00 00 00 00 27 40 00 ?..?@.?...'@.
0019FDF8 AA 00 00 00 20 27 40 00 00 00 00 00 00 00 00 00 ?.. '@.........
操作码如下:
0019FECB AA 15 20 ?
0019FEDB 01 00 00 AA 15 40 01 00 00 A0 10 00 00 00 00 A8 ..?@..?....?
0019FEEB A0 10 F0 00 00 00 A8 A0 10 60 01 00 00 A7 AA 11 ??..��`..��
0019FEFB 80 00 00 00 AA 10 60 00 00 00 AA 12 B0 00 00 00 �...?`...??..
0019FF0B A9 A2 EA A6 0E A0 10 20 01 00 00 A0 11 10 01 00 ���? ..?.
0019FF1B 00 A4 A5 A0 10 40 01 00 00 A0 11 10 01 00 00 A4 .��?@..?..?
0019FF2B A5 8C 65 40 00 7F 02 40 00 75 6B F7 94 9B 49 40 ��e@.@.uk���I@
0019FF3B 00 80 FF 19 00 98 41 40 00 01 00 00 00 D8 2D 98 .��.�A@....??
0019FF4B 02 B0 1C 98 02 79 69 F7 94 E1 42 40 00 E1 42 40 ??yi���B@.�B@
0019FF5B 00 00 90 35
通过上述特征,可以确定这是一个小型虚拟机,继续跟踪分析操作码,其主要对应的功能为:
A5 A0 10 40 01 00 00 A0 11 10 01 00 00 A4 error
0E A0 10 20 01 00 00 A0 11 10 01 00 00 A4 ok
AA 11 80 00 00 00 decode
00406038 31 35 34 39 37 38 30 36 35 32 30 33 36 32 35 38 1549780652036258
00406048 34 38 34 34 32 34 37 35 31 37 30 35 31 30 32 37 4844247517051027
00406058 38 31 38 38 34 33 38 36 31 31 33 81884386113
AA 10 60 00 00 00 decode
00406020 39 38 37 36 35 34 33 32 31 30 39 38 37 36 35 34 9876543210987654
00406030 33 32 31 30 31 32 33 3210123
AA 12 B0 00 00 00 decode
00406064 39 37 35 33 31 32 34 36 38 30 39 37 35 33 31 32 9753124680975312
00406074 34 36 38 30 39 37 35 33 31 32 34 36 38 30 39 37 4680975312468097
00406084 35 33 31 32 34 36 38 30 53124680
A9 load sn
A2 EA ?? cmp1
A6 0E cmp2
下面主要分析load sn,A9这条指令,其对应的函数为 00402700
00402700 . 56 push esi
00402701 . 8B7424 08 mov esi, dword ptr [esp+8]
00402705 . 8B06 mov eax, dword ptr [esi]
00402707 . 034424 0C add eax, dword ptr [esp+C]
0040270B . 50 push eax
0040270C . E8 3FFDFFFF call 00402450
00402711 . 8346 14 01 add dword ptr [esi+14], 1
00402715 . 83C4 04 add esp, 4
00402718 . 8906 mov dword ptr [esi], eax
0040271A . 5E pop esi
0040271B . C3 retn
继续分析00402450,
00402517 . 8B4D F8 mov ecx, dword ptr [ebp-8]
0040251A . 8B45 08 mov eax, dword ptr [ebp+8]
0040251D . E8 2EF8FFFF call <base64_decode>
00402522 . 83C4 04 add esp, 4
00402525 . 8945 FC mov dword ptr [ebp-4], eax
00402528 . 8D85 F0FEFFFF lea eax, dword ptr [ebp-110]
首先,对sn进行base64解码
0040256D . 898D D0FEFFFF mov dword ptr [ebp-130], ecx
00402573 . 83BD D0FEFFFF>cmp dword ptr [ebp-130], 5A ;解码后的长度
0040257A . 75 30 jnz short 004025AC
0040257C . 0FBE95 04FFFF>movsx edx, byte ptr [ebp-FC]
00402583 . 83FA 2D cmp edx, 2D ;间隔 ‘-’
00402586 . 75 24 jnz short 004025AC
00402588 . 0FBE85 05FFFF>movsx eax, byte ptr [ebp-FB]
0040258F . 83F8 2D cmp eax, 2D
00402592 . 75 18 jnz short 004025AC
00402594 . 0FBE8D 2DFFFF>movsx ecx, byte ptr [ebp-D3]
0040259B . 83F9 2D cmp ecx, 2D
0040259E . 75 0C jnz short 004025AC
004025A0 . 0FBE95 2EFFFF>movsx edx, byte ptr [ebp-D2]
004025A7 . 83FA 2D cmp edx, 2D
004025AA . 74 06 je short 004025B2
解码后长度必须为5A,sn分为3部分中间以‘--’分隔
004025C6 > \C705 ECB69900>mov dword ptr [99B6EC], 1 ;关键,全局变量=1
004025D0 > A1 ECB69900 mov eax, dword ptr [99B6EC]
004025D5 . 83F8 00 cmp eax, 0
004025D8 . 74 02 je short 004025DC
004025DA .^ EB F4 jmp short 004025D0 ;循环等待,全局变量=0
004025DC > 68 EA264000 push 004026EA
004025E1 ? C3 retn
004025E2 . 8D8D F0FEFFFF lea ecx, dword ptr [ebp-110]
004025E8 . 51 push ecx
004025E9 . E8 D2F8FFFF call 00401EC0 ;比较 sn1
004025EE . 83C4 04 add esp, 4
这里通知另一线程处理,通知的全局变量为99B6EC,通过这个变量发现3处线程函数:
000023E0 00402A90 00257000 ERROR_SUCCESS (00000000) ���� 32 + 0 0.0000 s 0.0000 s
00002664 00402830 00251000 ERROR_SUCCESS (00000000) ���� 32 + 0 0.0000 s 0.0000 s
00003864 00402970 00254000 ERROR_SUCCESS (00000000) ���� 32 + 0 0.0000 s 0.0000 s
其作用是分别对运行中的代码进行修改,修改地址可以在线程函数中找到。
下面分析 sn1的处理过程,即00401EC0
00401F80 |> /8B5424 10 mov edx, dword ptr [esp+10]
00401F84 |> |0FB61C01 movzx ebx, byte ptr [ecx+eax]
00401F88 |. |3218 xor bl, byte ptr [eax]
00401F8A |. |83C0 05 add eax, 5 ; sn^k1
00401F8D |. |885C06 FB mov byte ptr [esi+eaw-5], bl
00401F91 |. |0FB65C07 FB movzx ebx, byte ptr [edi+eaw-5]
对sn1进行异或解码,其中key如下:
00405144 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 abcdefghijklmnop
00405154 71 72 73 74 75 76 77 78 79 7A 61 62 63 64 65 66 qrstuvwxyzabcdef
00405164 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 ghijklmnopqrstuv
00405174 77 78 79 7A wxyz
sn2的解码也使用了上述key,
00401FE0 . 68 20604000 push 00406020 ; ASCII "98765432109876543210123"
00401FE5 . 68 F0B69900 push 0099B6F0
00401FEA . E8 B11E0000 call <big_mul>
00401FEF . 83C4 08 add esp, 8
00401FF2 . 8BF0 mov esi, eax
00401FF4 . 0F31 rdtsc
00401FF6 . 895424 14 mov dword ptr [esp+14], edx
00401FFA . 894424 10 mov dword ptr [esp+10], eax
00401FFE . B9 38604000 mov ecx, 00406038 ; ASCII "1549780652036258484424751705102781884386113"
00402003 . 8BC6 mov eax, esi
00402005 > 8A10 mov dl, byte ptr [eax]
00402007 . 3A11 cmp dl, byte ptr [ecx]
00402009 . 75 1A jnz short 00402025
大数乘法运算,即sn1*98765432109876543210123==13095069099216326605010245808779535277211541324456558063162414338128147458401
下面分析 sn1的处理过程,即00402090
004020EF . 8890 05B79900 mov byte ptr [eax+99B705], dl
004020F5 . 0FB65401 14 movzx edx, byte ptr [ecx+eax+14]
004020FA . 3290 42514000 xor dl, byte ptr [eax+405142] ; sn2 ^ k1
00402100 . 8890 06B79900 mov byte ptr [eax+99B706], dl
00402106 . 0FB65401 15 movzx edx, byte ptr [ecx+eax+15]
0040210B . 3290 43514000 xor dl, byte ptr [eax+405143]
00402111 . 83F8 27 cmp eax, 27
00402114 . 8890 07B79900 mov byte ptr [eax+99B707], dl
0040211A .^ 7C C5 jl short 004020E1
0040211C . 68 08B79900 push 0099B708
00402121 . 68 08B79900 push 0099B708
00402126 . E8 751D0000 call <big_mul>
0040212B . 8BF0 mov esi, eax
0040212D . 68 64604000 push 00406064 ; ASCII "9753124680975312468097531246809753124680"
00402132 . 56 push esi
00402133 . E8 881C0000 call 00403DC0
00402138 . 83C4 10 add esp, 10
0040213B . B9 90644000 mov ecx, 00406490 ; ASCII "13095069099216326605010245808779535277211541324456558063162414338128147458401"
00402140 . 8BC6 mov eax, esi
同样大数运算,sn2*sn2 == 13095069099216326605010245808779535277211541324456558063162414338128147458401
下面分析 sn3的处理过程,即004021D0
0040235E |. 8D8424 200200>lea eax, dword ptr [esp+220]
00402365 |. E8 E6F8FFFF call 00401C50
0040236A |. 8D8424 C80000>lea eax, dword ptr [esp+C8]
00402371 |. E8 4AEDFFFF call 004010C0
00402376 |. 6A 0A push 0A
00402378 |. 68 F0B69900 push 0099B6F0
0040237D |. E8 CEF8FFFF call 00401C50
00402382 |. 8D8424 700100>lea eax, dword ptr [esp+170]
00402389 |. E8 32EDFFFF call 004010C0
0040238E |. 6A 0A push 0A
00402390 |. 68 08B79900 push 0099B708
00402395 |. E8 B6F8FFFF call 00401C50
0040239A |. 8D9424 700100>lea edx, dword ptr [esp+170]
004023A1 |. 52 push edx
004023A2 |. 8D4424 24 lea eax, dword ptr [esp+24]
004023A6 |. 50 push eax
004023A7 |. 8D9424 D00000>lea edx, dword ptr [esp+D0]
004023AE |. 8D8424 200200>lea eax, dword ptr [esp+220]
004023B5 |. E8 D6F6FFFF call <exp_mod>
004023BA |. 33C0 xor eax, eax
004023BC |. 837C24 24 04 cmp dword ptr [esp+24], 4
004023C1 |. 75 69 jnz short 0040242C
004023C3 |> 8B4C04 28 /mov ecx, dword ptr [esp+eax+28]
004023C7 |. 3B88 E0644000 |cmp ecx, dword ptr [eax+4064E0]
首先对sn3进行了编解码,之后进行进制转换,再之后进行大数幂模运算即RSA运算,获取的数据如下:
N=
31 90 99 35 A1 B1 6B 8D 2A 66 2A 86 73 20 17 56
56172073862A662A8D6BB1A135999031
E=
E3 1E 46 4A 94 82 C3 D9
D9C382944A461EE3
M=
63 1F 97 04 A7 49 1E 88 CC 4B 49 28 1C 34 E5 35
35E5341C28494BCC881E49A704971F63
D=?
4A064A97921BDF9E3F354E9020AE054F
C=?
2A 1E B3 C9 57 9D FA 30 7C F5 B6 C8 73 01 14 DB
DB140173C8B6F57C30FA9D57C9B31E2A
2A1EB3C9579DFA307CF5B6C8730114DB
已知N,E,M,通过rsa工具分解出D,使用D和N解密M可以求的明文C
编码的时候C必须足够大,才能符合sn长度为5A的要求,这也是该题多解原因。
为了满足上述要求,可以将C+N*x,由于取模运算同样可以得出M。
import math
import base64
k1 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
def key_encode(a):
v = bytearray()
i = 0
while i < len(a):
v.append(ord(a[i]) ^ ord(k1[i]))
i = i + 1
return v
def is_ok(a):
for x in a:
if x & 0x80:
return 0
return 1
b = int(98765432109876543210123)
c = int(1549780652036258484424751705102781884386113)
#sn1 = int(c/b)
sn1 = 15691529100101820131
print "sn1=",sn1
print((sn1*b)==c)
v1 = key_encode(str(sn1))
c = int(13095069099216326605010245808779535277211541324456558063162414338128147458401)
#sn2 = int(math.sqrt(c))
sn2 = 114433688655117320765854989491151409201
print "sn2=",sn2
print (sn2 * sn2) == c
v2 = key_encode(str(sn2))
v = v1
v.append(0x2d)
v.append(0x2d)
v = v + v2
v.append(0x2d)
v.append(0x2d)
M = int("35E5341C28494BCC881E49A704971F63", 16)
D = int("4A064A97921BDF9E3F354E9020AE054F", 16
N = int("56172073862A662A8D6BB1A135999031", 16
c = int("56172b366a392d0751d99d1b824d1f7a3377be6254e46ed98db5c9", 16) #为了满足长度和编码要求这里预先加了部分N
v3 = bytearray()
for i in range(1, 100000000):
c = c + N
v3 = bytearray.fromhex(str(hex(c))[2:-1])
try :
if is_ok(v3) == 1:
print hex(c)
break
except:
print hex(c)
#c = (M**D)%N
#v3=bytearray("\x2A\x1E\xB3\xC9\x57\x9D\xFA\x30\x7C\xF5\xB6\xC8\x73\x01\x14\xDB")
v = v + v3
print len(v) == 0x5a
sn = base64.b64encode(v)
print "sn=",sn
sn= UFdVXVRTVVFYWltdXV9XQkFDQEUtLVBTV1BWVVFQUVxeWVxfWENDQkRCQE5CTEBCWFZaVVRTVlxZU1lcXC0tVhcrNmo5LQdTZh5TOh5WFQsHYRlKDRoDBUN3
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。