GKCTF X DASCTF emergency Challenge Cup - Maple_root-Writeup

Posted by jehardesty on Tue, 25 Jan 2022 19:40:22 +0100

Some title WP contains pictures, because CSDN can't get external pictures, so it can't join. If you want to watch the full version, welcome Click here to access
Another: CSDN inserting the outer chain picture failed again and again. It's really disgusting. We're already considering transferring stations

Participants:

b4tteRy, x0r, f1oat

Final score: 2285

Final ranking: 27

summary

After several off-line drills in recent years, I feel that I am a little good at CTF. This time, I finally don't explode 0. Continue my efforts

MISC

Sign in

When wireshark is opened, it can be seen that it is shell traffic, and the command result is encoded as hex+base64. By observing the output of the previous whoami/ls commands, we can see that the output of each line is in reverse order.
Therefore, the result of cat /f14g|base64 is spliced and decoded in reverse order to obtain the editing record of the flag, and the double write is removed to obtain the flag.

Do you know apng

After converting apng to gif, it is found that there are QR codes in some key frames.
The scanning results are spliced in sequence to obtain the flag.

Ginkgo Island wonderful adventure

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly

FireFox Forensics

After downloading and decompressing, there is a json file and a db database file stored in sql. Check that the db database content is encrypted. According to the topic prompt, the content of this topic belongs to the login information, which should be the login information stored in the FireFox browser, which has been related on Github Decryption script , after downloading directly, put the two files given in the title into the same directory and use Python 3 firepwd Py to successfully decrypt the flag

excel operation

Open and see a line of words. According to the prompt, flag is hidden in the table.
View the cells / decompress the data in turn. You can find that the value of some cells is 1, and you can find that the format is;;;, The number is displayed normally after changing the format.
Set the conditional format so that all cells with a value of 1 are filled with black, and stretch all cells within the number range to squares to obtain the Chinese letter code drawn by the black cells.
Use the Chinese coded app to scan the flag.

Reverse

QQQQT

After downloading, PEID scanning is a WIN32 program. Dragging it into IDA32 for analysis, it can be seen that the program is obviously written in Qt language, and the title also confirms this. At first, it failed to find the logical search in the WinMain window of IDA for many times, and then it tried to conduct dynamic debugging in OD, and found the text address of the keyword related to flag in the analyzed string
Then find the location of these strings in IDA according to the above address, and you can get the following function

