Simple Reverse - 0x15(2023 HW - crackme_vectorization)

Simple Reverse - 0x15(2023 HW - crackme_vectorization)

Source Code

  • IDA Main Function
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    __int64 __fastcall main(int a1, char **a2, char **a3)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      __isoc99_scanf("%d", &user_input_len);        // 長度為49
      user_input_len_cp = user_input_len;
      sqrt_length = sqrt((double)user_input_len);   // 開根號後是7
      sqrt_length_cp = (int)sqrt_length;
      if ( sqrt_length > (double)(int)sqrt_length )
        ++sqrt_length_cp;
      sqrt_len = _mm_shuffle_epi32(_mm_cvtsi32_si128(sqrt_length_cp), 224).m128i_u64[0];// 原本的shuffle num就是user input length的開根號結果
      space = (struc_1 *)malloc(0x10uLL);
      space->sqrt_len = sqrt_len;
      size = 4 * sqrt_length_cp * (__int64)sqrt_length_cp;// size是196
      shuffle_space = malloc(size);
      space->content_space = (__int64)shuffle_space;
      if ( user_input_len_cp > 0 )
      {
        shuffle_space_cp = shuffle_space;
        len = 0LL;
        do
        {
          __isoc99_scanf("%d", content);
          shuffle_space_cp[len++] = content[0];
        }
        while ( user_input_len > (int)len );        // 要輸入東西49次
      }
      if ( length == sqrt_length_cp
        && (space_1 = (struc_1 *)malloc(0x10uLL),
            space_1->sqrt_len = sqrt_len,
            shuffle_space_1 = malloc(size),
            src = cipher_flag,
            space_1->content_space = (__int64)shuffle_space_1,
            memcpy(shuffle_space_1, src, size),
            result = ugly_matrix_multiplication(
                      (int *)space_1,
                      (__int64)space),             // guess_cipher的大小是196
                                                    // 他會把我們輸入的東西和他原本的東西一起送到guess_encrypt的這個function中
            !memcmp((const void *)result[1], verify_key, size)) )
      {
        puts("Correct!");
      }
      else
      {
        puts(":(");
      }
      return 0LL;
    }
    
  • IDA Ugly Function
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    _QWORD *__fastcall guess_encrypt(int *space_1, __int64 space)
    {
      // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
    
      _RAX = malloc(0x10uLL);
      _RDI = *space_1;
      guess_cipher = _RAX;
      length_0x4 = *(int *)(space + 4);
      __asm { vmovd   xmm5, edi }
      length_0x0 = *space_1;
      _RBX = 4 * length_0x4;
      __asm { vpinsrd xmm0, xmm5, r13d, 1 }
      length_0x4_cp = length_0x4;
      __asm { vmovq   qword ptr [rax], xmm0 }
      space_2 = malloc(4 * length_0x4 * _RDI);
      guess_cipher[1] = space_2;
      if ( length_0x0 > 0 )
      {
        length_0x4_cp2 = length_0x4;
        if ( (int)length_0x4 > 0 )
        {
          length_0x0_2 = space_1[1];
          length_0x0_cp = length_0x0;
          guess_cipher_1 = guess_cipher;
          length_16_0x4 = 16 * length_0x4;
          space_2_cp = space_2;
          length_0x0_2_minus_1 = length_0x0_2 - 1;
          space_1_cp = space_1;
          length_0x0_2_x_4 = 16LL * ((unsigned int)length_0x0_2 >> 2);
          v14 = 0;
          while ( 1 )
          {
            v15 = 0LL;
            v16 = length_0x0_2 * v14;
            v87 = 4LL * length_0x0_2 * v14;
            cmd = length_0x4_cp & 7;
            if ( (length_0x4_cp & 7) == 0 )
              goto LABEL_44;
            switch ( cmd )
            {
              case 1LL:
                goto LABEL_42;
              case 2LL:
                goto LABEL_40;
              case 3LL:
                goto LABEL_38;
              case 4LL:
                goto LABEL_36;
              case 5LL:
                goto LABEL_34;
            }
            if ( cmd != 6 )
            {
              if ( length_0x0_2 > 0 )
                goto LABEL_12;
              v15 = 1LL;
              *space_2_cp = 0;
            }
            if ( length_0x0_2 <= 0 )
              break;
    LABEL_12:
            v92 = v14;
            v18 = v15;
            v19 = *((_QWORD *)space_1_cp + 1);
            v20 = *(_QWORD *)(space + 8);
            if ( length_0x0_2_minus_1 <= 2 )
              goto LABEL_26;
            while ( 1 )
            {
              _R15 = v20 + 4 * v15;
              __asm { vpxor   xmm0, xmm0, xmm0 }
              v23 = v19 + v87;
              v24 = length_0x0_2_x_4 + v19 + v87;
              v25 = ((unsigned __int8)((unsigned __int64)(length_0x0_2_x_4 - 16) >> 4) + 1) & 3;
              if ( (((unsigned __int8)((unsigned __int64)(length_0x0_2_x_4 - 16) >> 4) + 1) & 3) == 0 )
                goto LABEL_51;
              if ( v25 != 1 )
              {
                if ( v25 != 2 )
                {
                  __asm
                  {
                    vmovd   xmm3, dword ptr [r15+rbx*2]
                    vmovd   xmm4, dword ptr [r15]
                  }
                  v23 += 16LL;
                  __asm
                  {
                    vpinsrd xmm2, xmm3, dword ptr [r15+r8], 1
                    vpinsrd xmm1, xmm4, dword ptr [r15+rbx], 1
                  }
                  _R15 += length_16_0x4;
                  __asm
                  {
                    vpunpcklqdq xmm6, xmm1, xmm2
                    vpmulld xmm0, xmm6, xmmword ptr [rdx-10h]
                  }
                }
                __asm
                {
                  vmovd   xmm7, dword ptr [r15+rbx*2]
                  vmovd   xmm9, dword ptr [r15]
                }
                v23 += 16LL;
                __asm
                {
                  vpinsrd xmm8, xmm7, dword ptr [r15+r8], 1
                  vpinsrd xmm10, xmm9, dword ptr [r15+rbx], 1
                }
                _R15 += length_16_0x4;
                __asm
                {
                  vpunpcklqdq xmm11, xmm10, xmm8
                  vpmulld xmm12, xmm11, xmmword ptr [rdx-10h]
                  vpaddd  xmm0, xmm0, xmm12
                }
              }
              __asm
              {
                vmovd   xmm13, dword ptr [r15+rbx*2]
                vmovd   xmm15, dword ptr [r15]
              }
              v23 += 16LL;
              __asm
              {
                vpinsrd xmm14, xmm13, dword ptr [r15+r8], 1
                vpinsrd xmm5, xmm15, dword ptr [r15+rbx], 1
              }
              _R15 += length_16_0x4;
              __asm
              {
                vpunpcklqdq xmm3, xmm5, xmm14
                vpmulld xmm2, xmm3, xmmword ptr [rdx-10h]
                vpaddd  xmm0, xmm0, xmm2
              }
              if ( v24 != v23 )
              {
    LABEL_51:
                do
                {
                  __asm
                  {
                    vmovd   xmm4, dword ptr [r15+rbx*2]
                    vmovd   xmm6, dword ptr [r15]
                  }
                  v23 += 64LL;
                  __asm
                  {
                    vpinsrd xmm1, xmm4, dword ptr [r15+r8], 1
                    vpinsrd xmm7, xmm6, dword ptr [r15+rbx], 1
                  }
                  _R15 = length_16_0x4 + _R15;
                  __asm
                  {
                    vmovd   xmm11, dword ptr [r15+rbx*2]
                    vmovd   xmm13, dword ptr [r15]
                    vpinsrd xmm12, xmm11, dword ptr [r15+r8], 1
                    vpinsrd xmm14, xmm13, dword ptr [r15+rbx], 1
                  }
                  _R15 = length_16_0x4 + _R15;
                  __asm
                  {
                    vpunpcklqdq xmm8, xmm7, xmm1
                    vmovd   xmm3, dword ptr [r15+rbx*2]
                    vpmulld xmm9, xmm8, xmmword ptr [rdx-40h]
                    vpinsrd xmm4, xmm3, dword ptr [r15+r8], 1
                    vpaddd  xmm10, xmm0, xmm9
                    vmovd   xmm2, dword ptr [r15]
                    vpinsrd xmm1, xmm2, dword ptr [r15+rbx], 1
                  }
                  _R15 = length_16_0x4 + _R15;
                  __asm
                  {
                    vpunpcklqdq xmm15, xmm14, xmm12
                    vmovd   xmm9, dword ptr [r15+rbx*2]
                    vmovd   xmm11, dword ptr [r15]
                    vpmulld xmm5, xmm15, xmmword ptr [rdx-30h]
                    vpinsrd xmm12, xmm11, dword ptr [r15+rbx], 1
                    vpaddd  xmm0, xmm10, xmm5
                    vpunpcklqdq xmm6, xmm1, xmm4
                    vpmulld xmm7, xmm6, xmmword ptr [rdx-20h]
                    vpinsrd xmm10, xmm9, dword ptr [r15+r8], 1
                    vpaddd  xmm8, xmm0, xmm7
                  }
                  _R15 = length_16_0x4 + _R15;
                  __asm
                  {
                    vpunpcklqdq xmm13, xmm12, xmm10
                    vpmulld xmm14, xmm13, xmmword ptr [rdx-10h]
                    vpaddd  xmm0, xmm8, xmm14
                  }
                }
                while ( v24 != v23 );
              }
              __asm
              {
                vpsrldq xmm15, xmm0, 8
                vpaddd  xmm5, xmm0, xmm15
                vpsrldq xmm0, xmm5, 4
              }
              v75 = length_0x0_2 & 0xFFFFFFFC;
              __asm
              {
                vpaddd  xmm3, xmm5, xmm0
                vmovd   ecx, xmm3
              }
              if ( length_0x0_2 != (length_0x0_2 & 0xFFFFFFFC) )
                goto LABEL_21;
    LABEL_24:
              space_2_cp[v15++] = _ECX;
              if ( length_0x4_cp == v15 )
                break;
              v18 = v15;
              if ( length_0x0_2_minus_1 <= 2 )
              {
    LABEL_26:
                v75 = 0;
                _ECX = 0;
    LABEL_21:
                v78 = v75 + 1;
                _ECX += *(_DWORD *)(v20 + 4LL * (int)(v75 * length_0x4_cp2 + v18))
                      * *(_DWORD *)(v19 + 4LL * (int)(v16 + v75));
                if ( (int)(v75 + 1) < length_0x0_2 )
                {
                  v79 = length_0x4_cp2 + v75 * length_0x4_cp2;
                  v80 = v75 + 2;
                  _ECX += *(_DWORD *)(v20 + 4LL * (v79 + v18)) * *(_DWORD *)(v19 + 4LL * (int)(v16 + v78));
                  if ( length_0x0_2 > v80 )
                    _ECX += *(_DWORD *)(v19 + 4LL * (v16 + v80)) * *(_DWORD *)(v20 + 4LL * (v18 + length_0x4_cp2 + v79));
                }
                goto LABEL_24;
              }
            }
            v14 = v92;
    LABEL_28:
            space_2_cp = (_DWORD *)((char *)space_2_cp + _RBX);
            if ( length_0x0_cp == ++v14 )
              return guess_cipher_1;
          }
          space_2_cp[v15++] = 0;
    LABEL_34:
          if ( length_0x0_2 > 0 )
            goto LABEL_12;
          space_2_cp[v15++] = 0;
    LABEL_36:
          if ( length_0x0_2 > 0 )
            goto LABEL_12;
          space_2_cp[v15++] = 0;
    LABEL_38:
          if ( length_0x0_2 > 0 )
            goto LABEL_12;
          space_2_cp[v15++] = 0;
    LABEL_40:
          if ( length_0x0_2 > 0 )
            goto LABEL_12;
          space_2_cp[v15++] = 0;
    LABEL_42:
          if ( length_0x0_2 > 0 )
            goto LABEL_12;
          space_2_cp[v15++] = 0;
          if ( length_0x4_cp == v15 )
            goto LABEL_28;
    LABEL_44:
          v82 = v15;
          while ( length_0x0_2 <= 0 )
          {
            space_2_cp[v82] = 0;
            v83 = v82 + 1;
            space_2_cp[v83] = 0;
            space_2_cp[v83 + 1] = 0;
            space_2_cp[v83 + 2] = 0;
            space_2_cp[v83 + 3] = 0;
            space_2_cp[v83 + 4] = 0;
            space_2_cp[v83 + 5] = 0;
            space_2_cp[v83 + 6] = 0;
            v82 = v83 + 7;
            if ( length_0x4_cp == v82 )
              goto LABEL_28;
          }
          v15 = v82;
          goto LABEL_12;
        }
      }
      return guess_cipher;
    }
    

