吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4628|回复: 16
上一主题 下一主题
收起左侧

[CTF] 学破解第107天,《攻防世界reverse练习区srm-50》分析

[复制链接]
跳转到指定楼层
楼主
小菜鸟一枚 发表于 2020-6-27 17:07 回帖奖励

学破解第107天,《攻防世界reverse练习区srm-50》分析

前言:
  一直对黑客充满了好奇,觉得黑客神秘,强大,无所不能,来论坛两年多了,天天看各位大佬发帖,自己只能做一个伸手党。也看了官方的入门视频教程,奈何自己基础太差,看不懂。自我反思之下,决定从今天(2019年6月17日)开始定下心来,从简单的基础教程开始学习,希望能从照抄照搬,到能独立分析,能独立破解。
不知不觉学习了好几个月,发现自己离了教程什么都不会,不懂算法,不懂编程。随着破解学习的深入,楼主这个半吊子迷失了自我,日渐沉迷水贴装X,不能自拔。
==========申明:从第71天楼主开始水贴装X,帖子不再具有连续性,仅供参考,后续帖子为楼主YY专用贴!!!==========

立帖为证!--------记录学习的点点滴滴

0x1下载程序

  1.首先查壳,显示Microsoft Visual C++ v.14 - 2015 ( E8 ),无壳。

  2.运行程序看看,程序让我们输入邮箱和序列号,(注意这里如果随便输入会提示格式不正确)弹出注册失败的提示信息。

0x2上OD

  1.丢进吾爱的OD跑起来,搜索字符串,看到错误

004013B0  |.  0F2805 A00A41>movaps xmm0,dqword ptr ds:[0x410AA0]     ;  Registration fai
004013B7  |.  8D8D C0FDFFFF lea ecx,[local.144]
004013BD  |.  0F1145 E4     movups dqword ptr ss:[ebp-0x1C],xmm0
004013C1  |.  8D51 01       lea edx,dword ptr ds:[ecx+0x1]
004013C4  |.  C745 F4 6C757>mov [local.3],0x6572756C
004013CB  |.  0F2805 900A41>movaps xmm0,dqword ptr ds:[0x410A90]     ;  Registration SucRegistration fai
004013D2  |.  0F1145 C0     movups dqword ptr ss:[ebp-0x40],xmm0
004013D6  |.  66:C745 F8 2E>mov word ptr ss:[ebp-0x8],0x2E
004013DC  |.  0F2805 800A41>movaps xmm0,dqword ptr ds:[0x410A80]     ;  cess!\nYour flag Registration SucRegistration fai

  2.很好,定位到关键函数了,向上翻,看到了

0040130C  |.  68 00010000   push 0x100                               ; /Count = 100 (256.)
00401311  |.  50            push eax                                 ; |Buffer = NULL
00401312  |.  68 E9030000   push 0x3E9                               ; |ControlID = 3E9 (1001.)
00401317  |.  53            push ebx                                 ; |hWnd = NULL
00401318  |.  FFD6          call esi                                 ; \GetDlgItemTextA
0040131A  |.  68 00010000   push 0x100                               ; /Count = 100 (256.)
0040131F  |.  8D85 C0FDFFFF lea eax,[local.144]                      ; |
00401325  |.  50            push eax                                 ; |Buffer = NULL
00401326  |.  68 EA030000   push 0x3EA                               ; |ControlID = 3EA (1002.)
0040132B  |.  53            push ebx                                 ; |hWnd = NULL
0040132C  |.  FFD6          call esi                                 ; \GetDlgItemTextA

显然是在获取我输入的信息,所以我就在0040132E 这里下断,看看如何处理我输入的数据。

  3.F2在0040132E 这里下断点后,邮箱输入778899@qq.com,序列号输入778899,然后点击OK,断了下来,开始单步跟踪

0040132E  |.  8D85 C0FCFFFF lea eax,[local.208]                      ;  取邮箱778899@qq.com
00401334  |.  68 380A4100   push 9d2361b3.00410A38                   ;  @
00401339  |.  50            push eax                                 ;  eax入栈
0040133A  |.  E8 E10D0000   call 9d2361b3.00402120                   ;  检查邮箱格式是否正确
0040133F  |.  83C4 08       add esp,0x8                              ;  平衡堆栈
00401342  |.  85C0          test eax,eax                             ;  比较eax是否为0
00401344  |.  75 1E         jnz short 9d2361b3.00401364              ;  不为0则跳转
00401346  |>  68 3C0A4100   push 9d2361b3.00410A3C                   ;  Your E-mail address in not valid.

验证的过程没分析出来,反正不影响我们分析程序,这个call直接F8步过

  4.我这里输入的是正常的邮箱,所以上面那个jnz会跳转,然后继续F8,后面的代码的也是类似的,暂时没什么头绪。

0x3上IDA

  1.在OD分析的过程中,已经定位到了关键函数00401280,那么在IDA中找到这个函数,F5一下

