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

[reversing.kr] Ransomware

728x90

1. 문제


1) 문제 확인

Decrypt File (EXE)


By Pyutic

file이라는 암호화된 파일이 있다. 저거를 풀라면 올바른 키값을 입력하라고 한다. 힌트로 file은 exe 실행파일이라고 한다.

2) 코드흐름 파악

악성코드 개발자가 분석을 방해하기 위해서 쓰레기 코드를 앞에 넣어놨다. 그래서 헥스레이가 안돼는데 코드 패치를 하면 되긴하지만 걍 어셈으로 분석가능해서 진행했다

잘보면 file open → fseek → fgetc → feof 요런걸 대충 보아 파일을 열고 한바이트 저장하는거 같다. 아마 입력한 키값으로 복호화를 진행하는거 같은데 디버깅을 하면서 확인해보자

2. 접근방법


위 그래프를 보면 fgetc로 한바이트 읽어온 값을 0x5415b8 위치에 한바이트 저장하고 우측 하단에서 이를 이용한다. 저게 아마 파일에서 읽어온 값이 저장되는거 같다

우측을 보면 ecx와 edx를 xor하고 그 결과를 다시 0x5415b8에 넣는다. 그다음 다시 가져와서 0xff과 xor를 또한다.

저 부분을 디버깅해보면 내가 입력한 키와 파일 한바이트를 xor한다. 따라서 다음과 같이 복호화를 진행한다

File ^ Key ^ 0xff = 디코딩 결과

근데 키값을 현재 모른다. 모르면 브포를 때리면 된다. 현재 file이 exe 포맷이라는 걸 알고 있기 때문에 이를 이용하자

PE 구조 분석
2020. 5. 5. 20:37 by 까망눈공대생 IMAGE_DOS_HEADER 구조체 크기 : 40 IMAGE_OPTIONAL_HEADER 32 메모리에 올라갈 때 참조해야할 중요한 필드들이 위치하고 있다. 해당 구조체는 총 224bytes의 크기를 갖으며 많은 필드가 위치해 있다. typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields.
https://wogh8732.tistory.com/211?category=775085#f075eb8e-1971-4552-8430-270f62d43ad5

전에 PE 구조 분석할때 보았듯이

e_lfanew 필드 전까지는 대부분 동일한 헤더값을 가진다. 따라서 키 값을 모르기 때문에 걍 0x10 크기 씩 복호화를 진행시켜보자

'''
1. (입력한 키 한바이트 ^ encode) ^ 0xff = decode
2. 입력한 키 = decode ^ 0xff ^ encode

암호화 값 : DE C0 1B 8C 8C 93 9E 86 98 97 9A 8C 73 6C 9A 8B

복호화 되야할 값 : 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00

'''

encode=[0xDE,0xc0,0x1b,0x8c,0x8c,0x93,0x9e,0x86,0x98,0x97,0x9a,0x8c,0x73,0x6c,0x9a,0x8b]
decode=[0x4d,0x5a,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0x00,0x00]

key=''
for i in range(len(decode)):
    key+=chr(decode[i]^0xff^encode[i])

print(key)
--------------
=> letsplaychesslet

0x10 크기만큼 일단 돌려봤는데 letsplaychesslet 이라는 문자열이 나왔다. 0x10 크기만큼 더 돌려보자.

'''
1. (입력한 키 한바이트 ^ encode) ^ 0xff = decode
2. 입력한 키 = decode ^ 0xff ^ encode

암호화 값 : DE C0 1B 8C 8C 93 9E 86 98 97 9A 8C 73 6C 9A 8B

복호화 되야할 값 : 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00

'''

encode=[0xDE,0xc0,0x1b,0x8c,0x8c,0x93,0x9e,0x86,0x98,0x97,0x9a,0x8c,0x73,0x6c,0x9a,0x8b,\
    0x34, 0x8F, 0x93, 0x9E, 0x86, 0x9C, 0x97, 0x9A, 0xCC, 0x8C, 0x93, 0x9A, 0x8B, 0x8C, 0x8F, 0x93]
decode=[0x4d,0x5a,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0x00,0x00,\
    0xB8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]

key=''
for i in range(len(decode)):
    key+=chr(decode[i]^0xff^encode[i])

print(key)
---------------------
=> letsplaychess letsplaychess letspl

음 보면 반복되는 문자열인거 같다. 아마도 letsplaychess 인듯

3. 풀이


exe로 잘 풀린것 같다. 한번 실행해보자

4. 몰랐던 개념


728x90

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

[reversing.kr] Direct 3D FPS  (0) 2020.12.21
[reversing.kr] Position  (0) 2020.12.16
[reversing.kr] ImagePrc  (0) 2020.12.15
[reversing.kr] Replace  (0) 2020.12.14
[reversing.kr] Music Player.exe  (0) 2020.12.11