본문 바로가기
Wargame Write-Up/Reversing.kr

[Reversing.kr] (Reversing) HateIntel 풀이

by snwo 2021. 2. 1.

mach-o 파일이다. 맥북이 없어서 실행시키지는 못하겠고, ghidra 로 정적분석을 해야겠다. ㅜㅜ

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
undefined4 FUN_00002224(void)
 
{
  char acStack100 [80];
  undefined4 local_14;
  size_t local_10;
  int local_c;
  
  local_14 = 4;
  __symbol_stub4::_printf("Input key : ");
  __symbol_stub4::_scanf("%s",acStack100);
  local_10 = __symbol_stub4::_strlen(acStack100);
  FUN_0000232c(acStack100,local_14);
  local_c = 0;
  whiletrue ) {
    if ((int)local_10 <= local_c) {
      __symbol_stub4::_puts("Correct Key! ");
      return 0;
    }
    if (acStack100[local_c] != (&DAT_00003004)[local_c]) break;
    local_c = local_c + 1;
  }
  __symbol_stub4::_puts("Wrong Key! ");
  return 0;
}
cs

입력을받고, fun_0000232c 를 실행시켜서 복호화된 값들을 DAT_00003004 의 값들과 차례대로 비교하는 것같다.

 

fun_0000232c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void FUN_0000232c(char *param_1,int param_2)
 
{
  char cVar1;
  size_t sVar2;
  int local_14;
  int local_10;
  
  local_14 = 0;
  while (local_14 < param_2) {
    local_10 = 0;
    while (sVar2 = __symbol_stub4::_strlen(param_1), local_10 < (int)sVar2) {
      cVar1 = FUN_00002494(param_1[local_10],1);
      param_1[local_10] = cVar1;
      local_10 = local_10 + 1;
    }
    local_14 = local_14 + 1;
  }
  return;
}
 
cs

이중 반복문인데, param_2 에는 4 가 들어가니까 param_1 의 길이 *4 만큼 반복한다.

fun_00002494(param[i],1) 을 반복적으로 호출해 결과를 param_1 에 넣는다.

 

fun_00002494

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uint FUN_00002494(byte param_1,int param_2)
 
{
  uint local_10;
  int local_c;
  
  local_10 = (uint)param_1;
  local_c = 0;
  while (local_c < param_2) {
    local_10 = local_10 << 1;
    if ((local_10 & 0x100) != 0) {
      local_10 = local_10 | 1;
    }
    local_c = local_c + 1;
  }
  return local_10 & 0xff;
}
 
cs

param_2 가 1이니 반복문은 한 번만 실행이 되고, 

왼쪽으로 한 번 쉬프트 해준 뒤, 3번째 비트가 1이면 1 과 or 연산을 해준다. 그리고 0xff 과 and 연산을 한 뒤 리턴한다.

 

DAT_00003004 에 있는 각각의 값들은 이 함수를 4번 돌린 결과이다. 

0xff 과 and 연산을 하면, 왼쪽으로 4번 쉬프트 해주면 상위 4바이트는 없어져서

복호화할 수 없기 때문에, 브루트포스를 이용해

복호화시켰을 때 DAT_00003004 의 값들과 같은 값을 찾아야한다.

 

기드라는 값을 쉽게 가져올 수 있어 좋다.

solve

 

1
2
3
4
5
6
7
8
9
10
11
12
a="44 f6 f5 57 f5 c6 96 b6 56 f5 14 25 d4 f5 96 e6 37 47 27 57 36 47 96 03 e6 f3 a3 92".split()
d=[int(x,16for x in a]
for i in d:
    for j in range(0xff):
        tmp=j
        for k in range(4):
            tmp=tmp<<1
            if tmp&0x100!=0:
                tmp=tmp|1
            tmp=tmp&0xff
        if tmp==i:
            print(chr(j),end='')
cs