Recon

一陣基本操作處理完比較好看的狀態後,首先發現一開始先輸入字串的長度(應該是49),然後我們要輸入一些東西(就是按照前面輸入,總共也是49次),接著就會進到很醜沒辦法解析的function(我暫時不理他),一開始我在猜應該是做encryption之類的事情,接著就比對mem,一樣就噴correct這樣,我認為超級醜的function應該不是這次出題的重點,因為要全部逆完真的很有難度,對於學習也沒必要,此時我開始用動態+通靈的方式猜他在幹嘛,依照題目的標題和後面對比字串長度必須要等於7這兩個東西判斷,他應該是在做矩陣之類的操作,而那個醜不拉基的function應該是類似乘法或是加法之類的功能,有了想法就可以實驗他的操作 如果輸入長度49

  1. 內容都是零,毫不意外經過醜不拉基function後都會是零
    • Result
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      0x000055aa2b46b4b0│+0x0000: 0x0000000000000000   ← $rdi
      0x000055aa2b46b4b8│+0x0008: 0x0000000000000000
      0x000055aa2b46b4c0│+0x0010: 0x0000000000000000
      0x000055aa2b46b4c8│+0x0018: 0x0000000000000000
      0x000055aa2b46b4d0│+0x0020: 0x0000000000000000
      0x000055aa2b46b4d8│+0x0028: 0x0000000000000000
      0x000055aa2b46b4e0│+0x0030: 0x0000000000000000
      0x000055aa2b46b4e8│+0x0038: 0x0000000000000000
      0x000055aa2b46b4f0│+0x0040: 0x0000000000000000
      0x000055aa2b46b4f8│+0x0048: 0x0000000000000000
      0x000055aa2b46b500│+0x0050: 0x0000000000000000
      0x000055aa2b46b508│+0x0058: 0x0000000000000000
      0x000055aa2b46b510│+0x0060: 0x0000000000000000
      0x000055aa2b46b518│+0x0068: 0x0000000000000000
      0x000055aa2b46b520│+0x0070: 0x0000000000000000
      0x000055aa2b46b528│+0x0078: 0x0000000000000000
      0x000055aa2b46b530│+0x0080: 0x0000000000000000
      0x000055aa2b46b538│+0x0088: 0x0000000000000000
      0x000055aa2b46b540│+0x0090: 0x0000000000000000
      0x000055aa2b46b548│+0x0098: 0x0000000000000000
      0x000055aa2b46b550│+0x00a0: 0x0000000000000000
      0x000055aa2b46b558│+0x00a8: 0x0000000000000000
      0x000055aa2b46b560│+0x00b0: 0x0000000000000000
      0x000055aa2b46b568│+0x00b8: 0x0000000000000000
      0x000055aa2b46b570│+0x00c0: 0x0000000000000000
      
  2. 內容都是一,經過醜不拉基function後都會每七個都是同一個數字
    • Result
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      0x000055d2f80754b0│+0x0000: 0x000003d4000003d4   ← $rdi
      0x000055d2f80754b8│+0x0008: 0x000003d4000003d4
      0x000055d2f80754c0│+0x0010: 0x000003d4000003d4
      0x000055d2f80754c8│+0x0018: 0x000002d8000003d4
      0x000055d2f80754d0│+0x0020: 0x000002d8000002d8
      0x000055d2f80754d8│+0x0028: 0x000002d8000002d8
      0x000055d2f80754e0│+0x0030: 0x000002d8000002d8
      0x000055d2f80754e8│+0x0038: 0x0000030f0000030f
      0x000055d2f80754f0│+0x0040: 0x0000030f0000030f
      0x000055d2f80754f8│+0x0048: 0x0000030f0000030f
      0x000055d2f8075500│+0x0050: 0x000003000000030f
      0x000055d2f8075508│+0x0058: 0x0000030000000300
      0x000055d2f8075510│+0x0060: 0x0000030000000300
      0x000055d2f8075518│+0x0068: 0x0000030000000300
      0x000055d2f8075520│+0x0070: 0x000003b0000003b0
      0x000055d2f8075528│+0x0078: 0x000003b0000003b0
      0x000055d2f8075530│+0x0080: 0x000003b0000003b0
      0x000055d2f8075538│+0x0088: 0x000003c6000003b0
      0x000055d2f8075540│+0x0090: 0x000003c6000003c6
      0x000055d2f8075548│+0x0098: 0x000003c6000003c6
      0x000055d2f8075550│+0x00a0: 0x000003c6000003c6
      0x000055d2f8075558│+0x00a8: 0x0000031e0000031e
      0x000055d2f8075560│+0x00b0: 0x0000031e0000031e
      0x000055d2f8075568│+0x00b8: 0x0000031e0000031e
      0x000055d2f8075570│+0x00c0: 0x000000000000031e
      
  3. 內容都是二,和上面對比全部都會是兩倍
    • Result
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      0x0000563c09e664b0│+0x0000: 0x000007a8000007a8   ← $rdi
      0x0000563c09e664b8│+0x0008: 0x000007a8000007a8
      0x0000563c09e664c0│+0x0010: 0x000007a8000007a8
      0x0000563c09e664c8│+0x0018: 0x000005b0000007a8
      0x0000563c09e664d0│+0x0020: 0x000005b0000005b0
      0x0000563c09e664d8│+0x0028: 0x000005b0000005b0
      0x0000563c09e664e0│+0x0030: 0x000005b0000005b0
      0x0000563c09e664e8│+0x0038: 0x0000061e0000061e
      0x0000563c09e664f0│+0x0040: 0x0000061e0000061e
      0x0000563c09e664f8│+0x0048: 0x0000061e0000061e
      0x0000563c09e66500│+0x0050: 0x000006000000061e
      0x0000563c09e66508│+0x0058: 0x0000060000000600
      0x0000563c09e66510│+0x0060: 0x0000060000000600
      0x0000563c09e66518│+0x0068: 0x0000060000000600
      0x0000563c09e66520│+0x0070: 0x0000076000000760
      0x0000563c09e66528│+0x0078: 0x0000076000000760
      0x0000563c09e66530│+0x0080: 0x0000076000000760
      0x0000563c09e66538│+0x0088: 0x0000078c00000760
      0x0000563c09e66540│+0x0090: 0x0000078c0000078c
      0x0000563c09e66548│+0x0098: 0x0000078c0000078c
      0x0000563c09e66550│+0x00a0: 0x0000078c0000078c
      0x0000563c09e66558│+0x00a8: 0x0000063c0000063c
      0x0000563c09e66560│+0x00b0: 0x0000063c0000063c
      0x0000563c09e66568│+0x00b8: 0x0000063c0000063c
      0x0000563c09e66570│+0x00c0: 0x000000000000063c
      
  4. 只有第一個element是1,其他都是零,由結果可知只有七個一數的第一個element會有值,且該值是已經從儲存在原本的執行檔中,比對之後發現一模一樣
    • Result
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      0x0000563dd53444b0│+0x0000: 0x000000000000003c ("<"?)    ← $rdi
      0x0000563dd53444b8│+0x0008: 0x0000000000000000
      0x0000563dd53444c0│+0x0010: 0x0000000000000000
      0x0000563dd53444c8│+0x0018: 0x0000007300000000
      0x0000563dd53444d0│+0x0020: 0x0000000000000000
      0x0000563dd53444d8│+0x0028: 0x0000000000000000
      0x0000563dd53444e0│+0x0030: 0x0000000000000000
      0x0000563dd53444e8│+0x0038: 0x000000000000007a ("z"?)
      0x0000563dd53444f0│+0x0040: 0x0000000000000000
      0x0000563dd53444f8│+0x0048: 0x0000000000000000
      0x0000563dd5344500│+0x0050: 0x0000004100000000
      0x0000563dd5344508│+0x0058: 0x0000000000000000
      0x0000563dd5344510│+0x0060: 0x0000000000000000
      0x0000563dd5344518│+0x0068: 0x0000000000000000
      0x0000563dd5344520│+0x0070: 0x0000000000000067 ("g"?)
      0x0000563dd5344528│+0x0078: 0x0000000000000000
      0x0000563dd5344530│+0x0080: 0x0000000000000000
      0x0000563dd5344538│+0x0088: 0x0000007900000000
      0x0000563dd5344540│+0x0090: 0x0000000000000000
      0x0000563dd5344548│+0x0098: 0x0000000000000000
      0x0000563dd5344550│+0x00a0: 0x0000000000000000
      0x0000563dd5344558│+0x00a8: 0x00000000000000fa
      0x0000563dd5344560│+0x00b0: 0x0000000000000000
      0x0000563dd5344568│+0x00b8: 0x0000000000000000
      0x0000563dd5344570│+0x00c0: 0x0000000000000000
      