BOOL __userpurge DialogFunc@<eax>(__m128i a1@<xmm0>, HWND hDlg, UINT a3, WPARAM a4, LPARAM a5)
{
  HMODULE v6; // eax@31
  HICON v7; // eax@31
  HMODULE v8; // eax@31
  HCURSOR v9; // ST20_4@31
  HWND v10; // eax@31
  CHAR String; // [sp+8h] [bp-340h]@5
  CHAR v12[4]; // [sp+108h] [bp-240h]@5
  char v13; // [sp+10Ch] [bp-23Ch]@21
  char v14; // [sp+10Dh] [bp-23Bh]@23
  char v15; // [sp+10Eh] [bp-23Ah]@25
  char v16; // [sp+10Fh] [bp-239h]@27
  char v17; // [sp+110h] [bp-238h]@28
  char v18; // [sp+111h] [bp-237h]@26
  char v19; // [sp+112h] [bp-236h]@24
  char v20; // [sp+113h] [bp-235h]@22
  char v21; // [sp+114h] [bp-234h]@20
  char v22; // [sp+115h] [bp-233h]@18
  char v23; // [sp+116h] [bp-232h]@16
  char v24; // [sp+117h] [bp-231h]@14
  CHAR Text; // [sp+208h] [bp-140h]@5
  __int128 v26; // [sp+308h] [bp-40h]@11
  __int128 v27; // [sp+318h] [bp-30h]@11
  int v28; // [sp+328h] [bp-20h]@11
  __int128 v29; // [sp+32Ch] [bp-1Ch]@11
  int v30; // [sp+33Ch] [bp-Ch]@11
  __int16 v31; // [sp+340h] [bp-8h]@11

  if ( a3 == 16 )
  {
    EndDialog(hDlg, 0);
    return 0;
  }
  if ( a3 == 272 )
  {
    v6 = GetModuleHandleW(0);
    v7 = LoadIconW(v6, (LPCWSTR)0x67);
    SetClassLongA(hDlg, -14, (LONG)v7);
    v8 = GetModuleHandleW(0);
    v9 = LoadCursorW(v8, (LPCWSTR)0x66);
    v10 = GetDlgItem(hDlg, 1);
    SetClassLongA(v10, -12, (LONG)v9);
    return 1;
  }
  if ( a3 != 273 || (unsigned __int16)a4 != 1 )
    return 0;
  sub_402710(&String, a4 - 1, 256);
  sub_402710(v12, 0, 256);
  sub_402710(&Text, 0, 256);
  GetDlgItemTextA(hDlg, 1001, &String, 256);
  GetDlgItemTextA(hDlg, 1002, v12, 256);
  if ( sub_402120(a1, (int)&String, (const __m128i *)&unk_410A38)
    && sub_402120(a1, (int)&String, (const __m128i *)".")
    && *(_BYTE *)(sub_402120(a1, (int)&String, (const __m128i *)".") + 1)
    && *(_BYTE *)(sub_402120(a1, (int)&String, (const __m128i *)&unk_410A38) + 1) != 46 )
  {
    v29 = xmmword_410AA0;
    v30 = 1701999980;
    v26 = xmmword_410A90;
    v31 = 46;
    v27 = xmmword_410A80;
    v28 = 3830633;
    if ( strlen(v12) != 16
      || v12[0] != 67
      || v24 != 88
      || v12[1] != 90
      || v12[1] + v23 != 155
      || v12[2] != 57
      || v12[2] + v22 != 155
      || v12[3] != 100
      || v21 != 55
      || v13 != 109
      || v20 != 71
      || v14 != 113
      || v14 + v19 != 170
      || v15 != 52
      || v18 != 103
      || v16 != 99
      || v17 != 56 )
    {
      sub_4030C7(&Text, 256, &v29);
    }
    else
    {
      sub_4030C7(&Text, 256, &v26);
      sub_403121(&Text, 256, v12);
    }
  }
  else
  {
    sub_4030C7(&Text, 256, "Your E-mail address in not valid.");
  }
  MessageBoxA(hDlg, &Text, "Registeration", 0x40u);
  return 1;
}

  2.外层if显然是判断邮件地址是否正确,不需要管他,去看里面的那一个if,根据经验知道必须满足if才是正确流程,接下来就分析这些代码的作用。

GetDlgItemTextA(hDlg, 1001, &String, 256);//邮箱
GetDlgItemTextA(hDlg, 1002, v12, 256);//用户名

这两行是将输入框的内容存入String和v12中,知道了两个重要变量的含义,我就直接去分析if里面的那一个if。

v29 = xmmword_410AA0;
    v30 = 1701999980;
    v26 = xmmword_410A90;
    v31 = 46;
    v27 = xmmword_410A80;
    v28 = 3830633;

上面这几行数据定义是不是有点懵,那么再看下之前在OD中看到的:

