首页
论坛
课程
招聘
[原创]看雪TSRC_2017秋季赛第三题---------WriteUp
2017-10-29 10:58 1681

[原创]看雪TSRC_2017秋季赛第三题---------WriteUp

2017-10-29 10:58
1681

0x00 流程分析

拿到题没啥可说的,直接ida看流程,程序无花无壳,就一些反调试,不影响静态分析
主要流程如下:

.text:00435076                 call    ds:GetDlgItemTextA
.text:0043507C                 cmp     esi, esp
.text:0043507E                 call    j___RTC_CheckEsp
.text:00435083                 mov     [ebp+var_420], eax
.text:00435089                 mov     [ebp+var_1038], 0
.text:00435090                 push    3FFh            ; size_t
.text:00435095                 push    0               ; int
.text:00435097                 lea     eax, [ebp+var_1037]
.text:0043509D                 push    eax             ; void *
.text:0043509E                 call    j__memset
.text:004350A3                 add     esp, 0Ch
.text:004350A6                 lea     eax, [ebp+var_C30]
.text:004350AC                 push    eax
.text:004350AD                 push    400h
.text:004350B2                 lea     ecx, [ebp+String]
.text:004350B8                 push    ecx
.text:004350B9                 call    base64Decode     ;第一次base64解码
.text:004350BE                 add     esp, 0Ch
.text:004350C1                 mov     [ebp+var_1440], 0
.text:004350C8                 push    3FFh            ; size_t
.text:004350CD                 push    0               ; int
.text:004350CF                 lea     eax, [ebp+var_1440+1]
.text:004350D5                 push    eax             ; void *
.text:004350D6                 call    j__memset
.text:004350DB                 add     esp, 0Ch
.text:004350DE                 lea     eax, [ebp+var_1038]
.text:004350E4                 push    eax
.text:004350E5                 push    400h
.text:004350EA                 lea     ecx, [ebp+var_C30]
.text:004350F0                 push    ecx
.text:004350F1                 call    base64Decode     ;第二次base64解码
.text:004350F6                 add     esp, 0Ch
.text:004350F9                 push    400h            ; int
.text:004350FE                 lea     eax, [ebp+var_1440]
.text:00435104                 push    eax             ; int
.text:00435105                 lea     ecx, [ebp+var_1038]
.text:0043510B                 push    ecx             ; char *
.text:0043510C                 call    transform_input  ;转换解码后的值
.text:00435111                 add     esp, 0Ch
.text:00435114                 mov     [ebp+var_144C], 3
.text:0043511E                 lea     eax, [ebp+var_1474]
.text:00435124                 push    eax             ; int
.text:00435125                 mov     ecx, [ebp+var_144C]
.text:0043512B                 push    ecx             ; size_t
.text:0043512C                 lea     edx, [ebp+var_1038]
.text:00435132                 push    edx             ; void *
.text:00435133                 call    SM3              ;计算转换后的SM3值
... ...
... ...
.text:0043518B                 lea     eax, [ebp+var_187C]
.text:00435191                 push    eax             ; char *
.text:00435192                 call    j__strlen        ;取SM3值的串长度
.text:00435197                 add     esp, 4
.text:0043519A                 push    eax             ; size_t
.text:0043519B                 lea     ecx, [ebp+String]
.text:004351A1                 push    ecx             ; char *
.text:004351A2                 call    j__strlen        ;取输入的串长度
.text:004351A7                 add     esp, 4
.text:004351AA                 lea     esi, [ebp+eax+String]    ;取输入的串结尾地址
.text:004351B1                 lea     edx, [ebp+var_187C]
.text:004351B7                 push    edx             ; char *
.text:004351B8                 call    j__strlen        ;取SM3值的串长度
.text:004351BD                 add     esp, 4
.text:004351C0                 sub     esi, eax         ;从输入串结尾向前取SM3值的长度的数据
.text:004351C2                 push    esi             ; void *
.text:004351C3                 lea     eax, [ebp+var_187C]
.text:004351C9                 push    eax             ; void *
.text:004351CA                 call    j__memcmp        ;比较
.text:004351CF                 add     esp, 0Ch
.text:004351D2                 test    eax, eax
.text:004351D4                 jnz     short loc_435214
.text:004351D6                 call    sub_42D0B4
.text:004351DB                 lea     eax, [ebp+var_1440]
.text:004351E1                 push    eax
.text:004351E2                 push    offset unk_49B000
.text:004351E7                 call    j_check          ;最终校验
.text:004351EC                 add     esp, 8
.text:004351EF                 movzx   ecx, al
.text:004351F2                 cmp     ecx, 1
.text:004351F5                 jnz     short loc_435214
.text:004351F7                 mov     esi, esp
.text:004351F9                 push    0               ; uType
.text:004351FB                 push    offset Caption  ; "CrackMe"
.text:00435200                 push    offset Text     ; "ok"
.text:00435205                 push    0               ; hWnd
.text:00435207                 call    ds:MessageBoxA

