정상파일을 ".crypt" 확장자를 부여하여 암호화하는 특징을 갖는 CryptXXX 이름의 랜섬웨어는 현재까지 버전 1.x, 2.x, 3.x 세 가지 형태가 알려져 있다. 본 글에서는 이 중, 2.x 버전의 암호화 방식을 소개하고, 이를 바탕으로 일부 파일에 한해 복구가 가능함을 설명한다.

 

1. 암호화 방식

아래의 [그림-1]은 CryptXXX 에 의해 암호화된 "Photo.jpg.crypt" 파일을 나타낸다. 암호화는 고정크기(0x1FFF)의 블록 단위로 순차적으로 이루어지며, 암호화 최대 크기는 0xD012FE (대략 13M)로 이후의 데이터는 원본파일과 동일하다. (단, 원본파일 끝에 260바이트 크기의 데이터는 삽입)

 

[그림-1] CryptXXX 암호화 방식

 

암호화된 파일은 공통적으로 원본파일과 비교하여 260(=0x104)바이트가 증가한 형태이며, 이는 파일 끝 부분에 삽입된 KeyTable 정보([그림-1]에서 붉은색 블록)로 인한 것이다. 이 KeyTable 정보가 블록 단위의 암호를 복호화하는데 핵심이 되는 데이터로 공개키를 통해 암호화되어 저장된다. 즉, 구조적으로는 해당 공개키에 매칭되는 개인키 정보없이는 해당 KeyTable 정보를 복호화할 수 없고, 파일복구가 불가능하다. 하지만, 해당 KeyTable 정보는 개인키 없이도 원본파일 시작부분 일부 데이터(예를들면 파일포멧 별 Magic 정보)만 알 수 있다면 유추할 수 있는 취약성이 존재한다.

- PDF 파일의 Magic: "%PDF" (파일시작 첫 4바이트)
- DOC, PPT, XLS 파일의 Magic: "D0CF11E0" (파일시작 첫 4바이트)

 

2. KeyTable 생성방식과 취약성

아래의 [그림-2]는 파일 끝에 삽입된 0x104 바이트 크기의 KeyTable 이 생성되는 과정을 나타내며, 노란색 부분이 공개키로 암호화된 KeyTable_A[0x40] 이며, CryptEncrypt() API를 통해 공개키로 암호화 시 원본 0x40 크기의 데이터가 최종 0x80 크기로 증가된다.

 

[그림-2] 키 테이블 생성과정

 

[그림-2]에서 언급된 암호화에 사용되는 핵심 정보 3가지는 "4바이트 SEED 값", "KeyTable_A[0x40]", KeyTable_B[0x100] 이며, 최초 4바이트 크기의 SEED 값으로 부터 이후 정보들이 순차적으로 만들어지는 구조를 갖는다. 키 생성과정의 최 상위에 위치하는 SEED 값은 감염시점의 시스템시간(SystemTime) 정보 중, 시(wHour), 분(wMinute), 초(wSecond), 밀리초(wMillisecond) 를 이용하여 얻어지며, 이 SEED 값으로부터 0x40 크기의 KeyTable_A[0x40] 데이터가 생성된다. 바로 이 부분에서 제작자가 의도하지 않은(?) 취약성이 존재하며, SEED 값이 동일하면 매번 동일한 KeyTable_A[0x40] 가 생성되는 구조를 갖는다. 최종 블록 단위의 암호화에 사용되는 KeyTable_B[0x100]의 데이터와 원본파일로 부터 읽은 블록과의 XOR를 통해 암호화가 수행된다. 

즉, SEED 값이 동일하면, 매번 생성되는 최종 키 테이블정보가 동일한 점과 암호화 방식이 XOR라는 2가지 포인트를 바탕으로 복구대상 파일의 고정적 Magic 정보가 존재한다면, 역으로 키를 유추할 수 있는 구조이다. 아래의 [그림-3]은 SEED 값이 0x02978CAC 일 때, 생성되는 키 테이블 A,B의 예를 나타낸다.

 

[그림-3] 키 테이블 A,B 예제

 

KeyTable_A[0x40] 데이터가 생성되는 방식은 아래의 2가지 기본 테이블 중, Delphi Random 함수를 통해 얻은 랜덤값을 바탕으로 하나의 값이 선택되어 구성되는 구조를 갖는다.

(1) "QWERTYUIOPASDFGHJKLZXCVBNM<>:\?!@$%^&*()_+~|"
(2) "qwertyuiop[]asdfghjkl;zxcvbnm,./`1234567890-="

CryptXXX 는 총 2번의 Delphi Random 함수를 사용하여 아래의 Index(A)와 Index(B)를 얻게되고, Index(A)는 위 기본 테이블 중 하나를 선택하기 위한 목적으로, Index(B)는 선택된 테이블의 데이터 중 하나를 선택하기 위한 목적으로 사용된다.

Index(A): DelphiRandom(3) - 0 ~ 2 범위의 랜덤 값 생성 (0, 2인 경우 -> (1)번, 1인 경우 -> (2)번)
Index(B): DelphiRandom(44) - 0 ~ 43 범위의 랜덤 값 생성

예를 들어 Index(A) == 0 이고, Index(B) == 3이면, ‘R’ 문자열이 선택된다.

 

3. 키 테이블 생성함수

CryptXXX 랜섬웨어에서 파일 암호화 시 사용되는 핵심 정보 3가지 별 생성함수는 다음과 같다.

 

(1) SEED 값 생성

