首页
社区
课程
招聘
[原创]看雪CTF2017 第八题分析
2017-6-17 11:39 4058

[原创]看雪CTF2017 第八题分析

2017-6-17 11:39
4058

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漏洞挖掘与利用;代码审计。

收藏
点赞1
打赏
分享
最新回复 (4)
雪    币: 4441
活跃值: (805)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
windtrace 2017-6-19 08:47
2
0
大牛!
雪    币: 1467
活跃值: (2182)
能力值: ( LV9,RANK:156 )
在线值:
发帖
回帖
粉丝
whydbg 2017-6-19 10:40
3
0

c  =  int("56172b366a392d0751d99d1b824d1f7a3377be6254e46ed98db5c9",  16)  #为了满足长度和编码要求这里预先加了部分N&quot;

这段数据  是  c  =  c  +  N累加得到的吗?

雪    币: 3053
活跃值: (886)
能力值: ( LV13,RANK:1300 )
在线值:
发帖
回帖
粉丝
HighHand 11 2017-6-19 16:20
4
0
whydbg c&nbsp;&nbsp;=&nbsp;&nbsp;int(&quot;56172b366a392d0751d99d ...
是的
雪    币: 1467
活跃值: (2182)
能力值: ( LV9,RANK:156 )
在线值:
发帖
回帖
粉丝
whydbg 2017-6-19 16:23
5
0
谢谢    。
游客
登录 | 注册 方可回帖
返回