[Dreamhack] rev-basic-9

김성진·2022년 8월 10일
0

Dreamhack_Reversing

목록 보기
10/13

📒 Description


📒 C code

📖 main

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[256]; // [rsp+20h] [rbp-118h] BYREF

  memset(v4, 0, sizeof(v4));
  sub_1400012E0("Input : ", argv, envp);
  sub_140001340("%256s", v4);
  if ( (unsigned int)sub_140001000(v4) )
    puts("Correct");
  else
    puts("Wrong");
  return 0;
}

📖 sub_140001000

_BOOL8 __fastcall sub_140001000(const char *a1)
{
  int i; // [rsp+20h] [rbp-18h]
  int v3; // [rsp+24h] [rbp-14h]

  v3 = strlen(a1);
  if ( (v3 + 1) % 8 )
    return 0i64;
  for ( i = 0; i < v3 + 1; i += 8 )
    sub_1400010A0(&a1[i]);
  return memcmp(a1, &unk_140004000, 0x19ui64) == 0;
}

음... 먼저 a1의 길이를 v3에 받는다. v3+1은 8로 나누어지면 안된다.
이걸 통과하면 10A0 함수에 a1의 8배수 원소들만 인자로 넘겨준다.
memcmp도 하므로 10A0 함수 내에서 a1 배열의 값들을 바꾼 다는 것을 예측해볼 수 있다.

📖 sub_1400010A0

__int64 __fastcall sub_1400010A0(unsigned __int8 *a1)
{
  __int64 result; // rax
  unsigned __int8 v2; // [rsp+0h] [rbp-48h]
  int j; // [rsp+4h] [rbp-44h]
  int i; // [rsp+8h] [rbp-40h]
  char v5[16]; // [rsp+10h] [rbp-38h] BYREF

  strcpy(v5, "I_am_KEY");
  result = *a1;
  v2 = *a1;
  for ( i = 0; i < 16; ++i )
  {
    for ( j = 0; j < 8; ++j )
    {
      v2 = __ROR1__(a1[((_BYTE)j + 1) & 7] + byte_140004020[(unsigned __int8)v5[j] ^ v2], 5);
      a1[((_BYTE)j + 1) & 7] = v2;
    }
    result = (unsigned int)(i + 1);
  }
  return result;
}

이 함수에 들어온 값들에 대해 v2값을 설정한다.

a1[((_BYTE)j + 1) & 7] = __ROR1__(a1[((_BYTE)j + 1) & 7] + byte_140004020[(unsigned __int8)v5[j] ^ v2], 5);

결론적으로 위의 코드를 실행한다. 이 때 좌항의 값은 unk_140004000의 값이어야 한다.
이 배열을 answer이라 해보자. byte_140004020 배열은 dummy라 하자.


📒 Exploit

📖 식 정리

answer[i]==ROR(a1[i+((j+1)&7)] + dummy[key[j]v2],5)a1[i+((j+1)&7)] + dummy[key[j]v2]==ROL(answer[i],5)a1[i+((j+1)&7)]==ROL(answer[i],5)dummy[key[j]v2]answer[i] == ROR(a1[i + ((j+1)\&7)]\ +\ dummy[key[j]\oplus v2], 5) \\ a1[i + ((j+1)\&7)]\ +\ dummy[key[j]\oplus v2] == ROL(answer[i], 5)\\ a1[i + ((j+1)\&7)] == ROL(answer[i], 5) - dummy[key[j]\oplus v2]

📖 exploit.py

저 i값을 건드리는 게 조금 불편해서, 그냥 8바이트 단위로 함수를 끊었다.

v5 = "I_am_KEY".encode()

byte_140004020 = [
   99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 
  103,  43, 254, 215, 171, 118, 202, 130, 201, 125, 
  250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 
  114, 192, 183, 253, 147,  38,  54,  63, 247, 204, 
   52, 165, 229, 241, 113, 216,  49,  21,   4, 199, 
   35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 
  235,  39, 178, 117,   9, 131,  44,  26,  27, 110, 
   90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
   83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 
  190,  57,  74,  76,  88, 207, 208, 239, 170, 251, 
   67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 
  159, 168,  81, 163,  64, 143, 146, 157,  56, 245, 
  188, 182, 218,  33,  16, 255, 243, 210, 205,  12, 
   19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 
  100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 
  144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
  224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 
  172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 
  141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 
  174,   8, 186, 120,  37,  46,  28, 166, 180, 198, 
  232, 221, 116,  31,  75, 189, 139, 138, 112,  62, 
  181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 
  134, 193,  29, 158, 225, 248, 152,  17, 105, 217, 
  142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
  140, 161, 137,  13, 191, 230,  66, 104,  65, 153, 
   45,  15, 176,  84, 187,  22
]

unk_140004000 = [
    0x7E, 0x7D, 0x9A, 0x8B, 0x25, 0x2D, 0xD5, 0x3D, 0x03, 0x2B, 
    0x38, 0x98, 0x27, 0x9F, 0x4F, 0xBC, 0x2A, 0x79, 0x00, 0x7D, 
    0xC4, 0x2A, 0x4F, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00
]



def ROL(x, n):
	shiftBit = x << n
	shiftBit &= 255
	carryBit = x >> 8 - n
	result= shiftBit | carryBit
	return result

a = unk_140004000[0:8]
for i in range(15, -1, -1):
        for j in range(7, -1, -1):
            v2 = a[(j + 1) & 7] & 0xFF
            a[(j + 1) & 7] = (ROL(v2, 5) - byte_140004020[v5[j] ^ a[j & 7]])  & 0xFF
for i in a:
    print(chr(i), end='')


a = unk_140004000[8:16]
for i in range(15, -1, -1):
        for j in range(7, -1, -1):
            v2 = a[(j + 1) & 7]  & 0xFF
            a[(j + 1) & 7] = (ROL(v2, 5) - byte_140004020[v5[j] ^ a[j & 7]])  & 0xFF
for i in a:
    print(chr(i), end='')

a = unk_140004000[16:24]
for i in range(15, -1, -1):
        for j in range(7, -1, -1):
            v2 = a[(j + 1) & 7]  & 0xFF
            a[(j + 1) & 7] = (ROL(v2, 5) - byte_140004020[v5[j] ^ a[j & 7]])  & 0xFF
for i in a:
    print(chr(i), end='')

print()
profile
Today I Learned

0개의 댓글