int __thiscall sub_4012F0(_DWORD *this)
{
  int v1; // edi
  _BYTE *v2; // esi
  const char *v3; // edx
  _BYTE *v4; // esi
  int v5; // ecx
  int v6; // eax
  int v7; // ecx
  int v8; // edx
  int v9; // edi
  int v10; // esi
  _BYTE *v11; // ecx
  unsigned int v12; // ecx
  int v14; // [esp-8h] [ebp-A8h]
  char v16[4]; // [esp+10h] [ebp-90h] BYREF
  char v17[4]; // [esp+14h] [ebp-8Ch] BYREF
  _BYTE *v18; // [esp+18h] [ebp-88h]
  const char *v19; // [esp+1Ch] [ebp-84h]
  int v20; // [esp+20h] [ebp-80h]
  int v21; // [esp+24h] [ebp-7Ch] BYREF
  _BYTE *v22; // [esp+28h] [ebp-78h] BYREF
  char v23[60]; // [esp+2Ch] [ebp-74h] BYREF
  __int128 v24[2]; // [esp+68h] [ebp-38h] BYREF
  __int64 v25; // [esp+88h] [ebp-18h]
  int v26; // [esp+9Ch] [ebp-4h]

  MEMORY[0x5FF6](*(_DWORD *)(this[6] + 4), v16);
  v26 = 0;
  MEMORY[0x7C7C](v16, v17);
  LOBYTE(v26) = 1;
  v19 = (const char *)MEMORY[0x7C48](v17);
  v24[0] = 0i64;
  v24[1] = 0i64;
  v25 = 0i64;
  strcpy(v23, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
  v21 = 138 * strlen(v19) / 0x64;
  v14 = v21 + 1;
  v1 = 0;
  v22 = (_BYTE *)MEMORY[0x8114](v21 + 1);
  v2 = v22;
  sub_402C08(v22, 0, v14);
  v3 = v19;
  v20 = (int)(v19 + 1);
  if ( strlen(v19) )
  {
    v4 = &v2[v21];
    v18 = v4;
    while ( 1 )
    {
      v20 = ((char)*v4 << 8) + v3[v1];
      v5 = v20 / 58;
      *v4 = v20 % 58;
      if ( v5 )
      {
        do
        {
          v6 = (char)*--v4;
          v7 = (v6 << 8) + v5;
          v20 = v7 / 58;
          *v4 = v7 % 58;
          v5 = v20;
        }
        while ( v20 );
        v4 = v18;
      }
      if ( ++v1 >= strlen(v19) )
        break;
      v3 = v19;
    }
    v2 = v22;
  }
  v8 = 0;
  if ( !*v2 )
  {
    do
      ++v8;
    while ( !v2[v8] );
  }
  v9 = v21;
  if ( v8 <= v21 )
  {
    v10 = v2 - (_BYTE *)v24;
    do
    {
      v11 = (char *)v24 + v8++;
      *v11 = v23[(char)v11[v10]];
    }
    while ( v8 <= v9 );
  }
  if ( !MEMORY[0x7C1A](v24, "56fkoP8KhwCf3v7CEz") )
  {
    if ( v19 )
      v12 = strlen(v19);
    else
      v12 = -1;
    v22 = (_BYTE *)MEMORY[0x7CCC](v19, v12);
    LOBYTE(v26) = 2;
    v21 = MEMORY[0x7CCC]("flag", 4);
    LOBYTE(v26) = 3;
    MEMORY[0x6124](this, &v21, &v22, 1024, 0);
    MEMORY[0x7C66](&v21);
    MEMORY[0x7C66](&v22);
  }
  MEMORY[0x7C30](v17);
  return MEMORY[0x7C66]();
}

The above string 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz is inferred as Base58 encoding, and the string 56fkoP8KhwCf3v7CEz is decoded with Base58 and then attempted to submit as flag

Crash

Open and find that this program is written in Golang, so use ida7 6 open to correspond to most character sets, and open main_main look at the 18th behavior

 if ( v1[1] == 43LL && *(_DWORD *)v0 == 1413696327 && *(_WORD *)(v0 + 4) == 31558 && *(_BYTE *)(v0 + 42) == 125 )

Among them, each equivalent determines tckg (string stored in reverse order in memory address), {F,}, so it is inferred that the determination of flag should be carried out here, and then enter main_check function

void __golang main_check(__int64 a1, unsigned __int64 a2)
{
  __int64 v2; // [rsp+10h] [rbp-68h]
  __int64 v3; // [rsp+10h] [rbp-68h]
  __int64 v4; // [rsp+10h] [rbp-68h]
  __int64 v5; // [rsp+18h] [rbp-60h]
  __int64 v6; // [rsp+18h] [rbp-60h]
  __int64 v7; // [rsp+18h] [rbp-60h]
  __int64 v8; // [rsp+18h] [rbp-60h]
  __int64 v9; // [rsp+18h] [rbp-60h]
  __int64 v10; // [rsp+18h] [rbp-60h]
  __int64 v11; // [rsp+20h] [rbp-58h]
  __int64 v12; // [rsp+20h] [rbp-58h]
  __int64 v13; // [rsp+20h] [rbp-58h]
  __int64 v14; // [rsp+20h] [rbp-58h]
  __int64 v15; // [rsp+20h] [rbp-58h]
  __int64 v16; // [rsp+20h] [rbp-58h]
  __int64 v17; // [rsp+28h] [rbp-50h]
  __int64 v18; // [rsp+28h] [rbp-50h]
  char v19[32]; // [rsp+30h] [rbp-48h] BYREF
  char v20[32]; // [rsp+50h] [rbp-28h] BYREF

  if ( a2 < 0x1E )
    runtime_panicSliceAlen();
  v2 = main_encrypto(a1 + 6, 24LL);
  if ( v5 == 44 )
  {
    v11 = runtime_memequal(v2, (__int64)"o/aWPjNNxMPZDnJlNp0zK5+NLPC4Tv6kqdJqjkL0XkA=", 44LL, 44);
    if ( (_BYTE)v5 )
    {
      if ( a2 < 0x22 )
        runtime_panicSliceAlen();
      v17 = runtime_stringtoslicebyte((__int64)v19, a1 + 30, 4LL, v5, v11);
      Encrypt_HashHex2(v6, v12, v17, v6, v12);
      if ( v13 == 64 )
      {
        v14 = runtime_memequal(
                v7,
                (__int64)"6e2b55c78937d63490b4b26ab3ac3cb54df4c5ca7d60012c13d2d1234a732b74",
                64LL,
                v7);
        if ( (_BYTE)v7 )
        {
          if ( a2 < 0x26 )
            runtime_panicSliceAlen();
          v18 = runtime_stringtoslicebyte((__int64)v20, a1 + 34, 4LL, v7, v14);
          Encrypt_HashHex5(v8, v15, v18, v8, v15);
          if ( v16 == 128 )
          {
            runtime_memequal(
              v9,
              (__int64)"6500fe72abcab63d87f213d2218b0ee086a1828188439ca485a1a40968fd272865d5ca4d5ef5a651270a52ff952d955c9"
                       "b757caae1ecce804582ae78f87fa3c9",
              128LL,
              v9);
            if ( (_BYTE)v9 )
            {
              if ( a2 < 0x2A )
                runtime_panicSliceAlen();
              main_hash(a1 + 38, 4LL, v3, v9);
              if ( v10 == 32 )
                runtime_memequal(v4, (__int64)"ff6e2fd78aca4736037258f0ede4ecf0", 32LL, 32);
            }
          }
        }
      }
    }
  }
}

It can be seen that it is divided into several segments. The first segment has six characters and uses DES encryption (direct blasting). The second segment uses sha256 encryption, the third segment uses sha512 encryption, and the last segment uses md5 encryption. The length of the plaintext before encryption can be inferred from the length of the submitted content intercepted in the front, Therefore, except for the first des blasting and decryption of existing relevant websites, all the others can write the same script blasting
The first segment of DES encryption can be from encoding_ json_ key and iv found in unmarshal

    "key": "WelcomeToTheGKCTF2021XXX",
    "iv": "1Ssecret"

Next, it is found that the key here has a total of 24byte s, so it is speculated to be 3des. Therefore, the first flag can be obtained by corresponding blasting. The problem-solving scripts in the following paragraphs are as follows:
Sha256 - > 4 bits

import hashlib
import string
import itertools

dateset = string.ascii_lowercase + string.digits

res = "6e2b55c78937d63490b4b26ab3ac3cb54df4c5ca7d60012c13d2d1234a732b74"

def generate_strings(length=4):
    chars = string.ascii_lowercase + string.digits
    for item in itertools.product(chars, repeat=length):
        tmp = "".join(item)
        aa = hashlib.sha256(tmp.encode('utf-8')).hexdigest()

        if aa.hexdigest() == res:
            print(tmp)
            exit(0)



generate_strings()

SHA512 - > 4 bits

import hashlib
import string
import itertools

dateset = string.ascii_lowercase + string.digits

res = "6500fe72abcab63d87f213d2218b0ee086a1828188439ca485a1a40968fd272865d5ca4d5ef5a651270a52ff952d955c9b757caae1ecce804582ae78f87fa3c9"

def generate_strings(length=4):
    chars = string.ascii_lowercase + string.digits
    for item in itertools.product(chars, repeat=length):
        tmp = "".join(item)
        aa = hashlib.sha512(tmp.encode('utf-8')).hexdigest()

        if aa.hexdigest() == res:
            print(tmp)
            exit(0)



generate_strings()

MD5 - > 4 bits

import hashlib
import string
import itertools

dateset = string.ascii_lowercase + string.digits

flag = "ff6e2fd78aca4736037258f0ede4ecf0"

def generate_strings(length=4):
    chars = string.ascii_lowercase + string.digits
    for item in itertools.product(chars, repeat=length):
        md5 = hashlib.md5()

        tmp = "".join(item)
        md5.update(tmp.encode('utf-8'))

        if md5.hexdigest() == flag:
            print(tmp)
            exit(0)

The above burst values are connected together in order, which is called flag

Web

easycms

The title prompts five weak passwords. Log in successfully after trying admin/12345.
Try to change the code of the template related to the topic, and prompt that you need to create / system / TMP / XXXX Txt (seemingly dynamic four letters).
When uploading a file in the material library, it can be observed that the path is directly spliced by the file name, so the file created according to the above requirements can be created by directory crossing. Insert a shell into the template and read the flag.

Topics: CTF writeup