1. 문제
다리미가 화가나서 드리미 컴퓨터에 랜섬웨어 설치
2. 코드 분석
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define JOKER "\\x40\\x53\\x06\\x03\\x43\\x52\\x54\\x3b" // "@S\\x06\\x03CRT;"
#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);
// argc는 인자의 개수이고 argv는 인자의 값들이 들어간다. 하지만 argv[0]은 보통 프로그램 명이 들어가고 argv 부터 인자 값이 저장된다.
int main (int argc, char *argv[]) {
// argc 즉 인자의 개수가 2개가 아니라면 if 문을 실행한다.
if (argc != 2) {
// __print_sw_title 함수를 실행하여 프로그램 명을 전달하고
__print_sw_title(argv[0]);
return ERRO;
}
// __is_valid_pwd에서 첫 번째 인자값이
if ( __is_valid_pwd(argv[1]) ) {
// if 문이 참이면 즉, JOKER와 PWD 값이 같으면 실행된다.
// __create_tag(arvg[0]) 값을 전달한다.
__create_tag(argv[0]);
printf("\\n +-+ 무, 무슨... 말도 안돼!! 어떻게 복호화 키를...?? +-+ \\n");
} else {
printf("\\n 너의 파일들은 이제 요단강을 건너다가 저승사자와 하이파이브를 하게되었다! 으하하하하!\\n"); // ㅋㅋㅋㅋㅋㅋ
}
return OK;
}
// 첫 번째 인자값을 입력받는다.
int __is_valid_pwd (char *pwd) {
// 만약 strncpm 함수로 JOKER 와 __obfuscation 을 한 값을 비교한다.
// 비교하는 이자의 수는 JOKER의 사이즈 즉, 8바이트 만큼 비교한다.
// 제어문자들은 출력 시 보이지 않지만 메모리에서는 그대로 8 바이트이다.
if (! strncmp(JOKER, __obfuscation(pwd, KEY), sizeof(JOKER)) ) {
return TRUE;
}
return FALSE;
}
// argv[1]의 문자열과 key값을 매개변수로 받는 함수이다.
char *__obfuscation (char *pwd, char *key) {
// 입력한 매개변수 길이 만큼 암호화를 진행한다.
int i;
for (i = 0; i < strlen(pwd); i++) {
if(key[i] == '\\0') break; // key 값이 NULL 값이면 종료한다.
// 암호화 방식은 KEY 값과 pwd의 문자열을 1대1로 XOR 연산을 진행한다.
pwd[i] = pwd[i] ^ key[i];
}
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 포인터를 지정하고
FILE *fd;
// 프로그램 이름 만큼 동적 할당을 해주고, 메모리를 0으로 초기화 한다.
char *tag_name = (char *)malloc(24 * sizeof(char));
memset(tag_name, '\\0', 24);
snprintf(tag_name,24, "./%s.success", id);
// 파일을 쓰기 모드로 열어준다.
// 파일 열기를 하고 파일 포인터 값이 NULL 값이 아니면 복호화 완료 메시지가 뜬다.
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");
}
}
3. 풀이
코드를 봐서는 if 문의 __is_valid_pwd 함수를 참으로 만들어야 한다.
__is_valid_pwd 함수에서 인자로 사용자 입력값을 전달해준다.
if 문을 TRUE로 만들기 위해서는 JOKER 과 pwd의 문자열 값이 같아야 한다.
_obfuscation 함수에서 문자열 길이만큼 KEY 값과 입력 문자열을 XOR 연산한다.
따라서 JOKER의 문자들을 바이트 단위로 변환시켜준다.
zip 함수를 사용해서 iterable 객체의 요소들을 한개 씩 받아서 XOR 연산을 수행한다.
join 메소드를 사용해서 문자열로 변환시켜주면 복호화 키가 나온다.
'Wargame > wargame 암호학' 카테고리의 다른 글
[Dreamhack] ICM2022 (0) | 2024.05.11 |
---|---|
[Dreamhack] likeb64 (0) | 2024.05.11 |
[Dreamhack] robot_only (0) | 2024.04.30 |
[Dreamhack] basic crypto (0) | 2024.04.29 |
[Dreamhack] ROT128 (0) | 2024.04.29 |