004013B0  |.  0F2805 A00A41>movaps xmm0,dqword ptr ds:[0x410AA0]     ;  Registration fai
004013B7  |.  8D8D C0FDFFFF lea ecx,[local.144]
004013BD  |.  0F1145 E4     movups dqword ptr ss:[ebp-0x1C],xmm0
004013C1  |.  8D51 01       lea edx,dword ptr ds:[ecx+0x1]
004013C4  |.  C745 F4 6C757>mov [local.3],0x6572756C
004013CB  |.  0F2805 900A41>movaps xmm0,dqword ptr ds:[0x410A90]     ;  Registration SucRegistration fai
004013D2  |.  0F1145 C0     movups dqword ptr ss:[ebp-0x40],xmm0
004013D6  |.  66:C745 F8 2E>mov word ptr ss:[ebp-0x8],0x2E
004013DC  |.  0F2805 800A41>movaps xmm0,dqword ptr ds:[0x410A80]     ;  cess!\nYour flag Registration SucRegistration fai
004013E3  |.  0F1145 D0     movups dqword ptr ss:[ebp-0x30],xmm0

可以知道[0x410AA0] 存储的是Registration fai,[0x410A90] 存储的是Registration SucRegistration fai,[0x410A80] 存储的是cess!\nYour flag Registration SucRegistration fai。

  3.变量定义清楚了,接下来就去看看if中的条件。

if (strlen(v12) != 16               //序列号长度要等于16
            || v12[0] != 67         //第一个字符要为字母C
            || v24 != 88            //v24要为字母X
            || v12[1] != 90         //第二个字符要为字母Z
            || v12[1] + v23 != 155  //v23要为字母A
            || v12[2] != 57         //第三个字符要为数字9
            || v12[2] + v22 != 155  //v22要为字母b
            || v12[3] != 100        //第四个字符要为字母d
            || v21 != 55            //v21要为数字7
            || v13 != 109           //v13要为字母m
            || v20 != 71            //v20要为字母G
            || v14 != 113           //v14要为字母q
            || v14 + v19 != 170     //v19要为数字9
            || v15 != 52            //v15要为数字4
            || v18 != 103           //v18要为字母g
            || v16 != 99            //v16要为字母c
            || v17 != 56)           //v17要为字母8

看似把它拼起来就是flag,然而我只知道数组v12的四个字符分别为CZ9d,后面的V变量的值代表的是序列号中的哪几位呢?

  4.去看看他们与v12的变量声明

    CHAR v12[4]; // [sp+108h] [bp-240h]@5
    char v13; // [sp+10Ch] [bp-23Ch]@21
    char v14; // [sp+10Dh] [bp-23Bh]@23
    char v15; // [sp+10Eh] [bp-23Ah]@25
    char v16; // [sp+10Fh] [bp-239h]@27
    char v17; // [sp+110h] [bp-238h]@28
    char v18; // [sp+111h] [bp-237h]@26
    char v19; // [sp+112h] [bp-236h]@24
    char v20; // [sp+113h] [bp-235h]@22
    char v21; // [sp+114h] [bp-234h]@20
    char v22; // [sp+115h] [bp-233h]@18
    char v23; // [sp+116h] [bp-232h]@16
    char v24; // [sp+117h] [bp-231h]@14

esp+108是V12[0],esp+109是v12[1],esp+10A是v12[2],esp+10B是v12[3],esp+10C是v13......,按照这个存储顺序,依次类推就能得出flag:CZ9dmq4c8g9G7bAX

0x4总结

  1.通过关键字符串搜索或messageBOX定位到关键函数
  2.使用IDA对关键函数进行F5,分析关键函数
  3.通过与OD对照,能让自己更加清晰的知道每个变量的值
  4.通过堆栈结构和数据类型所占空间大小,得出字符串的正确顺序

免费评分

参与人数 9威望 +1 吾爱币 +28 热心值 +9 收起 理由
尤雨溪 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
minboss + 1 + 1 用心讨论,共获提升!
feelings + 1 + 1 用心讨论,共获提升!
xiuji + 1 + 1 谢谢@Thanks!
三点半源码 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
iteamo + 2 + 1 谢谢@Thanks!
hnwang + 1 + 1 我很赞同!
alittlebear + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
hnwang 发表于 2020-6-27 18:06
跟楼主学习了不少东西 感谢
3#
终南明月 发表于 2020-6-27 18:42
4#
湖北吴彦祖 发表于 2020-6-27 19:19
5#
lxhwan100 发表于 2020-6-27 19:35
duang,
6#
6263085 发表于 2020-6-27 23:54
支持用心学习的
7#
lanhu2009 发表于 2020-6-28 02:57
坚持坚持
8#
xiuji 发表于 2020-6-28 09:04
学习了,感谢
9#
yitoumao 发表于 2020-6-28 09:39
加油加油
10#
weijian1215 发表于 2020-6-28 11:24
看着很高深,感谢分享。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 09:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表