2017 Second Guangdong strong network Cup online game --Nonstandard

Test file: http://static2.ichunqiu.com/icq/resources/fileupload/CTF/echunqiu/qwb/Nonstandard_26195e1832795caa18fd4c7cfbd56600.zip

 

1. Prepare

get information:

  • 32 files

 

2.IDA Open

int __cdecl main(int argc, const char **argv, const char **envp)
{
  FILE *v3; // eax
  FILE *v4; // eax
  FILE *v5; // eax
  char Buf[16]; // [esp+0h] [ebp-24h]
  __int64 v8; // [esp+10h] [ebp-14h]
  int v9; // [esp+18h] [ebp-Ch]
  __int16 v10; // [esp+1Ch] [ebp-8h]

  v9 = 0;
  _mm_storeu_si128((__m128i *)Buf, (__m128i)0i64);
  v10 = 0;
  v8 = 0i64;
  v3 = _iob_func();
  fputs("Place Input Flag:\n", v3 + 1);
  v4 = _iob_func();
  fgets(Buf, 29, v4);
  if ( sub_401480(Buf) == 1 )
  {
    v5 = _iob_func();
    fputs("yes\n", v5 + 1);
  }
  return 0;
}

 

3. Code Analysis

Open sub_401480 (Buf) function

 1 signed int __thiscall sub_401480(const char *this)
 2 {
 3   const char *v1; // esi
 4   const char *v2; // eax
 5   unsigned int v3; // eax
 6   unsigned int v4; // kr04_4
 7   signed int result; // eax
 8   char v6; // [esp+4h] [ebp-38h]
 9   charDST; // [ESP + 5H] [EBP-37h] 
10  
. 11    V6 = 0 ;
 12 is    V1 = the this ;                                     // the this address for the input character string, a length of 28, do not contain the ending character 
13 is    Memset (& Dst , 0 , 0x31u );                        // Dst is the size of the space 49 
14    IF (strlen (V1) =! 28 )                        // input a string of 28 
15      GOTO LABEL_10;
 16    V2 sub_401070 = (( int ) V1, 28U ) ;
 . 17    strncpy_s (& V6,0x32u , v2, 0x30u );
18    v3 = 0 ;
19    v4 = strlen (& v6);
20    if (! V4)
 21      goto LABEL_10;
22    do 
23    {
 24      if (byte_402120 [v3]! = * (& V6 + v3))
 25        break ;
26      ++ v3;
27    }
 28    while (v3 < v4);
29    if (v3 == 48 )
 30      result = 1 ;
31   else
32 LABEL_10:
33     result = -1;
34   return result;
35 }

First of all, I note that the first 24 lines of code comparison, byte_402120 [] = "AdtxA66nbbdxA71tUAE2AOlnnbtrAp1nQzGtAQGtrjC7 ===", which is encrypted string section, and from a comparison of the array v6 v2, v2 is a function sub_401070 ((int) v1, 28u) return value is passed v1 our input string.

Open sub_401070 ((int) v1, 28u)

sub_401070((int)v1, 28u)

 

This encryption method is base32

Quoted from: https://www.ichunqiu.com/writeup/detail/815

 base64 encoding is 64 (6th power of 2) ASCII characters to represent 256 (2 ^ 8) of ASCII characters, i.e. three encoded binary array after the display becomes four ASCII characters in length than the original increased by a third.
 Similarly, base32 is to use 32 (fifth power of 2) two specific ASCII code 256 to indicate the ASCII code. So, five ASCII characters after base32 encoded becomes 8 characters (divisor 40), increase the length of 3/5. 8n insufficient use "=" to make up.
 base16 256 ASCII characters is represented by 16 (2 to the power 4) -th specific ASCII code. After a base16 encoded ASCII characters will become two characters in length doubled. Less than 2n with "=" complement

 

At the same time we are concerned that the first 41 lines of code, sub_401000 (); function

signed __int16 sub_401000()
{
  signed int v0; // eax
  int v1; // esi
  char *v2; // edx
  char v3; // cl
  signed __int16 result; // ax

  v0 = 1;
  do
  {
    byte_403020[v0] += 32;
    v0 += 2;
  }
  while ( v0 < 26 );
  v1 = 0;
  v2 = &aMnopqrstuvwxyz[13];
  do
  {
    v3 = byte_40301F[++v1];
    byte_40301F[v1] = *v2;
    *v2-- = v3;
  }
  while ( (signed int)v2 > (signed int)aMnopqrstuvwxyz );
  *(_DWORD *)&aMnopqrstuvwxyz[14] = '3567';
  result = '12';
  word_40303E = '12';
  byte_403040 = 0;
  return result;
}

This function will regenerate encryption table, available in OD dynamic debugging

 

Therefore, the overall operation is, will we enter the string, using the encryption table, base32 encryption newly generated, get AdtxA66nbbdxA71tUAE2AOlnnbtrAp1nQzGtAQGtrjC7 === encrypted string

 

4. The script gets

Use anybase32 package to decrypt: https://github.com/alanblevins/anybase32

from __future__ import print_function
import anybase32

arbitrary_alphabet = b"zYxWvUtSrQpOnMlKjIhGfEdCbA765321"

encoded = b"nAdtxA66nbbdxA71tUAE2AOlnnbtrAp1nQzGtAQGtrjC7"

flag = anybase32.decode(encoded, arbitrary_alphabet)

print(flag)

 

5.get flag!

flag{f1ag_1s_enc0de_bA3e32!}

Guess you like

Origin www.cnblogs.com/Mayfly-nymph/p/11815118.html