• Buuoj reverse3


    1 打开reverse3.exe

    reverse3.exe

    2 ida32

    2.1 丢进ida反编译后,搜索字符串“flag”可以找到以下源码

    main0

    从下往上分析:
      (1)如果Dest和Str2前v2个字节相同,则得到的是正确的flag。而v2就是Dest的长度;
      (2)for循环对Dest进行修改,第j位元素的ASCII加上j;
      (3)将v1拷贝给Dest;
      (4)将Str经过sub_4110BE()后赋值给v1。sub_4110BE()只会return一个sub_411AB0()所以这个函数至关重要。
    Str2的值为:
    str2

    2.2 sub_411AB0函数

    由于截图截不全,直接把代码贴过来

    void *__cdecl sub_411AB0(char *a1, unsigned int a2, int *a3)
    {
      int v4; // STE0_4
      int v5; // STE0_4
      int v6; // STE0_4
      int v7; // [esp+D4h] [ebp-38h]
      signed int i; // [esp+E0h] [ebp-2Ch]
      unsigned int v9; // [esp+ECh] [ebp-20h]
      int v10; // [esp+ECh] [ebp-20h]
      signed int v11; // [esp+ECh] [ebp-20h]
      void *Dst; // [esp+F8h] [ebp-14h]
      char *v13; // [esp+104h] [ebp-8h]
    
      if ( !a1 || !a2 )
        return 0;
      v9 = a2 / 3;
      if ( (signed int)(a2 / 3) % 3 )
        ++v9;
      v10 = 4 * v9;
      *a3 = v10;
      Dst = malloc(v10 + 1);
      if ( !Dst )
        return 0;
      j_memset(Dst, 0, v10 + 1);
      v13 = a1;
      v11 = a2;
      v7 = 0;
      while ( v11 > 0 )
      {
        byte_41A144[2] = 0;
        byte_41A144[1] = 0;
        byte_41A144[0] = 0;
        for ( i = 0; i < 3 && v11 >= 1; ++i )
        {
          byte_41A144[i] = *v13;
          --v11;
          ++v13;
        }
        if ( !i )
          break;
        switch ( i )
        {
          case 1:
            *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
            v4 = v7 + 1;
            *((_BYTE *)Dst + v4++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
            *((_BYTE *)Dst + v4++) = aAbcdefghijklmn[64];
            *((_BYTE *)Dst + v4) = aAbcdefghijklmn[64];
            v7 = v4 + 1;
            break;
          case 2:
            *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
            v5 = v7 + 1;
            *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
            *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
            *((_BYTE *)Dst + v5) = aAbcdefghijklmn[64];
            v7 = v5 + 1;
            break;
          case 3:
            *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
            v6 = v7 + 1;
            *((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
            *((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
            *((_BYTE *)Dst + v6) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
            v7 = v6 + 1;
            break;
        }
      }
      *((_BYTE *)Dst + v7) = 0;
      return Dst;
    }
    
    1. 比较关键的地方从while里的for循环开始,它把v13的值传给了byte_41A144。v13实际上就是a1(我们再对应main里的变量,实际它就是那个我们输入的Str)。
    2. 然后这个i实际经过循环以后就是3,它是在for循环以前就被声明了。所以while中最核心的是
      b64
    3. 似曾相识,它就是base64,我在Base64百度百科中找到了最容易对应理解的一段话。
      base64
      以下的移位在上述解释中没提到
      移位
      很容易理解,这里移位前进行的变换对移位结果其实并没有啥影响。byte_41A144[1]&0xF0也就是11110000以后再右移4位和直接移位道理是一样的。下边那行同理。

    查看编码表aAbcdefghijklmn,是常规的Base64编码表
    编码表

    3 解密

    以上分析完,思路已经很清晰了。顺过程是:输入的字符串会先经过base64后,利用for循环把第j位元素的ASCII加上j再赋给第j位的元素。所以逆过程得到flag的步骤是:

    import base64
    str2 = 'e3nifIH9b_C@n@dH'
    rawDest = ""
    
    for i in range(len(str2)):
        rawDest += chr(ord(str2[i]) - i)
    print(rawDest)
    flag = base64.b64decode(rawDest)
    print(flag)
    

    flag{i_l0ve_you}

  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/vict0r/p/13205229.html
Copyright © 2020-2023  润新知