首先接受用户输入,并且进行两次base64的解码计算,之后将解出来的串进行一个转换计算,
然后再对转换后的串计算SM3值,并用这个值与输入的后64位进行比较,通过进行最终校验。

 

根据流程已经知道了key的组成方式为: base64(base64(key))+SM3(transform_input(key))

0x01 主要函数分析

先看看最终的check函数要验证什么样的数据,代码如下:

.text:00435584                 mov     eax, [ebp+arg_4]
.text:00435587                 movsx   ecx, byte ptr [eax]
.text:0043558A                 cmp     ecx, 6Ch
.text:0043558D                 jnz     short loc_4355D4
.text:0043558F                 mov     eax, [ebp+var_8]
.text:00435592                 add     eax, [ebp+var_44]
.text:00435595                 cmp     eax, 0Ah
.text:00435598                 jge     short loc_4355D4
.text:0043559A                 mov     eax, [ebp+var_14]
.text:0043559D                 imul    eax, 28h
.text:004355A0                 add     eax, [ebp+arg_0]
.text:004355A3                 mov     ecx, [ebp+var_8]
.text:004355A6                 add     ecx, [ebp+var_44]
.text:004355A9                 cmp     dword ptr [eax+ecx*4], 0
.text:004355AD                 jnz     short loc_4355CD
.text:004355AF                 mov     eax, [ebp+var_14]
.text:004355B2                 imul    eax, 28h
.text:004355B5                 add     eax, [ebp+arg_0]
.text:004355B8                 mov     ecx, [ebp+var_8]
.text:004355BB                 mov     dword ptr [eax+ecx*4], 4
.text:004355C2                 mov     eax, [ebp+var_8]
.text:004355C5                 add     eax, [ebp+var_44]
.text:004355C8                 mov     [ebp+var_8], eax
.text:004355CB                 jmp     short loc_4355D4
.text:004355CD ; ---------------------------------------------------------------------------
.text:004355CD
.text:004355CD loc_4355CD:                             ; CODE XREF: check+1AD↑j
.text:004355CD                 xor     al, al
.text:004355CF                 jmp     loc_435665
.text:004355D4 ; ---------------------------------------------------------------------------
.text:004355D4
.text:004355D4 loc_4355D4:                             ; CODE XREF: check+18D↑j
.text:004355D4                                         ; check+198↑j ...
.text:004355D4                 mov     eax, [ebp+arg_4]
.text:004355D7                 movsx   ecx, byte ptr [eax]
.text:004355DA                 cmp     ecx, 71h
.text:004355DD                 jnz     short loc_43561E
.text:004355DF                 mov     eax, [ebp+var_14]
.text:004355E2                 add     eax, [ebp+var_20]
.text:004355E5                 js      short loc_43561E
.text:004355E7                 mov     eax, [ebp+var_14]
.text:004355EA                 add     eax, [ebp+var_20]
.text:004355ED                 imul    eax, 28h
.text:004355F0                 add     eax, [ebp+arg_0]
.text:004355F3                 mov     ecx, [ebp+var_8]
.text:004355F6                 cmp     dword ptr [eax+ecx*4], 0
.text:004355FA                 jnz     short loc_43561A
.text:004355FC                 mov     eax, [ebp+var_14]
.text:004355FF                 imul    eax, 28h
.text:00435602                 add     eax, [ebp+arg_0]
.text:00435605                 mov     ecx, [ebp+var_8]
.text:00435608                 mov     dword ptr [eax+ecx*4], 4
.text:0043560F                 mov     eax, [ebp+var_14]
.text:00435612                 add     eax, [ebp+var_20]
.text:00435615                 mov     [ebp+var_14], eax
.text:00435618                 jmp     short loc_43561E
.text:0043561A ; ---------------------------------------------------------------------------
.text:0043561A
.text:0043561A loc_43561A:                             ; CODE XREF: check+1FA↑j
.text:0043561A                 xor     al, al
.text:0043561C                 jmp     short loc_435665
.text:0043561E ; ---------------------------------------------------------------------------
.text:0043561E
.text:0043561E loc_43561E:                             ; CODE XREF: check+1DD↑j
.text:0043561E                                         ; check+1E5↑j ...
.text:0043561E                 mov     eax, [ebp+arg_4]
.text:00435621                 movsx   ecx, byte ptr [eax]
.text:00435624                 cmp     ecx, 70h
.text:00435627                 jnz     short loc_435655
.text:00435629                 mov     eax, [ebp+var_8]
.text:0043562C                 add     eax, [ebp+var_38]
.text:0043562F                 js      short loc_435655
.text:00435631                 mov     eax, [ebp+var_14]
.text:00435634                 imul    eax, 28h
.text:00435637                 add     eax, [ebp+arg_0]
.text:0043563A                 mov     ecx, [ebp+var_8]
.text:0043563D                 add     ecx, [ebp+var_38]
.text:00435640                 cmp     dword ptr [eax+ecx*4], 0
.text:00435644                 jnz     short loc_435651
.text:00435646                 mov     eax, [ebp+var_8]
.text:00435649                 add     eax, [ebp+var_38]
.text:0043564C                 mov     [ebp+var_8], eax
.text:0043564F                 jmp     short loc_435655
.text:00435651 ; ---------------------------------------------------------------------------
.text:00435651
.text:00435651 loc_435651:                             ; CODE XREF: check+244↑j
.text:00435651                 xor     al, al
.text:00435653                 jmp     short loc_435665
.text:00435655 ; ---------------------------------------------------------------------------
.text:00435655
.text:00435655 loc_435655:                             ; CODE XREF: check+141↑j
.text:00435655                                         ; check+227↑j ...
.text:00435655                 mov     eax, [ebp+arg_4]
.text:00435658                 add     eax, 1
.text:0043565B                 mov     [ebp+arg_4], eax
.text:0043565E                 jmp     loc_435528
.text:00435663 ; ---------------------------------------------------------------------------
.text:00435663
.text:00435663 loc_435663:                             ; CODE XREF: check+131↑j
.text:00435663                 mov     al, 1