아래의 [그림-4]는 SystemTime 정보를 통해 4바이트 크기의 SEED 값을 생성하는 함수를 나타낸다. 시스템시간 정보는 SEED 값 생성에 가장 중요한 정보로 암호화된 파일의 수정시간을 통해 유추할 수 있으나, CryptXXX 는 암호화 수행 전 해당 파일의 시간정보를 저장(GetFileTime)해둔 후, 암호화 완료 후 원래의 시간정보로 재 설정(SetFileTime)하는 기능으로 인해 유추가 불가능하다.

[그림-4] SEED 값 생성함수

 

(2) 키 테이블(A) 생성

아래의 [그림-5]는 SEED 값을 바탕으로 0x40 크기의 키 테이블을 생성하는 함수이며, do-while 문을 통해 1바이트 씩 생성되는 데이터가 SEED 값이 동일하면 동일형태로 생성되는 취약성이 존재하는 부분이다.

[그림-5] 키 테이블(A) 생성함수

 

(3) 키 테이블(B) 생성

아래의 [그림-6]은 키 테이블(A)로 부터 0x100 크기의 최종 키 테이블(B)가 생성되는 함수를 나타낸다. 이 키 테이블 정보는 1바이트 단위의 블록단위의 암호화 시 XOR 키 값으로 사용된다.

[그림-6] 키 테이블(B) 생성함수

 

4. 복구방식

시, 분, 초, 밀리초 정보를 통해 계산되는 SEED 값의 범위는 다음과 같다.

- 최소값: 00:00:00:0000 -> 0, 최대값: 23:59:59:999 -> 0x5265BFF

사용자 마다 그리고 암호화된 파일마다 서로 다른 SEED 값을 유추하기 위해 0 ~ 0x5265BFF 범위의 SEED 를 순차적으로 선택하며, 이를 바탕으로 암호화에 사용된 키 테이블을 생성 및 복호화를 시도한다. 첫 번째 블록에 대한 복호화를 통해 파일의 고유한 Magic 정보가 확인되면, 유효한 SEED 값으로 판단하고 전체 파일에 대한 블록 단위의 복구를 시도한다. 우선 첫 번째 파일이 복구에 성공하면, 두 번째 파일부터는 SEED의 범위를 제한하여 좀 더 빠른 복구가 가능하도록 하였다. 이러한 설정은 복구대상 파일들이 동일 시간대에 감염된 형태가 대부분일 것으로 가정하여 이루어진 것으로 복구대상 파일들이 서로 다른 시스템에서 다른 시간대에 수집된 형태의 경우, 복구시간이 더 오래 걸리는 특징을 갖는다.

아래의 [그림-7]은 CryptXXX 복구툴에서 파일복구을 위해 이루어지는 과정을 나타낸 것으로 구조상 첫번째 파일을 복구하는데 오랜 시간이 소요되며, 이후 파일부터는 빠르게 복구가 가능하다.

 

[그림-7] 복구툴 동작방식

 

5. 복구대상 리스트

복구툴을 통해 복구가능한 CryptXXX 버전은 2.x 로 제한적이며, 우선 아래의 확장자들에 대해 복구가 가능하도록 제작되었다. 하지만, 이 외에도 원본파일의 고유한 Magic 정보만 알 수 있다면, 복구가 가능한 구조이므로 추후 복구대상이 추가될 수 있다.

CHM, AI, HWP, PDB, PDF, RTF, HTM, HTML, PHP, XML, DWG, PS, WSF, KEY, CSR, CRT, WAV, MP3, OGG, WMA, WMV, AVI, ASF, MP4, MOV, MID, MPG, FLV, PNG, GIF, BMP, TIF, JPG, JPEG, ZIP, RAR, BZ2, 7Z, GZ, JAR, APK, TGZ, ODS, DOC, DOT, PPT, POT, PPS, XLS, XLT, DOCX, DOCM, DOTX, DOTM, PPTX, PPTM, POTM, POTX, PPSM, XLSX, XLSB, XLSM, XLTM, XLTX, EPS, ISO, SQLITE3, MDB, MSI, APP, FDB, ACCDB, SLN, CLASS, VCXPROJ

(단, 위 명시된 확장자들 중, 파일시작 부분이 고유한 Magic 정보를 갖지않는 파일들(HTM, HTML, XML, PHP 등)은 현재 일부 태그(<html, <?xml, <?php 등)만을 Magic 정보로 추가한 상태이다. 즉, 암호화된 파일이 해당 태그로 시작하지 않는 경우, 복구하지 못함)

 

6. 복구툴 경로

CryptXXX 랜섬웨어 2.x 버전에 대한 복구툴은 아래의 경로로 부터 다운로드 가능하다.

https://www.ahnlab.com/kr/site/download/product/productVaccineView.do?seq=118


복구툴에 의해 진단되었으나 치료버튼 클릭 시, 아래와 같이 "복원 실패"로 처리된 파일들의 유형은 다음의 2가지 경우에 해당한다.

전용 복구툴 실행화면

 

유형-1) 감염시점이 복구된 파일들과 다른 경우: 재 검사/치료 시 복원 가능

유형-2) Magic 값을 찾지못한 경우: 새로운 Magic 패턴 추가필요 (대부분 HTML, PHP, XML 등의 경우에 해당)

 

7. CryptXXX 3.x 버전

CryptXXX 랜섬웨어 3.x 버전은 원본 파일을 암호화 시, 키 테이블을 이용한 XOR 방식이 아닌 공개키를 사용하는 것으로 확인되어 복구가 불가능한 구조를 갖습니다. 전용 복구툴을 통해 3.x 버전에 감염된 파일을 진단 시, 아래와 같은 메시지 창을 확인할 수 있습니다.

 

3.x 버전에 대한 복원 불가 메시지

 

 

Creative Commons License
Creative Commons License
Posted by yhayoung