• BUUCTF-RE-[2019红帽杯]easyRE


    搜索关键字符串

    Shift+F12

    双击进去 Ctrl+x

    交叉引用的地方
    F5分析

    signed __int64 sub_4009C6()
    {
      __int64 v0; // rax
      signed __int64 result; // rax
      unsigned __int64 v2; // rax
      __int64 v3; // rax
      const __m128i *v4; // ST10_8
      const __m128i *v5; // ST18_8
      const __m128i *v6; // ST20_8
      const __m128i *v7; // ST28_8
      const __m128i *v8; // ST30_8
      const __m128i *v9; // ST38_8
      const __m128i *v10; // ST40_8
      const __m128i *v11; // ST48_8
      const __m128i *v12; // ST50_8
      __int64 v13; // ST58_8
      int i; // [rsp+Ch] [rbp-114h]
      char v15; // [rsp+60h] [rbp-C0h]
      char v16; // [rsp+61h] [rbp-BFh]
      char v17; // [rsp+62h] [rbp-BEh]
      char v18; // [rsp+63h] [rbp-BDh]
      char v19; // [rsp+64h] [rbp-BCh]
      char v20; // [rsp+65h] [rbp-BBh]
      char v21; // [rsp+66h] [rbp-BAh]
      char v22; // [rsp+67h] [rbp-B9h]
      char v23; // [rsp+68h] [rbp-B8h]
      char v24; // [rsp+69h] [rbp-B7h]
      char v25; // [rsp+6Ah] [rbp-B6h]
      char v26; // [rsp+6Bh] [rbp-B5h]
      char v27; // [rsp+6Ch] [rbp-B4h]
      char v28; // [rsp+6Dh] [rbp-B3h]
      char v29; // [rsp+6Eh] [rbp-B2h]
      char v30; // [rsp+6Fh] [rbp-B1h]
      char v31; // [rsp+70h] [rbp-B0h]
      char v32; // [rsp+71h] [rbp-AFh]
      char v33; // [rsp+72h] [rbp-AEh]
      char v34; // [rsp+73h] [rbp-ADh]
      char v35; // [rsp+74h] [rbp-ACh]
      char v36; // [rsp+75h] [rbp-ABh]
      char v37; // [rsp+76h] [rbp-AAh]
      char v38; // [rsp+77h] [rbp-A9h]
      char v39; // [rsp+78h] [rbp-A8h]
      char v40; // [rsp+79h] [rbp-A7h]
      char v41; // [rsp+7Ah] [rbp-A6h]
      char v42; // [rsp+7Bh] [rbp-A5h]
      char v43; // [rsp+7Ch] [rbp-A4h]
      char v44; // [rsp+7Dh] [rbp-A3h]
      char v45; // [rsp+7Eh] [rbp-A2h]
      char v46; // [rsp+7Fh] [rbp-A1h]
      char v47; // [rsp+80h] [rbp-A0h]
      char v48; // [rsp+81h] [rbp-9Fh]
      char v49; // [rsp+82h] [rbp-9Eh]
      char v50; // [rsp+83h] [rbp-9Dh]
      char v51[32]; // [rsp+90h] [rbp-90h]
      int v52; // [rsp+B0h] [rbp-70h]
      char v53; // [rsp+B4h] [rbp-6Ch]
      char v54; // [rsp+C0h] [rbp-60h]
      char v55; // [rsp+E7h] [rbp-39h]
      char v56; // [rsp+100h] [rbp-20h]
      unsigned __int64 v57; // [rsp+108h] [rbp-18h]
    
      v57 = __readfsqword(0x28u);
      v15 = 73;
      v16 = 111;
      v17 = 100;
      v18 = 108;
      v19 = 62;
      v20 = 81;
      v21 = 110;
      v22 = 98;
      v23 = 40;
      v24 = 111;
      v25 = 99;
      v26 = 121;
      v27 = 127;
      v28 = 121;
      v29 = 46;
      v30 = 105;
      v31 = 127;
      v32 = 100;
      v33 = 96;
      v34 = 51;
      v35 = 119;
      v36 = 125;
      v37 = 119;
      v38 = 101;
      v39 = 107;
      v40 = 57;
      v41 = 123;
      v42 = 105;
      v43 = 121;
      v44 = 61;
      v45 = 126;
      v46 = 121;
      v47 = 76;
      v48 = 64;
      v49 = 69;
      v50 = 67;     //v15-v50这是一个字符串数组
      memset(v51, 0, sizeof(v51));
      v52 = 0;
      v53 = 0;
      sub_4406E0(0LL, (__int64)v51);
    
      v53 = 0;
      LODWORD(v0) = sub_424BA0((const __m128i *)v51);
      if ( v0 == 36 )
      {
        for ( i = 0; ; ++i )
        {
          LODWORD(v2) = sub_424BA0((const __m128i *)v51);
          if ( i >= v2 )
            break;
          if ( (unsigned __int8)(v51[i] ^ i) != *(&v15 + i) ) //这里做了一次数组的异或
          {
            result = 0xFFFFFFFELL;
            goto LABEL_13;
          }
        }
        sub_410CC0((const __m128i *)"continue!");
        memset(&v54, 0, 0x40uLL);
        v56 = 0;
        sub_4406E0(0LL, (__int64)&v54);  //v54是又一次输入
        v55 = 0;
        LODWORD(v3) = sub_424BA0((const __m128i *)&v54);
        if ( v3 == 39 )
        {
          v4 = (const __m128i *)sub_400E44((const __m128i *)&v54);//这里反复套用做了十次的base64加密
          v5 = (const __m128i *)sub_400E44(v4);
          v6 = (const __m128i *)sub_400E44(v5);
          v7 = (const __m128i *)sub_400E44(v6);
          v8 = (const __m128i *)sub_400E44(v7);
          v9 = (const __m128i *)sub_400E44(v8);
          v10 = (const __m128i *)sub_400E44(v9);
          v11 = (const __m128i *)sub_400E44(v10);
          v12 = (const __m128i *)sub_400E44(v11);
          v13 = sub_400E44(v12);
      if ( !(unsigned int)sub_400360(v13, (__int64)off_6CC090) )//这里是判断v13这个结果base64处理之后的值和off_6CC090是不是相等
      {
            sub_410CC0((const __m128i *)"You found me!!!");
            sub_410CC0((const __m128i *)"bye bye~");
          }
          result = 0LL;
        }
        else
        {
          result = 0xFFFFFFFDLL;
        }
      }
      else
      {
        result = 0xFFFFFFFFLL;
      }
    LABEL_13:
      if ( __readfsqword(0x28u) != v57 )
        sub_444020();
      return result;
    }
    /* Orphan comments:
    Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJ
    */
    

    sub_400E44:这表明做了Base64加密 这个数组就是v54的这个数组

    off_6CC090的值是:

    把off_6CC090的值解密10次base64之后,得到的内容是网址:https://bbs.pediy.com/thread-254172.htm


    这个网址看起来没东西,flag就不是在这里。不对劲

    回到这里 发现 有两组数据 没见过的 Ctrl+X

    它们用的是同一段的函数

    再次交叉引用 可以看到 出现了_fini. 这样的字样

    .fini段的解释是:此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。


    这一段里面有数据
    我们分析该段

    unsigned __int64 sub_400D35()
    {
      unsigned __int64 result; // rax
      unsigned __int64 v1; // rt1
      unsigned int v2; // [rsp+Ch] [rbp-24h]
      signed int i; // [rsp+10h] [rbp-20h]
      signed int j; // [rsp+14h] [rbp-1Ch]
      unsigned int v5; // [rsp+24h] [rbp-Ch]
      unsigned __int64 v6; // [rsp+28h] [rbp-8h]
    
      v6 = __readfsqword(0x28u);
      v2 = sub_43FD20(0LL) - qword_6CEE38;
      for ( i = 0; i <= 1233; ++i )
      {
        sub_40F790(v2);
        sub_40FE60();
        sub_40FE60();
        v2 = (unsigned __int64)sub_40FE60() ^ 0x98765432;
      }
      v5 = v2;
      if ( ((unsigned __int8)v2 ^ byte_6CC0A0[0]) == ‘f’ && (HIBYTE(v5) ^ (unsigned __int8)byte_6CC0A3) == 'g') //通过这里反向推出v2和v5的值
      {
        for ( j = 0; j <= 24; ++j )
          sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v5 + j % 4)));
      }
      v1 = __readfsqword(0x28u);
      result = v1 ^ v6;
      if ( v1 != v6 )
        sub_444020();
      return result;
    }
    

    Byte_6CC0A0[]=[0x40,0x35,0x20]
    Byte_6CC0A3[]=[0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
    我们可以看到就是v2和Byte_6CC0A0[0]异或后等于'f' v5和Byte_6CC0A3异或后等于'g'
    合理推测v2v3v4v5 四个应该是flag 那么它们对应的应该是Byte_6CC0A0[0]-[3]和Byte_6CC0A3[0]
    那么flag的值就应该在Byte_6CC0A3[]里面一共25个字符

    后面这段数据咋找的思路:
    一般出题人不会无缘无故给一段没用的数据
    这段代码是会执行的,.fini段,是在程序的结束之后执行。了解了init,fini段后基本上都会检查这两个段的。
    [V&N2020 公开赛]strangeCpp这道题,也是把数据藏起来了没有引用,需要找。
    写程序的时候一般不会添加无用数据,所以发现有意义的数据看看交叉引用啥的……

    参考来自

    解题脚本

    第一组异或

    key = [73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,119,101,107,57,123,105,121,61,126,121,76,64,69,67]
    flag = ''
    for i in range(len(key)):
         flag+=chr(key[i]^i)
    print(flag)
    

    结果是:Info:The first four chars are flag
    这告诉我们该flag开头是flag

    推出v5的值

    v5=''
    enc='flag'
    key1=[0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
    for i in range(4):
            v5+=chr(key1[i]^ord(enc[i]))
    print(v5)
    

    v5的值是:&YA1

    flag值

    flag2=''
    for i in range(25):
        flag2+=chr(key1[i]^ord(v5[i%4]))
    print(flag2)
    

    flag{Act1ve_Defen5e_Test}

  • 相关阅读:
    EasyUI combox实现联动
    房费制(一)——上下机、总结
    6、Cocos2dx 3.0游戏开发的基本概念找个小三场比赛
    java 集装箱 arraylist 用法
    涂料动漫学习笔记(一)
    cocos2d-x plist在拍照
    Hadoop与HBase中遇到的问题(续)java.io.IOException: Non-increasing Bloom keys异常
    Java用ZIP格式压缩和解压缩文件
    Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释
    Oracle OS认证和口令文件认证方法
  • 原文地址:https://www.cnblogs.com/Nickyl07/p/13344953.html
Copyright © 2020-2023  润新知