• 攻防世界--game


    题目链接:https://adworld.xctf.org.cn/task/answer?type=reverse&number=4&grade=0&id=5074

    准备

    打开测试用例

    首先分析程序

    得到是win32程序

    第一种方法

    分析代码

    使用IDA打开,找到main函数,F5得到C代码

    得知主要是main_0这个函数,打开

     1     "If m of the Nth lamp is 1,it's on ,if not it's off
    "
     2     "At first all the lights were closed
    ");
     3   sub_45A7BE("Now you can input n to change its state
    ");
     4   sub_45A7BE(
     5     "But you should pay attention to one thing,if you change the state of the Nth lamp,the state of (N-1)th and (N+1)th w"
     6     "ill be changed too
    ");
     7   sub_45A7BE("When all lamps are on,flag will appear
    ");
     8   sub_45A7BE("Now,input n 
    ");
     9   while ( 1 )
    10   {
    11     while ( 1 )
    12     {
    13       sub_45A7BE("input n,n(1-8)
    ");
    14       sub_459418();
    15       sub_45A7BE("n=");
    16       sub_4596D4("%d", &v1);
    17       sub_45A7BE("
    ");
    18       if ( v1 >= 0 && v1 <= 8 )
    19         break;
    20       sub_45A7BE("sorry,n error,try again
    ");
    21     }
    22     if ( v1 )
    23     {
    24       sub_4576D6(v1 - 1);
    25     }
    26     else
    27     {
    28       for ( i = 0; i < 8; ++i )
    29       {
    30         if ( (unsigned int)i >= 9 )
    31           j____report_rangecheckfailure();
    32         byte_532E28[i] = 0;
    33       }
    34     }
    35     j__system("CLS");
    36     sub_458054();
    37     if ( byte_532E28[0] == 1
    38       && byte_532E28[1] == 1
    39       && byte_532E28[2] == 1
    40       && byte_532E28[3] == 1
    41       && byte_532E28[4] == 1
    42       && byte_532E28[5] == 1
    43       && byte_532E28[6] == 1
    44       && byte_532E28[7] == 1 )
    45     {
    46       sub_457AB4();
    47     }
    48   }
    49 }

    通过

        if ( byte_532E28[0] == 1
          && byte_532E28[1] == 1
          && byte_532E28[2] == 1
          && byte_532E28[3] == 1
          && byte_532E28[4] == 1
          && byte_532E28[5] == 1
          && byte_532E28[6] == 1
          && byte_532E28[7] == 1 )

    判断出我们需要将这八个数组的值都变为1,也就是8盏灯都闭合。

    分析规则

    打开sub_4576D6(v1 - 1);函数

    bool __cdecl sub_45E640(int a1)
    {
      bool result; // al
    
      if ( a1 )
      {
        if ( a1 == 7 )
        {
          byte_532E28[7] = byte_532E28[7] == 0;
          byte_532E27[7] = byte_532E27[7] == 0;
          result = 1;
          byte_532E28[0] = byte_532E28[0] == 0;
        }
        else
        {
          byte_532E28[a1] = byte_532E28[a1] == 0;
          byte_532E27[a1] = byte_532E27[a1] == 0;
          result = byte_532E29[a1] == 0;
          byte_532E29[a1] = result;
        }
      }
      else
      {
        byte_532E28[0] = byte_532E28[0] == 0;
        byte_532E29[0] = byte_532E29[0] == 0;
        result = 1;
        byte_532E28[7] = byte_532E28[7] == 0;
      }
      return result;
    }

    分析得到按键与电路闭合的关系:

    • 按1--闭合1,2,8
    • 按8--闭合1,7,8
    • 按i(除1,8)--闭合i-1,i,i+1

    暴力破解

    由此并结合C,汇编代码我们写出暴力破解的C++代码:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    #define for(a,b,c) for(int a = b; a < c; ++a)
    #define N 8
    
    vector<int> flag(8,-1);
    
    void func(int *arr){
        for(i,0,N){
            int n = arr[i];
            if(n == 0){
                flag[0] *= -1;
                flag[1] *= -1;
                flag[7] *= -1;
            }else{
                if(n == 7){
                    flag[0] *= -1;
                    flag[6] *= -1;
                    flag[7] *= -1;
                }else{
                    flag[n] *= -1;
                    flag[n-1] *= -1;
                    flag[n+1] *= -1;
                }
            }
        }
    }
    
    bool Judge(){
        for(i,0,8)
        if(flag[i] == -1)
        return false;
        
        return true;
    }
    
    int main(void)
    {
        int array[N] = {0};
        for(i,0,8)
        for(j,0,8)
        for(k,0,8)
        for(m,0,8)
        for(n,0,8)
        for(p,0,8)
        for(q,0,8)
        for(t,0,8){
            array[0] = i;
            array[1] = j;
            array[2] = k;
            array[3] = m;
            array[4] = n;
            array[5] = p;
            array[6] = q;
            array[7] = t;
            func(array);
            if(Judge()){
                cout << "success:" << i+1 << j+1 << k+1 << m+1 << n+1 << p+1 << q+1 << t+1 << endl;
                system("PAUSE");
            }else{
                for(x,0,8)
                fill(flag.begin(), flag.end(), -1);
            } 
        }
        
        cout << "over!";
        
        system("PAUSE");
        return 0;
    }

    get flag!

    输入到程序中

    第二种方法

    分析代码

    通过分析代码,我们很容易获知sub_457AB4()就是输出flag的函数

        if ( byte_532E28[0] == 1
          && byte_532E28[1] == 1
          && byte_532E28[2] == 1
          && byte_532E28[3] == 1
          && byte_532E28[4] == 1
          && byte_532E28[5] == 1
          && byte_532E28[6] == 1
          && byte_532E28[7] == 1 )
        {
          sub_457AB4();
        }
    int sub_45E940()
    {
      char v1; // [esp+0h] [ebp-164h]
      signed int i; // [esp+D0h] [ebp-94h]
      char v3; // [esp+DCh] [ebp-88h]
      char v4; // [esp+DDh] [ebp-87h]
      char v5; // [esp+DEh] [ebp-86h]
      char v6; // [esp+DFh] [ebp-85h]
      char v7; // [esp+E0h] [ebp-84h]
      char v8; // [esp+E1h] [ebp-83h]
      char v9; // [esp+E2h] [ebp-82h]
      char v10; // [esp+E3h] [ebp-81h]
      char v11; // [esp+E4h] [ebp-80h]
      char v12; // [esp+E5h] [ebp-7Fh]
      char v13; // [esp+E6h] [ebp-7Eh]
      char v14; // [esp+E7h] [ebp-7Dh]
      char v15; // [esp+E8h] [ebp-7Ch]
      char v16; // [esp+E9h] [ebp-7Bh]
      char v17; // [esp+EAh] [ebp-7Ah]
      char v18; // [esp+EBh] [ebp-79h]
      char v19; // [esp+ECh] [ebp-78h]
      char v20; // [esp+EDh] [ebp-77h]
      char v21; // [esp+EEh] [ebp-76h]
      char v22; // [esp+EFh] [ebp-75h]
      char v23; // [esp+F0h] [ebp-74h]
      char v24; // [esp+F1h] [ebp-73h]
      char v25; // [esp+F2h] [ebp-72h]
      char v26; // [esp+F3h] [ebp-71h]
      char v27; // [esp+F4h] [ebp-70h]
      char v28; // [esp+F5h] [ebp-6Fh]
      char v29; // [esp+F6h] [ebp-6Eh]
      char v30; // [esp+F7h] [ebp-6Dh]
      char v31; // [esp+F8h] [ebp-6Ch]
      char v32; // [esp+F9h] [ebp-6Bh]
      char v33; // [esp+FAh] [ebp-6Ah]
      char v34; // [esp+FBh] [ebp-69h]
      char v35; // [esp+FCh] [ebp-68h]
      char v36; // [esp+FDh] [ebp-67h]
      char v37; // [esp+FEh] [ebp-66h]
      char v38; // [esp+FFh] [ebp-65h]
      char v39; // [esp+100h] [ebp-64h]
      char v40; // [esp+101h] [ebp-63h]
      char v41; // [esp+102h] [ebp-62h]
      char v42; // [esp+103h] [ebp-61h]
      char v43; // [esp+104h] [ebp-60h]
      char v44; // [esp+105h] [ebp-5Fh]
      char v45; // [esp+106h] [ebp-5Eh]
      char v46; // [esp+107h] [ebp-5Dh]
      char v47; // [esp+108h] [ebp-5Ch]
      char v48; // [esp+109h] [ebp-5Bh]
      char v49; // [esp+10Ah] [ebp-5Ah]
      char v50; // [esp+10Bh] [ebp-59h]
      char v51; // [esp+10Ch] [ebp-58h]
      char v52; // [esp+10Dh] [ebp-57h]
      char v53; // [esp+10Eh] [ebp-56h]
      char v54; // [esp+10Fh] [ebp-55h]
      char v55; // [esp+110h] [ebp-54h]
      char v56; // [esp+111h] [ebp-53h]
      char v57; // [esp+112h] [ebp-52h]
      char v58; // [esp+113h] [ebp-51h]
      char v59; // [esp+114h] [ebp-50h]
      char v60; // [esp+120h] [ebp-44h]
      char v61; // [esp+121h] [ebp-43h]
      char v62; // [esp+122h] [ebp-42h]
      char v63; // [esp+123h] [ebp-41h]
      char v64; // [esp+124h] [ebp-40h]
      char v65; // [esp+125h] [ebp-3Fh]
      char v66; // [esp+126h] [ebp-3Eh]
      char v67; // [esp+127h] [ebp-3Dh]
      char v68; // [esp+128h] [ebp-3Ch]
      char v69; // [esp+129h] [ebp-3Bh]
      char v70; // [esp+12Ah] [ebp-3Ah]
      char v71; // [esp+12Bh] [ebp-39h]
      char v72; // [esp+12Ch] [ebp-38h]
      char v73; // [esp+12Dh] [ebp-37h]
      char v74; // [esp+12Eh] [ebp-36h]
      char v75; // [esp+12Fh] [ebp-35h]
      char v76; // [esp+130h] [ebp-34h]
      char v77; // [esp+131h] [ebp-33h]
      char v78; // [esp+132h] [ebp-32h]
      char v79; // [esp+133h] [ebp-31h]
      char v80; // [esp+134h] [ebp-30h]
      char v81; // [esp+135h] [ebp-2Fh]
      char v82; // [esp+136h] [ebp-2Eh]
      char v83; // [esp+137h] [ebp-2Dh]
      char v84; // [esp+138h] [ebp-2Ch]
      char v85; // [esp+139h] [ebp-2Bh]
      char v86; // [esp+13Ah] [ebp-2Ah]
      char v87; // [esp+13Bh] [ebp-29h]
      char v88; // [esp+13Ch] [ebp-28h]
      char v89; // [esp+13Dh] [ebp-27h]
      char v90; // [esp+13Eh] [ebp-26h]
      char v91; // [esp+13Fh] [ebp-25h]
      char v92; // [esp+140h] [ebp-24h]
      char v93; // [esp+141h] [ebp-23h]
      char v94; // [esp+142h] [ebp-22h]
      char v95; // [esp+143h] [ebp-21h]
      char v96; // [esp+144h] [ebp-20h]
      char v97; // [esp+145h] [ebp-1Fh]
      char v98; // [esp+146h] [ebp-1Eh]
      char v99; // [esp+147h] [ebp-1Dh]
      char v100; // [esp+148h] [ebp-1Ch]
      char v101; // [esp+149h] [ebp-1Bh]
      char v102; // [esp+14Ah] [ebp-1Ah]
      char v103; // [esp+14Bh] [ebp-19h]
      char v104; // [esp+14Ch] [ebp-18h]
      char v105; // [esp+14Dh] [ebp-17h]
      char v106; // [esp+14Eh] [ebp-16h]
      char v107; // [esp+14Fh] [ebp-15h]
      char v108; // [esp+150h] [ebp-14h]
      char v109; // [esp+151h] [ebp-13h]
      char v110; // [esp+152h] [ebp-12h]
      char v111; // [esp+153h] [ebp-11h]
      char v112; // [esp+154h] [ebp-10h]
      char v113; // [esp+155h] [ebp-Fh]
      char v114; // [esp+156h] [ebp-Eh]
      char v115; // [esp+157h] [ebp-Dh]
      char v116; // [esp+158h] [ebp-Ch]
    
      sub_45A7BE((int)"done!!! the flag is ", v1);
      v60 = 18;
      v61 = 64;
      v62 = 98;
      v63 = 5;
      v64 = 2;
      v65 = 4;
      v66 = 6;
      v67 = 3;
      v68 = 6;
      v69 = 48;
      v70 = 49;
      v71 = 65;
      v72 = 32;
      v73 = 12;
      v74 = 48;
      v75 = 65;
      v76 = 31;
      v77 = 78;
      v78 = 62;
      v79 = 32;
      v80 = 49;
      v81 = 32;
      v82 = 1;
      v83 = 57;
      v84 = 96;
      v85 = 3;
      v86 = 21;
      v87 = 9;
      v88 = 4;
      v89 = 62;
      v90 = 3;
      v91 = 5;
      v92 = 4;
      v93 = 1;
      v94 = 2;
      v95 = 3;
      v96 = 44;
      v97 = 65;
      v98 = 78;
      v99 = 32;
      v100 = 16;
      v101 = 97;
      v102 = 54;
      v103 = 16;
      v104 = 44;
      v105 = 52;
      v106 = 32;
      v107 = 64;
      v108 = 89;
      v109 = 45;
      v110 = 32;
      v111 = 65;
      v112 = 15;
      v113 = 34;
      v114 = 18;
      v115 = 16;
      v116 = 0;
      v3 = 123;
      v4 = 32;
      v5 = 18;
      v6 = 98;
      v7 = 119;
      v8 = 108;
      v9 = 65;
      v10 = 41;
      v11 = 124;
      v12 = 80;
      v13 = 125;
      v14 = 38;
      v15 = 124;
      v16 = 111;
      v17 = 74;
      v18 = 49;
      v19 = 83;
      v20 = 108;
      v21 = 94;
      v22 = 108;
      v23 = 84;
      v24 = 6;
      v25 = 96;
      v26 = 83;
      v27 = 44;
      v28 = 121;
      v29 = 104;
      v30 = 110;
      v31 = 32;
      v32 = 95;
      v33 = 117;
      v34 = 101;
      v35 = 99;
      v36 = 123;
      v37 = 127;
      v38 = 119;
      v39 = 96;
      v40 = 48;
      v41 = 107;
      v42 = 71;
      v43 = 92;
      v44 = 29;
      v45 = 81;
      v46 = 107;
      v47 = 90;
      v48 = 85;
      v49 = 64;
      v50 = 12;
      v51 = 43;
      v52 = 76;
      v53 = 86;
      v54 = 13;
      v55 = 114;
      v56 = 1;
      v57 = 117;
      v58 = 126;
      v59 = 0;
      for ( i = 0; i < 56; ++i )
      {
        *(&v3 + i) ^= *(&v60 + i);
        *(&v3 + i) ^= 0x13u;
      }
      return sub_45A7BE((int)"%s
    ", (unsigned int)&v3);
    }

    这实际上就是一段经过计算,输出flag的代码,for上面是已知条件,下面进行变换,我们可以转换为Python代码,输出flag

    脚本获取flag

    arr1 = [18, 64, 98, 5, 2, 4, 6, 3, 6, 48, 49, 65, 32, 12, 48, 65, 31, 78, 62, 32, 49, 32,
            1, 57, 96, 3, 21, 9, 4, 62, 3, 5, 4, 1, 2, 3, 44, 65, 78, 32, 16, 97, 54, 16, 44,
            52, 32, 64, 89, 45, 32, 65, 15, 34, 18, 16, 0]
    arr2 = [123, 32, 18, 98, 119, 108, 65, 41, 124, 80, 125, 38, 124, 111, 74, 49,
            83, 108, 94, 108, 84, 6, 96, 83, 44, 121, 104, 110, 32, 95, 117, 101, 99,
            123, 127, 119, 96, 48, 107, 71, 92, 29, 81, 107, 90, 85, 64, 12, 43, 76, 86,
            13, 114, 1, 117, 126, 0]
    
    str = ''
    
    for i in range(0, 56):
        arr2[0 + i] ^= arr1[0 + i]
        arr2[0 + i] ^= 0x13
        str = str + chr(arr2[i]);
    
    print(str)

    get flag!

    zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}

  • 相关阅读:
    sql server中将一个字段根据某个字符拆分成多个字段显示
    MVC中使用Action全局过滤器出现:网页无法正常运作 将您重定向的次数过多。解决办法
    C#中将DataTable转成List
    Dictionary读取键值的快捷方法
    jquery检测浏览器类型
    ubuntu安装网易云音乐
    Ufw使用指南
    MySQL数据库基础命令
    ubuntu搭建ftp后,winSCP连接报错为“列出’/home/ftp’的目录项时出错”
    linux ftp服务器设置,只允许用户访问指定的文件夹,禁止访问其他文件夹
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11370663.html
Copyright © 2020-2023  润新知