문제 정보

    플래그를 찾을 수 있겠나요?

    문제 파일


    분석

    sub_7FF7D3221C30

    char __fastcall sub_7FF7D3221C30(void **a1)
    {
    ...
      v24[0] = '{HD';
      if ( a1[2] != (void *)24 )
      {
    ...
      }
    ...
      do
      {
        v7 = a1;
        if ( v5 >= 0x10 )
          v7 = (void **)*a1;
        if ( *((_BYTE *)v7 + v6) != *((_BYTE *)v24 + v6) )// CHECKPOINT: DH{
          goto LABEL_34;
        ++v4;
        ++v6;
      }
    ...
      if ( *((_BYTE *)v8 + 23) != '}' )
      {
        ...
      }
    ...
      sub_7FF7D3221A10(v18, &v20, v12);
      v13 = &dword_7FF7D3228050; // [0x40007608, 0x800075f6...
      v14 = v18[0];
      do
      {
        if ( *(_QWORD *)((char *)v13 + v18[0] - (void *)&dword_7FF7D3228050) != *(_QWORD *)v13 )// CHECKPOINT
        {
          if ( v18[0] )
          {
            if ( (unsigned __int64)(4 * ((signed __int64)(v19 - (unsigned __int64)v18[0]) >> 2)) >= 0x1000 )
            {
              v14 = (void *)*((_QWORD *)v18[0] - 1);
              if ( (unsigned __int64)(v18[0] - v14 - 8) > 0x1F )
                goto LABEL_32;
            }
            operator delete(v14);
            *(_OWORD *)v18 = 0i64;
            v19 = 0i64;
          }
    LABEL_34:
          v2 = (unsigned __int64)a1[3];
          v10 = v2 < 0x10;
    LABEL_35:
          if ( !v10 )
          {
            v3 = *a1;
            goto LABEL_37;
          }
    LABEL_41:
          result = 0;
          goto LABEL_42;
        }
        v13 += 2;
      }
    ...
    }
    1. FLAG 길이가 총 24바이트인지 확인한다.
    2. FLAG가 DH{으로 시작하는지 확인한다.
    3. FLAG가 }으로 마치는지 확인한다.
    4. 입력받은 FLAG인 v20를 sub_7FF7D3221A10에서 수행시킨 v18을 가져오고 dword_7FF7D3228050에 있는 배열들을 하나씩 비교한다.
      비교를 총 12번 하는데 서로 비교하는 값들은 8바이트(QWORD) 단위이다.

    sub_7FF7D3221A10

    _QWORD *__fastcall sub_7FF7D3221A10(_QWORD *a1, _QWORD *a2, __int64 a3)
    {
    ...
      v5 = a2[2];// v5=24 (strlen)
      ...
      strcpy(v16, "neko_hat");
      v10 = 0;
      if ( a2[2] )// 24
      {
        v11 = 0i64;
        do
        {
          v12 = a2;
          if ( a2[3] >= 16ui64 )
            v12 = (_QWORD *)*a2;
          *(_DWORD *)(*a1 + 4 * v11) = *((char *)v12 + v11);
          *(_DWORD *)(*a1 + 4 * v11) = __ROR4__(*(_DWORD *)(*a1 + 4 * v11), 4);
          *(_DWORD *)(*a1 + 4 * v11) ^= v16[v10 % 8];
          *(_DWORD *)(*a1 + 4 * v11) += v16[v10 % 4];
          *(_DWORD *)(*a1 + 4 * v11) += 30000;
          ++v10;
          ++v11;
        }
        while ( (unsigned __int64)v10 < a2[2] );    // v10 < 24 (strlen)
      }
    ...
      return a1;
    }

    FLAG가 “DH{….”으로 가정했을때, 한글자씩 아래와 같은 연산을 해서 4바이트씩 값을 지정한다.
    파이썬3로 구현하면 다음과 같다.

    def ROR(data, shift, size=32):
        shift %= size
        body = data >> shift
        remains = (data << (size - shift)) - (body << size)
        return (body + remains)
    
    FLAG = "DH{..." #(24bytes)
    
    for i in range(24):
        oneChar = FLAG[i]
        oneChar = ROR(oneChar, 4)
        oneChar = oneChar ^ ord(neko[i % 8])
        oneChar = oneChar + ord(neko[i % 4])
        oneChar += 30000
        print(oneChar)

    풀이

    def ROR(data, shift, size=32):
        shift %= size
        body = data >> shift
        remains = (data << (size - shift)) - (body << size)
        return (body + remains)
    
    cmp_list = [0x40007608, 0x800075F6, 0xB0007607, 0x90007607,\
                0x000075FA, 0x50007604, 0xF00075FF, 0x40007616,\
                0x20007607, 0x300075FB, 0xF0007609, 0x30007608,\
                0xD00075F7, 0x00007604, 0xF00075FF, 0xF0007610,\
                0xD0007606, 0x100075F8, 0x50007603, 0x40007607,\
                0x300075FA, 0x20007604, 0x100075FE, 0xD0007612]
    
    neko = "neko_hat"
    FLAG = ""
    
    for i in range(24):
        for j in range(255):
            oneChar = j
            oneChar = ROR(oneChar, 4)
            oneChar = oneChar ^ ord(neko[i % 8])
            oneChar = oneChar + ord(neko[i % 4])
            oneChar += 30000
    
            if(oneChar == cmp_list[i]):
                print(chr(j), end='')

    역연산시키기 귀찮아서 0~255범위의 한글자를 브루트포싱해서 맞추는 식으로 풀었다.

    PS C:\Users\Seo Hyun-gyu\Desktop\babycmp> python3 .\solve.py
    DH{y0u_4r3_cmp__ma5t3r!}

    FLAG

    DH{y0u_4r3_cmp__ma5t3r!}

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다