首页
社区
课程
招聘
[原创] 看雪 ctf 攻防战 2018 - 追凶者也
2018-12-12 21:36 2497

[原创] 看雪 ctf 攻防战 2018 - 追凶者也

aqs 活跃值
5
2018-12-12 21:36
2497

一个 32位的 exe
自己电脑跑不起来,上班摸鱼又不敢花时间搞个win7,只能静态看了..

逻辑分析

ida 打开首先可以看到 WinMain 函数,进去看看

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  sub_401280();
  return 0;
}
.text:00401280 sub_401280      proc near               ; CODE XREF: WinMain(x,x,x,x)+5↑p
.text:00401280                                         ; DATA XREF: .data:off_414018↓o
.text:00401280                 push    ebp
.text:00401281                 mov     ebp, esp
.text:00401283                 push    eax
.text:00401284                 mov     eax, ebx
.text:00401286                 pop     eax
.text:00401287                 cmp     ebp, esp
.text:00401289                 call    __RTC_CheckEsp
.text:0040128E                 pop     ebp
.text:0040128F                 retn
.text:0040128F sub_401280      endp

WinMain 调了一个 函数,sub_401280 ,这个函数 call 了一个 CheckEsp 函数, 看 WinMain 的 xref 貌似 还加了反调试,应该是检查内存镜像完整性什么什么的
还好这个程序比较小,函数不多,乱点一下就可以找到关键逻辑
先看 DialogFunc 调用了下面这个函数

int __cdecl sub_401040(HWND hDlg)
{
......
  strcpy(Text, "try again!");
  strcpy(Caption, "fail");
  String = 0;
  v6 = 0;
  v7 = 0;
  v8 = 0;
  v9 = 0;
  v10 = 0;
  v11 = 0;
  GetDlgItemTextA(hDlg, 1001, &String, 20);
  v4 = 0;
  for ( i = 0; i < 20; ++i )
    v4 += *(&String + i);
  if ( v4 > 0 && v4 < 0x1024 )
  {
    v1 = malloc(v4);
    sub_401020();
    j___free_base(v1);
  }
  return MessageBoxA(0, Text, Caption, 0);
}

