zoukankan      html  css  js  c++  java
  • 攻防世界 reverse Windows_Reverse2

    Windows_Reverse2   2019_DDCTF

    查壳:

    寻找oep-->dump-->iat修复   便可成功脱壳

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      char Dest; // [esp+8h] [ebp-C04h]
      char v5; // [esp+9h] [ebp-C03h]
      char myinput; // [esp+408h] [ebp-804h]
      char Dst; // [esp+409h] [ebp-803h]
      char tg; // [esp+808h] [ebp-404h]
      char v9; // [esp+809h] [ebp-403h]
    
      myinput = 0;
      memset(&Dst, 0, 0x3FFu);
      tg = 0;
      memset(&v9, 0, 0x3FFu);
      printf("input code:");
      scanf("%s", &myinput);
      if ( !firstcheck_4011F0(&myinput) )
      {
        printf("invalid input
    ");
        exit(0);
      }
      maincheck_401240(&myinput, &tg);
      Dest = 0;
      memset(&v5, 0, 0x3FFu);
      sprintf(&Dest, "DDCTF{%s}", &tg);             // ADEBDEAEC7BE
      if ( !strcmp(&Dest, "DDCTF{reverse+}") )
        printf("You've got it !!! %s
    ", &Dest);
      else
        printf("Something wrong. Try again...
    ");
      return 0;
    }

    先进入第一处验证:

    char __usercall firstcheck_4011F0@<al>(const char *myinput@<esi>)
    {
      signed int lens; // eax
      signed int v2; // edx
      int v3; // ecx
      char v4; // al
    
      lens = strlen(myinput);
      v2 = lens;
      if ( lens && lens % 2 != 1 )                  // 2的倍数位
      {
        v3 = 0;
        if ( lens <= 0 )
          return 1;
        while ( 1 )
        {
          v4 = myinput[v3];
          if ( (v4 < '0' || v4 > '9') && (v4 < 'A' || v4 > 'F') )// 0-9 A-F
            break;
          if ( ++v3 >= v2 )
            return 1;
        }
      }
      return 0;
    }

    输入为0-9 A-F 之中的字符,2的倍数位

    再看下面的验证:

    int __usercall maincheck_401240@<eax>(const char *myinput@<esi>, char *tg)
    {
      signed int lens; // edi
      signed int i; // edx
      char t_; // bl
      char c; // al
      char v6; // al
      unsigned int v7; // ecx
      char t; // [esp+Bh] [ebp-405h]
      char v10; // [esp+Ch] [ebp-404h]
      char Dst; // [esp+Dh] [ebp-403h]
    
      lens = strlen(myinput);
      v10 = 0;
      memset(&Dst, 0, 0x3FFu);
      i = 0;
      if ( lens > 0 )//下面主要进行输入的转换,将输入的字符串按字面值存储,'0'-->0  ‘A’-->0x10  
      {
        t_ = t;
        do
        {
          c = myinput[i];
          if ( (unsigned __int8)(myinput[i] - '0') > 9u )
          {
            if ( (unsigned __int8)(c - 'A') <= 5u )
              t = c - '7';
          }
          else
          {
            t = myinput[i] - '0';
          }
          v6 = myinput[i + 1];
          if ( (unsigned __int8)(myinput[i + 1] - '0') > 9u )
          {
            if ( (unsigned __int8)(v6 - 'A') <= 5u )
              t_ = v6 - 55;
          }
          else
          {
            t_ = myinput[i + 1] - '0';
          }
          v7 = (unsigned int)i >> 1;
          i += 2;
          *(&v10 + v7) = t_ | 16 * t;
        }
        while ( i < lens );
      }
      return base64_encode_401000(lens / 2, tg);
    }
    base64_encode_401000
    int __cdecl base64_encode_401000(int size, void *tg)
    {
      char *v2; // ecx
      int v3; // ebp
      char *v4; // edi
      signed int v5; // esi
      unsigned __int8 v6; // bl
      signed int v7; // esi
      int v8; // edi
      int v9; // edi
      size_t v10; // esi
      void *v11; // edi
      const void *v12; // eax
      unsigned __int8 Dst; // [esp+14h] [ebp-38h]
      unsigned __int8 v15; // [esp+15h] [ebp-37h]
      unsigned __int8 v16; // [esp+16h] [ebp-36h]
      char v17; // [esp+18h] [ebp-34h]
      char v18; // [esp+19h] [ebp-33h]
      char v19; // [esp+1Ah] [ebp-32h]
      char i; // [esp+1Bh] [ebp-31h]
      void *v21; // [esp+1Ch] [ebp-30h]
      char v22; // [esp+20h] [ebp-2Ch]
      void *Src; // [esp+24h] [ebp-28h]
      size_t Size; // [esp+34h] [ebp-18h]
      unsigned int v25; // [esp+38h] [ebp-14h]
      int v26; // [esp+48h] [ebp-4h]
    
      v3 = size;
      v4 = v2;
      v21 = tg;
      std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<char,std::char_traits<char>,std::allocator<char>>(&v22);
      v5 = 0;
      v26 = 0;
      if ( size )
      {
        do
        {
          *(&Dst + v5) = *v4;
          v6 = v15;
          ++v5;
          --v3;
          ++v4;
          if ( v5 == 3 )
          {
            v17 = Dst >> 2;
            v18 = (v15 >> 4) + 16 * (Dst & 3);
            v19 = (v16 >> 6) + 4 * (v15 & 0xF);
            i = v16 & 0x3F;
            v7 = 0;
            do
              std::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(
                &v22,
                (unsigned __int8)(a745230189[(unsigned __int8)*(&v17 + v7++)] ^ 0x76));// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
            while ( v7 < 4 );
            v5 = 0;
          }
        }
        while ( v3 );
        if ( v5 )
        {
          if ( v5 < 3 )
          {
            memset(&Dst + v5, 0, 3 - v5);
            v6 = v15;
          }
          v18 = (v6 >> 4) + 16 * (Dst & 3);
          v17 = Dst >> 2;
          v19 = (v16 >> 6) + 4 * (v6 & 0xF);
          v8 = 0;
          for ( i = v16 & 0x3F; v8 < v5 + 1; ++v8 )
            std::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(
              &v22,
              (unsigned __int8)(a745230189[(unsigned __int8)*(&v17 + v8)] ^ 0x76));
          if ( v5 < 3 )
          {
            v9 = 3 - v5;
            do
            {
              std::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(&v22, '=');
              --v9;
            }
            while ( v9 );
          }
        }
      }
      v10 = Size;
      v11 = v21;
      memset(v21, 0, Size + 1);
      v12 = Src;
      if ( v25 < 0x10 )
        v12 = &Src;
      memcpy(v11, v12, v10);
      v26 = -1;
      return std::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string<char,std::char_traits<char>,std::allocator<char>>();
    }

    发现有点像base64编码,编码表^ 0x76,脚本跑出来发现正好是标准密码表

    最后的验证即 输入为大写16进制字符串,base64编码,验证结果是否为‘reverse+’

    base64 解码‘reverse+ ’  便可得到输入

    wp(python2):

    import base64
    s='reverse+'
    print base64.b64decode(s).encode('hex').upper()

    ADEBDEAEC7BE

    flag{ADEBDEAEC7BE}

      

  • 相关阅读:
    分布式与集群的区别是什么?
    Java NIO:IO与NIO的区别 JAVA BIO与NIO、AIO的区别
    localStorage使用总结 JS 详解 Cookie、 LocalStorage 与 SessionStorage
    tomcat+nginx+redis实现均衡负载、session共享 存储过程的优缺点 HTTP、TCP、IP协议常见面试题
    高并发下的Java数据结构(List、Set、Map)
    [剑指offer] 31. 整数中1出现的次数(从1到n整数中1出现的次数)
    [剑指offer] 30. 连续子数组的最大和
    [剑指offer] 29. 最小的K个数
    [剑指offer] 28. 数组中出现次数超过一半的数字
    [leetcode] 51. N-Queens (递归)
  • 原文地址:https://www.cnblogs.com/DirWang/p/12347399.html
Copyright © 2011-2022 走看看