很明显的一个循环,循环条件是当传入的串的当前字节不是0x20时就进入循环进行计算,否则直接返回1
所以说只要transform_input函数计算出来一个0x20开头的串就可以直接成功。

 

此外当当前字节不是0x20且不为z, l, q, p时程序会一直向后读取,用12345678生成的解可行,
但是感觉这种比较靠运气,越界后的内存中如果z, l, q, p0x20先来可能就不行了。

 

所以还是先来看看transform_input进行的什么样的计算,有没有机会让它给我们生成一个带有0x20的值。

.text:00435E0D                 mov     [ebp+var_20], 0
... ...
.text:00435E4E                 mov     eax, [ebp+var_20]
.text:00435E51                 add     eax, 1
.text:00435E54                 mov     [ebp+var_20], eax
... ...
.text:00435F30                 mov     eax, [ebp+arg_0]
.text:00435F33                 add     eax, [ebp+var_20]
.text:00435F36                 movsx   ecx, byte ptr [eax]
.text:00435F39                 cmp     ecx, 20h             ;判断传入的是不是空格
.text:00435F3C                 jz      short loc_435F6A     ;成立跳转
.text:00435F3E                 mov     eax, [ebp+arg_0]
.text:00435F41                 add     eax, [ebp+var_20]
.text:00435F44                 movsx   ecx, byte ptr [eax]
.text:00435F47                 cmp     ecx, '/'             ;判断是不是'/'
.text:00435F4A                 jz      short loc_435F6A     ;成立跳转
.text:00435F4C                 mov     eax, [ebp+var_14]
.text:00435F4F                 add     eax, [ebp+var_2C]
.text:00435F52                 mov     ecx, [ebp+arg_0]
.text:00435F55                 add     ecx, [ebp+var_20]
.text:00435F58                 mov     dl, [ecx]
.text:00435F5A                 mov     [eax], dl
.text:00435F5C                 mov     eax, [ebp+var_2C]
.text:00435F5F                 add     eax, 1
.text:00435F62                 mov     [ebp+var_2C], eax
.text:00435F65                 jmp     loc_436065
.text:00435F6A ; ---------------------------------------------------------------------------
.text:00435F6A
.text:00435F6A loc_435F6A:                             ; CODE XREF: sub_435DE0+15C↑j
.text:00435F6A                                         ; sub_435DE0+16A↑j
.text:00435F6A                 mov     eax, [ebp+arg_0]
.text:00435F6D                 add     eax, [ebp+var_20]
.text:00435F70                 movsx   ecx, byte ptr [eax]
.text:00435F73                 cmp     ecx, 20h             ;再判断是不是空格
.text:00435F76                 jnz     loc_436045           ;成立跳转
.text:00435F7C                 mov     eax, [ebp+arg_0]
.text:00435F7F                 add     eax, [ebp+var_20]
.text:00435F82                 movsx   ecx, byte ptr [eax-1]
.text:00435F86                 cmp     ecx, '/'             ;判断 -1 的index是不是'/'
.text:00435F89                 jz      loc_436045           ;成立跳转
... ...
... ...
.text:00436045                 mov     eax, [ebp+arg_0]
.text:00436048                 add     eax, [ebp+var_20]
.text:0043604B                 movsx   ecx, byte ptr [eax]  
.text:0043604E                 cmp     ecx, '/'             ;判断是不是 '/'
.text:00436051                 jnz     short loc_436065     ;不成立跳走,计算下一轮
.text:00436053                 mov     eax, [ebp+arg_4]
.text:00436056                 add     eax, [ebp+var_38]
.text:00436059                 mov     byte ptr [eax], 20h  ;成立, 得到一个0x20
.text:0043605C                 mov     ecx, [ebp+var_38]
.text:0043605F                 add     ecx, 1
.text:00436062                 mov     [ebp+var_38], ecx
.text:00436065
.text:00436065 loc_436065:                             ; CODE XREF: sub_435DE0+185↑j
.text:00436065                                         ; sub_435DE0+263↑j ...
.text:00436065                 jmp     loc_435E4E

可以看出当输入的串为空格或/时会有 0x20的结果出现,所以找个在线base64计算一个全是/的key来。

0x02 生成可用解

因为规则限制解只能是字母数字,所以要找两次base64后不包含=的值,我这里就用///////来计算
两次base64的值为THk4dkx5OHZMdz09, 没找到在线SM3的计算,所以就用OD调试,在SM3比较处下断点,用程序自己计算的值9aa4f168af9fcb372825d2e817379ab6ad4a7da973a38c44a0ec56a788dfb89b
补到后面,得到一个可用解。

 

THk4dkx5OHZMdz099aa4f168af9fcb372825d2e817379ab6ad4a7da973a38c44a0ec56a788dfb89b


[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

收藏
点赞0
打赏
分享
最新回复 (1)
雪    币: 160
活跃值: 活跃值 (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
blck四 活跃值 2018-7-3 19:13
2
0
实在是777
游客
登录 | 注册 方可回帖
返回