블로그 이전했습니다. https://jeongzero.oopy.io/
[reversing.kr] easy keygen
본문 바로가기
워게임/reversing.kr

[reversing.kr] easy keygen

728x90

1. 문제


1) 문제 확인

ReversingKr KeygenMe


Find the Name when the Serial is 5B134977135E7D13

readme를 보면 해당 시리얼 넘버일때의 이름을 찾으라고한다

바이너리를 실행시키고 이름을 아무거나 입력하고 시리얼 키를 입력하면 바로 종료가 되지만 사실 wrong이 출력된다.

3) 코드흐름 파악

int __cdecl main(int argc, const char **argv, const char **envp)
{
  signed int v3; // ebp
  signed int i; // esi
  char v6[3]; // [esp+Ch] [ebp-130h]
  char input; // [esp+10h] [ebp-12Ch]
  char v8; // [esp+11h] [ebp-12Bh]
  __int16 v9; // [esp+71h] [ebp-CBh]
  char v10; // [esp+73h] [ebp-C9h]
  char v11; // [esp+74h] [ebp-C8h]
  char v12; // [esp+75h] [ebp-C7h]
  __int16 v13; // [esp+139h] [ebp-3h]
  char v14; // [esp+13Bh] [ebp-1h]

  input = 0;
  v11 = 0;
  memset(&v8, 0, 0x60u);
  v9 = 0;
  v10 = 0;
  memset(&v12, 0, 0xC4u);
  v13 = 0;
  v14 = 0;
  v6[0] = 0x10;
  v6[1] = 0x20;
  v6[2] = 0x30;
  printf_((int)aInputName);
  scanf(aS, &input);
  v3 = 0;
  for ( i = 0; v3 < (signed int)strlen(&input); ++i )
  {
    if ( i >= 3 )
      i = 0;
    sprintf(&v11, aS02x, &v11, *(&input + v3++) ^ v6[i]);
		//sprintf(&v11, &(%s%02X), &v11, *(&input + v3++) ^ v6[i])
  }
  memset(&input, 0, 0x64u);
  printf_((int)aInputSerial);
  scanf(aS, &input);
  if ( !strcmp(&input, &v11) )
    sub_4011B9((int)aCorrect);
  else
    sub_4011B9((int)aWrong);
  return 0;
}

처음 이름을 입력하면 input에 저장이 되고 이를 v6[i]와 xor 연산하여 v11에 저장한다. 그리고 시리얼 키를 입력하여 연산되 v11과 비교를 한다. 역연산을 이용하여 input값을 알아내면 될것이다

2. 접근방법


이번엔 windbg로 풀었다. 리눅스에서만 해서 그런지 이게 훨편하다..

분석은 1차로 아이다에서 했고 동적으로 windbg에서 확인을 했다. strcmp 부분을 위주로 분석을 했다. 이는 실제 libc를 호출하는게 아니라 어셈으로 구현되어있다

eax에는 입력한 시리얼키, esi에는 입력한 input의 연산된 결과가 저장된다. 왼쪽을 보면 각 레지스터에 담긴 아스키 값을 볼수 있는데,

0019fe08  "5B134977135E7D13"
0:000> db eax
0019fe08  35 42 31 33 34 39 37 37-31 33 35 45 37 44 31 33  5B134977135E7D13
0019fe18  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0019fe28  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0019fe38  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0019fe48  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0019fe58  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0019fe68  00 00 00 00 37 31 34 31-35 31 37 31 00 00 00 00  ....71415171....
0019fe78  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

현재 35 42 ('5b') 이다. 어셈을 보면 한번의 비교 루틴에 [eax],[esi] [eax+1],[esi+1] 각 한바이트씩 비교하므로 시리얼 키는 2바이트씩 끊어서 비교하면 된다. 즉

5B 13 49 77 13 5E 7D 13

이렇게 계산하면 된다.

역연산은 시리얼 키 문자열 ^ [0x10,0x20,0x30] 을 돌아가면서 조지면 된다

3. 풀이



sss=[0x5B,0x13,0x49,0x77,0x13,0x5E,0x7D,0x13]
key=[0x10,0x20,0x30]
original=''

index=0
for c in sss:
        if index>=3:
                index=0
        print(hex(c^key[index]))
        original+=chr(c^key[index])
        index=index+1
        #print(hex(ord(c)^key))

print(original)

-------------------------
-> K3yg3nm3

4. 몰랐던 개념


728x90

'워게임 > reversing.kr' 카테고리의 다른 글

[reversing.kr] ImagePrc  (0) 2020.12.15
[reversing.kr] Replace  (0) 2020.12.14
[reversing.kr] Music Player.exe  (0) 2020.12.11
[reversing.kr] easy elf  (0) 2020.12.10
[reversing.kr] easy crack  (0) 2020.12.07