1nzag

[reversing.kr] ransomware writeup

wargame/reversing.kr

문제를 받아보면 upx 패킹이 되어있다는 것을 알 수 있다. 


패킹을 푼 후 코드를 분석해보면 hexray를 막기 위해 의미없는 코드들을 중간에 끼워 함수의 길이를 크게 늘려놓은것을 확인할 수 있다. 

보는 바와 같이 레지스터 값을 push 하고 다시 pop 하는 과정만 반복한다.

실제 의미있는 코드부분에 함수의 프롤로그가 될 수 있도록 패치를 한뒤, 함수지정을 해서 hexray를 가능하게 했다.


int sub_44A765()

{

  char file_char; // al

  int v2; // [esp+Ch] [ebp-24h]

  char *key_1_; // [esp+14h] [ebp-1Ch]

  const char *__key_end_offset__; // [esp+18h] [ebp-18h]

  FILE *new_fp; // [esp+1Ch] [ebp-14h]

  unsigned int file_size; // [esp+20h] [ebp-10h]

  unsigned int key_length; // [esp+24h] [ebp-Ch]

  unsigned int index; // [esp+28h] [ebp-8h]

  FILE *fp; // [esp+2Ch] [ebp-4h]


  printf("Key : ");

  no_mean_401000();

  scanf("%s", Key_44D370);

  __key_end_offset__ = Key_44D370;

  key_1_ = &Key_44D370[1];

  __key_end_offset__ += strlen(__key_end_offset__);

  v2 = ++__key_end_offset__ - &Key_44D370[1];

  key_length = __key_end_offset__ - &Key_44D370[1];

  no_mean_401000();

  index = 0;

  fp = fopen("file", "rb");

  no_mean_401000();

  if ( !fp )

  {

    no_mean_401000();

    printf("\n\n\n파일을 찾을수 없다!\n");

    no_mean_401000();

    exit(0);

  }

  fseek(fp, 0, 2);                              // go to end

  no_mean_401000();

  file_size = ftell(fp);

  no_mean_401000();

  rewind(fp);

  no_mean_401000();

  while ( !feof(fp) )

  {

    no_mean_401000();

    file_char = fgetc(fp);

    file_stream_5415B8[index] = file_char;

    no_mean_401000();

    ++index;

    no_mean_401000();

  }

  no_mean_401000();

  for ( index = 0; index < file_size; ++index )

  {

    file_stream_5415B8[index] ^= Key_44D370[index % key_length];

    no_mean_401000();

    file_stream_5415B8[index] = ~file_stream_5415B8[index];

    no_mean_401000();

  }

  fclose(fp);

  no_mean_401000();

  new_fp = fopen("file", "wb");

  no_mean_401000();

  no_mean_401000();

  for ( index = 0; index < file_size; ++index )

  {

    fputc(file_stream_5415B8[index], new_fp);

    no_mean_401000();

  }

  printf(asc_44C1E8);

  no_mean_401000();

  return getch();

}

 보는 바와 같이 루틴은 단순히 키값을 받고, 파일의 값을 not 한뒤 키값과 xor 해서 파일을 암호화 한다. 

readme.txt 를 보면 파일의 형식은 exe 였다. exe 파일은 보통 앞의 magic 값인 MZ 뒤에 널바이트가 꽤 많이 붙어있기 때문에 앞의 MZ를 제외한 나머지부분의 원래 값이 0이라 가정하고 나올 수 있는 key 값을 나오게 해보았다.

다음과 같이 대강 key값으로 보이는 부분이 몇개 보인다. 특히 play 부분의 단어가 같은 간격으로 반복되는 것으로 보아 key의 길이는 12바이트라는 것을 알 수 있었고 이를 통해 키 값을 게싱하여 파일을 복호화하였다.


복호화 된 exe 파일은 upx 패킹이 되어있었고, 그 파일을 실행시키면 키값을 알려준다. (나는 실행이 안되길래 그냥 프로그램을 까서 확인했다.)

'wargame > reversing.kr' 카테고리의 다른 글

[reversing.kr]Direct3D FPS Writeup  (0) 2018.08.02
[reversing.kr]Position Writeup  (0) 2018.08.02