Crypto/드림핵(dreamhack)

드림핵 darimchal_001(LEVEL 1) Write up

Roronoa 2022. 11. 11. 00:14
반응형

문제 설명

[그림 1] 문제 설명

드림이 친구 다리미가 랜섬웨어를 심어 XOR을 하여 암호화하여서 우리는 복호화키를 찾아야한다.

 

문제 코드

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define JOKER "\x40\x53\x06\x03\x43\x52\x54\x3b"
#define KEY   "023661dd4\0"
#define TRUE  1
#define FALSE 0
#define OK    0
#define ERRO -1

void __print_sw_title (char *sw_name);
int __is_valid_pwd (char *pwd);
char *__obfuscation (char *pwd, char *key);
void __create_tag (char *id);

int main (int argc, char *argv[]) {
  if (argc != 2) {
    __print_sw_title(argv[0]);          //intro
    return ERRO;
  }

  if ( __is_valid_pwd(argv[1]) ) {      //검증부분
    __create_tag(argv[0]);
    printf("\n +-+ 무, 무슨... 말도 안돼!! 어떻게 복호화 키를...?? +-+ \n");
  } else {
    printf("\n 너의 파일들은 이제 요단강을 건너다가 저승사자와 하이파이브를 하게되었다! 으하하하하!\n"); // ㅋㅋㅋㅋㅋㅋ
  }

  return OK;
}

int __is_valid_pwd (char *pwd) {
  if (! strncmp(JOKER, __obfuscation(pwd, KEY), sizeof(JOKER)) ) {
    return TRUE;
  }

  return FALSE;
}

char *__obfuscation (char *pwd, char *key) {      //xor함수
  int i;
  for (i = 0; i < strlen(pwd); i++) {             //pwd 길이만큼 반복
    if(key[i] == '\0') break;                     //key에 공백이 있으면 xor하지 않고 넘어감
    pwd[i] = pwd[i] ^ key[i];                     //xor
  }

  return pwd;
}

void __print_sw_title (char *sw_name) {
  printf(" ----------- [%s] ----------- \n", sw_name);
  printf(" ::. 복호화 방법: %s <복호화키>\n\n", sw_name);
}

void __create_tag (char *id) {
  FILE *fd;
  char *tag_name = (char *)malloc(24 * sizeof(char));
  memset(tag_name, '\0', 24);
  snprintf(tag_name,24, "./%s.success", id);
  fd = fopen(tag_name, "w");
  if (fd != NULL) {
    fprintf(fd, "복호화가 완료되었습니다.\n");
    fclose(fd);
  } else {
    printf("[ }{4k3r m3ss493 ] Hey sussy baka~ 7h3r3 w4s 4n 3rr0r 0p3nin9 7h3 file..\n");
  }
}

코드 분석

먼저 인자를 1개 받아야한다. 그 인자가 우리가 찾아야 할 복호화 키이다.

__is_valid_pwd()함수에서 JOKER 값과 pwd^KEY 값을 비교해서 같으면 복호화가 성공한다.

간단히 말해서 JOKER = pwd ^ KEY 공식이 성립한다.

pwd값을 구해야하므로 양쪽에 KEY값을 xor하면 JOKER^KEY = pwd^KEY^KEY 값이 되므로 pwd값은 JOKER^KEY가 성립한다.

__obfuscation()함수는 xor연산을 하는 함수이고 pwd의 길이만큼 반복해서 xor을 한다.

__is_valid_pwd()함수에서 JOKER의 길이만큼만 비교하고 있으므로 8바이트라고 생각하면 편하다.

하지만 key값은 10바이트이네?? 어차피 뒤에는 잘려서 상과없다.

pwd의 길이만큼이므로 key도 8바이트만 xor되서 저장된다.

 

파이썬 코드

JOKER = "\x40\x53\x06\x03\x43\x52\x54\x3b"
KEY = "023661dd4\0"
JOKER = [ord(a) for a in JOKER]
#print(JOKER)
KEY = [ord(b) for b in KEY]
#KEY = KEY[0:-2]
#print(KEY)

XOR = "".join([chr(a^b) for a,b in zip(JOKER,KEY)])
print(XOR)

실행 결과

[그림 2] 복호화 키 값
[그림 3] 복호화 키 값 확인

확인해보니 정답이다.

 

하지만 플래그를 입력할때는 뒤에 _를 빼주고 pa55uc0만 입력을 해야한다.

문제가 설명이 안되어있어서 왜 틀렷는지 의문이 들었지만 댓글보고 해결하였다.

 

플래그 값

pa55uc0
반응형

'Crypto > 드림핵(dreamhack)' 카테고리의 다른 글

드림핵 Basic_Crypto1(LEVEL 1) Write up  (0) 2022.11.08
드림핵 SingleByteXor(Level1) Write up  (2) 2022.09.14