由以上實驗可以大致確認醜不拉基function做的事情就是矩陣乘法,而我們知道他比較的乘法結果,也知道和我們輸入的矩陣相乘的乘數,換言之可以反推回我們應該輸入的東西為何

Exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from pwn import *
from sage.all import *

r = process('./simple-crackme_f5e33c76600e')

flag_len = 49
verify_matrix = Matrix([[0x00010ee0, 0x00010814, 0x00014d06, 0x00015a7c, 0x00012de1, 0x00014a5a, 0x0000f883], 
                       [0x0000df33, 0x0000a7a5, 0x0000e66b, 0x0000e0c8, 0x0000b727, 0x0000eb70, 0x00008d9e], 
                       [0x0000fe08, 0x0000d725, 0x00010163, 0x000101a0, 0x0000c427, 0x00010365, 0x0000afca], 
                       [0x0000db6f, 0x0000dbdf, 0x00010dc3, 0x0000fb36, 0x0000d5c3, 0x00011ae8, 0x0000ddc2], 
                       [0x00011589, 0x0000fbc8, 0x00014000, 0x00011f7f, 0x0001019d, 0x0001567c, 0x0000f435], 
                       [0x00012c8d, 0x0000ff0b, 0x00012caf, 0x00014592, 0x000112ff, 0x00015e64, 0x00010322], 
                       [0x000109f9, 0x0000f002, 0x000115ee, 0x0000fe74, 0x0000d58e, 0x00011306, 0x0000c506]])