主要是

  • 获取输入
  • 每个byte的hex 相加 <0x1024
  • 分配内存
    然后调用了一个函数

    .text:00401020 sub_401020      proc near               ; CODE XREF: sub_401040+E9↓p
    .text:00401020
    .text:00401020 var_4           = dword ptr -4
    .text:00401020
    .text:00401020                 push    ebp
    .text:00401021                 mov     ebp, esp
    .text:00401023                 push    ecx
    .text:00401024                 mov     [ebp+var_4], 0CCCCCCCCh
    .text:0040102B                 mov     [ebp+var_4], offset loc_40D180
    .text:00401032                 mov     esp, ebp
    .text:00401034                 pop     ebp
    .text:00401035                 retn
    .text:00401035 sub_401020      endp
    

    这函数就是跳到了 loc_40D180 这个地址,这里是再 rdata 段
    ida p 一下就可以 f5 看了,开头像下面

    .rdata:0040D180                 push    ebp
    .rdata:0040D181                 mov     ebp, esp
    .rdata:0040D183                 sub     esp, 100h
    .rdata:0040D189                 mov     [ebp+var_40], 'K'
    .rdata:0040D18D                 mov     [ebp+var_3F], 'e'
    .rdata:0040D191                 mov     [ebp+var_3E], 'r'
    .rdata:0040D195                 mov     [ebp+var_3D], 'n'
    .rdata:0040D199                 mov     [ebp+var_3C], 'e'
    .rdata:0040D19D                 mov     [ebp+var_3B], 6Ch
    .rdata:0040D1A1                 mov     [ebp+var_3A], '3'
    .rdata:0040D1A5                 mov     [ebp+var_39], '2'
    .rdata:0040D1A9                 mov     [ebp+var_38], '.'
    .rdata:0040D1AD                 mov     [ebp+var_37], 'd'
    .rdata:0040D1B1                 mov     [ebp+var_36], 'l'
    .rdata:0040D1B5                 mov     [ebp+var_35], 'l'
    .rdata:0040D1B9                 mov     [ebp+var_34], 0
    .rdata:0040D1BD                 mov     [ebp+var_50], 'G'
    .rdata:0040D1C1                 mov     [ebp+var_4F], 'e'
    .rdata:0040D1C5                 mov     [ebp+var_4E], 't'
    .rdata:0040D1C9                 mov     [ebp+var_4D], 'P'
    .rdata:0040D1CD                 mov     [ebp+var_4C], 'r'
    .rdata:0040D1D1                 mov     [ebp+var_4B], 'o'
    .rdata:0040D1D5                 mov     [ebp+var_4A], 'c'
    .rdata:0040D1D9                 mov     [ebp+var_49], 'A'
    .rdata:0040D1DD                 mov     [ebp+var_48], 'd'
    .rdata:0040D1E1                 mov     [ebp+var_47], 'd'
    .rdata:0040D1E5                 mov     [ebp+var_46], 'r'
    .rdata:0040D1E9                 mov     [ebp+var_45], 'e'
    ....
    .rdata:0040D285                 mov     [ebp+var_15], 0
    .rdata:0040D289                 mov     [ebp+var_8], 's'
    .rdata:0040D28D                 mov     [ebp+var_7], 'u'
    .rdata:0040D291                 mov     [ebp+var_6], 'c'
    .rdata:0040D295                 mov     [ebp+var_5], 'c'
    .rdata:0040D299                 mov     [ebp+var_4], 'e'
    .rdata:0040D29D                 mov     [ebp+var_3], 's'
    .rdata:0040D2A1                 mov     [ebp+var_2], 's'
    

    写了一堆字符,最后可以看到 MessageBox , success 等, 这里应该是 loadlibary 然后调里面的 MessageBox 什么的吧,好像没有什么逻辑处理的东西???
    乱点函数看到了一个可疑的逻辑

    bool __cdecl sub_401290(int a1, int a2)
    {
    byte_4147D0[0] = 4;
    byte_4147D0[1] = 1;
    byte_4147D0[2] = 3;
    byte_4147D0[3] = 7;
    byte_4147D0[4] = 2;
    byte_4147D0[5] = 5;
    byte_4147D0[6] = 8;
    byte_4147D0[7] = 6;
    byte_4147D0[8] = 0;
    return sub_4015B0(a1, a2);
    }
    bool __cdecl sub_4015B0(int a1, int a2)
    {
    int i; // [esp+0h] [ebp-Ch]
    int v4; // [esp+8h] [ebp-4h]
    
    v4 = -858993460;
    if ( a2 % 2 )
      return 0;
    for ( i = 0; i < a2; i += 2 )
    {
      if ( *(_BYTE *)(i + a1) == 'w' )
        v4 = 0;
      if ( *(_BYTE *)(i + a1) == 'd' )
        v4 = 1;
      if ( *(_BYTE *)(i + a1) == 's' )
        v4 = 2;
      if ( *(_BYTE *)(i + a1) == 'a' )
        v4 = 3;
      if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) )
        return 0;
    }
    return byte_4147D0[0] == 1
        && byte_4147D0[1] == 2
        && byte_4147D0[2] == 3
        && byte_4147D0[3] == 4
        && byte_4147D0[4] == 5
        && byte_4147D0[5] == 6
        && byte_4147D0[6] == 7
        && byte_4147D0[7] == 8
        && !byte_4147D0[8];
    }
    

    看到 wdsa 基本上就可以确定关键逻辑在这里了,这是要玩游戏??
    注意到 rdata 是不可执行的,可能这里有什么SEH的处理逻辑在里面,木有时间,就先不管了,反正逻辑找到了
    看看上面两个函数的 xref 什么的,wdsa 比较的应该就是 输入的每个byte
    ,输入的格式是
    wXdXSXaXaX 类似这样,X是数字 0-9
    每次获取两个byte 然后进入 sub_401380
    最后要求byte_4147D0 这个表里面的内容是 1,2,...,8,0 这样,这个有9个项, 会不会是 3x3 的迷宫什么什么的
    进 sub_401380 看看

    if ( !a2 )
      return 0;
    v4 = 0;
    LABEL_4:
    if ( v4 >= 3 )
      return 0;
    for ( i = 0; ; ++i )
    {
      if ( i >= 3 )
      {
        ++v4;
        goto LABEL_4;
      }
      if ( byte_4147D0[3 * v4 + i] == a2 )
        break;
    LABEL_6:
      ;
    }
    

    一开头的逻辑,可以确定这是进行 一个 3x3 的表的操作了,这里是根据 我们输入的 wX 的 X 定位一个项, 后面 根据 wdsa switch 处理
    wdsa 一般想到的是 方向键,还原一下 这个表初始化的时候

    4 1 3
    7 2 5
    8 6 0
    

    这不会是拼图游戏吧,类似这样?

    4 1 3            4 1 3
    7 2 5   => d6 => 7 2 5
    8 6 0            8 0 6
    

    看一下后面 switch 的处理逻辑也基本可以确定了,那么就是要把初始化的表变成

    1 2 3
    4 5 6
    7 8 0
    

    玩了一下,结果是
    d6d8s7s4a1w2a5


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2018-12-12 21:44 被aqs编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回