湖湘杯2020easyre题解

湖湘杯ezsyre题解

所需工具

  • IDA、任意Windows下调试器

解题流程

  • 入手题目。file查
~/Downloads/湖湘 » file easyre.exe                    wangxiaocheng@MacBook-
easyre.exe: PE32 executable (console) Intel 80386, for MS Windows

​ PE32,无脑打开run一下,可以看到是正常的输入flag然后检测

  • 黑盒测试试探。用Pin自带的inscount工具插桩一下程序,先模糊出输入长度后,改动输入,看指令数是否有变化。
    测试了几次,每次的指令数量都会有变化,可能是VS编译的方式吧,仅仅是个试探,于是没有深究。

  • 加载IDA中,交叉引用程序输出的字符串,可以很快定位到关键的代码。可以看到大概的流程,简单的接受参数,判断长度,然后后面的代码就有点迷茫,一大段的nop,什么都没有做。开始怀疑是不是在程序加载的时候会把这段nop替换为正常指令,于是开始动态调试。

  • 动态调试使用IDA自带的调试工具。调试的时候会发现比较怪异,程序总是会意外的飞走。

  • 点开检测长度的函数,可以看到有很多的“花指令”,引用了很多参数,看到最后引用到了参数49

    看一下栈的分布,可以知道这两个参数地址正是上层函数的返回地址的2个低字节位,明显改变了控制流。

  • 跳转到0x4048DA

    完全没有函数的样子,看样子是要分析汇编

  • 分析汇编()

    .text:004048DA                 mov     dword ptr [ebp-8], 0
    .text:004048E1                 mov     dword ptr [ebp-14h], 18h
    .text:004048E8                 sub     esp, 0Ch
    .text:004048EB                 pop     eax
    .text:004048EC                 mov     [ebp-8], eax			;	-8为输入,-0C为循环变量
    .text:004048EF                 mov     ecx, [ebp-8]
    .text:004048F2                 movzx   edx, byte ptr [ecx]
    .text:004048F5                 and     edx, 0E0h
    .text:004048FB                 mov     [ebp-0Dh], dl
    .text:004048FE                 mov     dword ptr [ebp-0Ch], 0
    .text:00404905                 jmp     short loc_404910
    .text:00404907 ; ---------------------------------------------------------------------------
    .text:00404907
    .text:00404907 loc_404907:                             ; CODE XREF: .text:00404952↓j
    .text:00404907                 mov     eax, [ebp-0Ch]		;看这个结构就知道是个for循环
    .text:0040490A                 add     eax, 1
    .text:0040490D                 mov     [ebp-0Ch], eax
    .text:00404910
    .text:00404910 loc_404910:                             ; CODE XREF: .text:00404905↑j
    .text:00404910                 mov     ecx, [ebp-14h]
    .text:00404913                 sub     ecx, 1
    .text:00404916                 cmp     [ebp-0Ch], ecx
    .text:00404919                 jge     short loc_404954 ;前17位进行操作
    .text:0040491B                 mov     edx, [ebp-8];当前字节shl 3位,下一字节sar 5位
    .text:0040491E                 add     edx, [ebp-0Ch]
    .text:00404921                 movzx   eax, byte ptr [edx]
    .text:00404924                 shl     eax, 3
    .text:00404927                 mov     ecx, [ebp-8]
    .text:0040492A                 add     ecx, [ebp-0Ch]
    .text:0040492D                 movzx   edx, byte ptr [ecx+1]
    .text:00404931                 sar     edx, 5
    .text:00404934                 or      eax, edx
    .text:00404936                 mov     ecx, [ebp-8]
    .text:00404939                 add     ecx, [ebp-0Ch]
    .text:0040493C                 mov     [ecx], al
    .text:0040493E                 mov     edx, [ebp-8]
    .text:00404941                 add     edx, [ebp-0Ch]
    .text:00404944                 movzx   eax, byte ptr [edx]
    .text:00404947                 xor     eax, [ebp-0Ch]
    .text:0040494A                 mov     ecx, [ebp-8]
    .text:0040494D                 add     ecx, [ebp-0Ch]
    .text:00404950                 mov     [ecx], al
    .text:00404952                 jmp     short loc_404907
    .text:00404954 ; ---------------------------------------------------------------------------
    .text:00404954
    .text:00404954 loc_404954:                             ; CODE XREF: .text:00404919↑j
    .text:00404954                 mov     edx, [ebp-8]
    .text:00404957                 add     edx, [ebp-14h]
    .text:0040495A                 movzx   eax, byte ptr [edx-1]
    .text:0040495E                 shl     eax, 3
    .text:00404961                 movzx   ecx, byte ptr [ebp-0Dh]
    .text:00404965                 sar     ecx, 5
    .text:00404968                 or      eax, ecx
    .text:0040496A                 mov     edx, [ebp-8];处理最后一位
    .text:0040496D                 add     edx, [ebp-14h]
    .text:00404970                 mov     [edx-1], al
    .text:00404973                 push    offset loc_40D7F6 ;retn后的地址
    .text:00404978                 retn
    

    需要关注的点就是for里的运算和最后的push and retn。

  • 运算。前17位都是取自己的低5位与下一字节的高3位组合,顺序是自己低5位在前,然后异或循环变量。以此类推,到最后一位的时候,把第一位的高3位放到后面。

  • push and retn即jmp,jmp后为一个简单的验证算法,结果数组也直接写在了内存里。

    .text:0040D7F6 loc_40D7F6:                             ; CODE XREF: .text:00404978↑j
    .text:0040D7F6                                         ; DATA XREF: .text:00404973↑o
    .text:0040D7F6                 mov     dword ptr [ebp-8], 0
    .text:0040D7FD                 sub     esp, 44h
    .text:0040D800                 pop     eax
    .text:0040D801                 add     esp, 40h
    .text:0040D804                 mov     [ebp-8], eax
    .text:0040D807                 mov     dword ptr [ebp-18h], 18h
    .text:0040D80E                 mov     dword ptr [ebp-0Ch], 0
    .text:0040D815                 jmp     short loc_40D820
    .text:0040D817 ; ---------------------------------------------------------------------------
    .text:0040D817
    .text:0040D817 loc_40D817:                             ; CODE XREF: .text:loc_40D880↓j
    .text:0040D817                 mov     ecx, [ebp-0Ch]
    .text:0040D81A                 add     ecx, 1
    .text:0040D81D                 mov     [ebp-0Ch], ecx
    .text:0040D820
    .text:0040D820 loc_40D820:                             ; CODE XREF: .text:0040D815↑j
    .text:0040D820                 mov     edx, [ebp-0Ch]
    .text:0040D823                 cmp     edx, [ebp-18h]
    .text:0040D826                 jge     short loc_40D882
    .text:0040D828                 mov     eax, [ebp-8]
    .text:0040D82B                 add     eax, [ebp-0Ch]
    .text:0040D82E                 movzx   ecx, byte ptr [eax]
    .text:0040D831                 mov     edx, [ebp-0Ch]
    .text:0040D834                 movzx   eax, byte_411000[edx];结果数组
    .text:0040D83B                 cmp     ecx, eax
    .text:0040D83D                 jz      short loc_40D880;循环检测
    .text:0040D83F                 mov     dword ptr [ebp-10h], 0
    .text:0040D846                 jmp     short loc_40D851
    .text:0040D848 ; ---------------------------------------------------------------------------
    .text:0040D848
    .text:0040D848 loc_40D848:                             ; CODE XREF: .text:0040D876↓j
    .text:0040D848                 mov     ecx, [ebp-10h]
    .text:0040D84B                 add     ecx, 1
    .text:0040D84E                 mov     [ebp-10h], ecx
    .text:0040D851
    .text:0040D851 loc_40D851:                             ; CODE XREF: .text:0040D846↑j
    .text:0040D851                 cmp     dword ptr [ebp-10h], 0Ah
    .text:0040D855                 jge     short loc_40D878
    .text:0040D857                 mov     edx, [ebp-10h]
    .text:0040D85A                 movzx   eax, byte_411020[edx]
    .text:0040D861                 xor     eax, 8Fh
    .text:0040D866                 push    eax
    .text:0040D867                 mov     ecx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
    .text:0040D86D                 push    ecx
    .text:0040D86E                 call    sub_401370
    .text:0040D873                 add     esp, 8
    .text:0040D876                 jmp     short loc_40D848
    .text:0040D878 ; ---------------------------------------------------------------------------
    .text:0040D878
    .text:0040D878 loc_40D878:                             ; CODE XREF: .text:0040D855↑j
    .text:0040D878                 push    0
    .text:0040D87A                 call    ds:__imp_exit
    .text:0040D880 ; ---------------------------------------------------------------------------
    .text:0040D880
    .text:0040D880 loc_40D880:                             ; CODE XREF: .text:0040D83D↑j
    .text:0040D880                 jmp     short loc_40D817
    .text:0040D882 ; ---------------------------------------------------------------------------
    .text:0040D882
    .text:0040D882 loc_40D882:                             ; CODE XREF: .text:0040D826↑j
    .text:0040D882                 mov     dword ptr [ebp-14h], 0
    .text:0040D889                 jmp     short loc_40D894
    .text:0040D88B ; ---------------------------------------------------------------------------
    .text:0040D88B
    .text:0040D88B loc_40D88B:                             ; CODE XREF: .text:0040D8BA↓j
    .text:0040D88B                 mov     edx, [ebp-14h]
    .text:0040D88E                 add     edx, 1
    .text:0040D891                 mov     [ebp-14h], edx
    .text:0040D894
    .text:0040D894 loc_40D894:                             ; CODE XREF: .text:0040D889↑j
    .text:0040D894                 cmp     dword ptr [ebp-14h], 33h
    .text:0040D898                 jge     short loc_40D8BC
    .text:0040D89A                 mov     eax, [ebp-14h]
    .text:0040D89D                 movzx   ecx, byte_41102C[eax]
    .text:0040D8A4                 xor     ecx, 8Fh
    .text:0040D8AA                 push    ecx
    .text:0040D8AB                 mov     edx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
    .text:0040D8B1                 push    edx
    .text:0040D8B2                 call    sub_401370
    .text:0040D8B7                 add     esp, 8
    .text:0040D8BA                 jmp     short loc_40D88B
    .text:0040D8BC ; ---------------------------------------------------------------------------
    .text:0040D8BC
    .text:0040D8BC loc_40D8BC:                             ; CODE XREF: .text:0040D898↑j
    .text:0040D8BC                 push    0
    .text:0040D8BE                 call    ds:__imp_exit
    

    这段代码就俩exit,猜一下就知道一个输出成功一个输出失败,虽然猜不猜都一样,主要关注最上面的循环验证就行了,提取结果数组直接逆运算就可得flag。

  • 解密脚本IDApython

    addr = 0x411000
    print("-------")
    a=''
    for i in range(24):
        a+=bin(Byte(addr+i)^i)[2:]
    print(a)
    

    然后把后三位剪切到前面,直接网上二进制转字符串,得到flagea5yre_1s_50_ea5y_t0_y0u最后md5一下

总结

这题主要是汇编阅读吧。还有一道IBM指令集的,实在是看不动,太菜了。

posted @ 2020-11-01 22:50  ixcWxc  阅读(452)  评论(0)    收藏  举报