ct = Matrix([[0x3C, 0xAD, 0xB9, 0xF5, 0x84, 0x25, 0x94], 
            [0x73, 0xC8, 0x4E, 0x01, 0xAF, 0x04, 0x9B], 
            [0x7A, 0xC8, 0x33, 0x6D, 0x0A, 0x7F, 0xA4], 
            [0x41, 0x8E, 0x12, 0xE1, 0x94, 0x73, 0x37], 
            [0x67, 0x82, 0x60, 0x7F, 0xE9, 0x91, 0x6E], 
            [0x79, 0xBA, 0xEE, 0x09, 0xC1, 0xD0, 0x0B], 
            [0xFA, 0xAD, 0x46, 0x64, 0x10, 0x59, 0x64]])

# flag = [102, 103, 112, 53, 70, 100, 72, 88, 47, 55, 122, 50, 69, 49, 66, 67, 74, 120, 118, 80, 68, 53, 99, 114, 102, 101, 100, 105, 57, 49, 89, 52, 68, 107, 71, 97, 83, 79, 68, 48, 113, 85, 79, 48, 86, 53, 48, 61, 0]

flag = (verify_matrix.transpose() / ct.transpose()).transpose().coefficients()
print(flag)
r.sendline(str(flag_len).encode())
for i in range(len(flag)):
    r.sendline(str(flag[i]).encode())
r.sendline(b'0')
assert r.recvline().strip().decode() == "Correct!"
r.close()

print("Password = " + "".join([chr(i) for i in flag]))
1
2
3
4
5
$ python exp.py
[+] Starting local process './simple-crackme_f5e33c76600e': pid 12091
[102, 103, 112, 53, 70, 100, 72, 88, 47, 55, 122, 50, 69, 49, 66, 67, 74, 120, 118, 80, 68, 53, 99, 114, 102, 101, 100, 105, 57, 49, 89, 52, 68, 107, 71, 97, 83, 79, 68, 48, 113, 85, 79, 48, 86, 53, 48, 61]
[*] Stopped process './simple-crackme_f5e33c76600e' (pid 12091)
Password = fgp5FdHX/7z2E1BCJxvPD5crfedi91Y4DkGaSOD0qUO0V50=

最後只要把解出來的東西丟回去revguard就可以拿到真正的flag了 圖片.png

Flag: FLAG{yOu_kn0w_hOw_to_r3v3r53_4_m47riX!}