zoukankan      html  css  js  c++  java
  • 攻防世界-reverse-reverse-for-the-holy-grail-350

    拖到linux中调试

    IDA中查看主函数

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int v3; // ebx
      int v4; // ebx
      __int64 v5; // rbx
      void *v7; // [rsp+0h] [rbp-70h]
      __int64 v8; // [rsp+10h] [rbp-60h]
      void *v9; // [rsp+20h] [rbp-50h]
      __int64 v10; // [rsp+30h] [rbp-40h]
      void *v11; // [rsp+40h] [rbp-30h]
      __int64 v12; // [rsp+48h] [rbp-28h]
      char v13; // [rsp+50h] [rbp-20h]
    
      v11 = &v13;
      v12 = 0LL;
      v13 = 0;
      std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your name?", 21LL);
      std::endl<char,std::char_traits<char>>(&std::cout);
      std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v11);
      std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your quest?", 22LL);
      std::endl<char,std::char_traits<char>>(&std::cout);
      std::istream::ignore((std::istream *)&std::cin);
      std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v11);
      std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What...  is the secret password?", 32LL);
      std::endl<char,std::char_traits<char>>(&std::cout);
      std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &userIn);
      v7 = &v8;
      std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
        &v7,
        (_BYTE *)userIn,
        (_BYTE *)(qword_601AE8 + userIn));
      v3 = validChars(&v7);
      if ( v7 != &v8 )
        operator delete(v7);
      if ( v3 < 0 )
        goto LABEL_14;
      v9 = &v10;
      std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
        &v9,
        (_BYTE *)userIn,
        (_BYTE *)(qword_601AE8 + userIn));
      v4 = stringMod((__int64 *)&v9);            //关键函数
      if ( v9 != &v10 )
        operator delete(v9);
      if ( v4 < 0 )
      {
    LABEL_14:
        std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Auuuuuuuugh", 11LL);
        std::endl<char,std::char_traits<char>>(&std::cout);
      }
      else
      {
        std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Go on. Off you go. tuctf{", 25LL);
        v5 = std::__ostream_insert<char,std::char_traits<char>>(&std::cout, userIn, qword_601AE8);
        std::__ostream_insert<char,std::char_traits<char>>(v5, "}", 1LL);
        std::endl<char,std::char_traits<char>>(v5);
      }
      if ( v11 != &v13 )
        operator delete(v11);
      return 0;
    }
    

    stringMod函数:

    __int64 __fastcall stringMod(__int64 *input_password_str)
    {
      __int64 v1; // r9
      __int64 v2; // r10
      __int64 v3; // rcx
      signed int v4; // er8
      int *v5; // rdi
      int *v6; // rsi
      signed int v7; // ecx
      signed int v8; // er9
      int v9; // er10
      unsigned int v10; // eax
      int v11; // esi
      int v12; // esi
      int v14[24]; // [rsp+0h] [rbp-60h]
    
      memset(v14, 0, 0x48uLL);
      v1 = input_password_str[1];
      if ( v1 )
      {
        v2 = *input_password_str;
        v3 = 0LL;
        v4 = 0;
        do
        {
          v12 = *(char *)(v2 + v3);
          v14[v3] = v12;
          if ( 3 * ((unsigned int)v3 / 3) == (_DWORD)v3 && v12 != firstchar[(unsigned int)v3 / 3] )//       第 0,3,6,9,12,15个字符对应firstchar的六个字符
            v4 = -1;
          ++v3;
        }
        while ( v3 != v1 );
      }
      else
      {
        v4 = 0;
      }
      v5 = v14;
      v6 = v14;
      v7 = 666;
      do
      {
        *v6 = v7 ^ *(unsigned __int8 *)v6;          // 每个字符与v7异或
        v7 += v7 % 5;
        ++v6;
      }
      while ( &v14[18] != v6 );
      v8 = 1;
      v9 = 0;
      v10 = 1;
      v11 = 0;
      do
      {
        if ( v11 == 2 )
        {
          if ( *v5 != thirdchar[v9] )               // 异或后的字符串的第 2,5,8,11,14,17位对应thirdchar的六个数
            v4 = -1;
          if ( v10 % *v5 != masterArray[v9] )
            v4 = -1;
          ++v9;
          v10 = 1;
          v11 = 0;
        }
        else
        {                                                  //只有v11==2时才校验字符,所以
          v10 *= *v5;                               // v10 == 异或后的字符串的第 0+3*n 位 乘以第 1+3*n 位
          if ( ++v11 == 3 )
            v11 = 0;
        }
        ++v8;
        ++v5;
      }
      while ( v8 != 19 );                           // 循环 1~18
      return (unsigned int)(v7 * v4);
    }
    

    stringMod函数校验过程一共分为三部分,第一部分中需要值得注意的是:
    v3是int型,除以一个数后小数部分会被去掉,所以3 * ((unsigned int)v3 / 3) == (_DWORD)v3成立的条件是v33的倍数,因此flag的第 3*n 个字符对应firstchar的六个字符

    脚本

    i = 666
    num = []                                       # v7
    flag = 'A**i**n**E**o**a**'           # flag第0+3*n位对应firstchar
    Xorflag = []                                   # flag每位与v7异或的结果
    thirdchar = [0x2ef, 0x2c4, 0x2dc, 0x2c7, 0x2de, 0x2fc]
    masterarray = [0x1d7, 0xc, 0x244, 0x25e, 0x93, 0x6c]
    for j in range(18):                         # 求v7
        num.append(i)
        i += (i % 5)
    temp_num = 0
    for i in range(2, len(flag)+1, 3):        # 求flag 第 1+3*n位
        temp = thirdchar[temp_num] ^ num[i]
        temp_num += 1
        flag = flag[:i] + chr(temp) + flag[i+1:]
    temp_num = 0
    for i in range(len(flag)):                 # flag每位与v7异或
        temp = ord(flag[i]) ^ num[i]
        Xorflag.append(temp)
    for i in range(1, 19, 3):                    # 求flag第1+3*n位
        for j in range(32, 128):
            j ^= num[i]
            temp = j * Xorflag[i-1] % Xorflag[i+1]
            if temp == masterarray[temp_num]:
                flag = flag[:i] + chr(j ^ num[i]) + flag[i+1:]
                temp_num += 1
                break
    print("tuctf{" + flag + '}')
    
  • 相关阅读:
    Less:优雅的写CSS代码
    线程池(ThreadPool)
    TiDB
    Docker实现CentOS容器SSH远程登录
    Oracle-Hints详解
    Oracle sql执行计划解析
    引擎基本服务接口API介绍
    ssh远程连接docker中linux(ubuntu/centos)
    自制操作系统
    kafka-net
  • 原文地址:https://www.cnblogs.com/pluie/p/13179472.html
Copyright © 2011-2022 走看看