[Binary] PETya 랜섬웨어 분석

[분석환경]
Windows 7 Ultimate 64bit

[분석도구]
PEiD, Stud_PE, BinText, PEView, OllyDbg, IDA Pro

 

리버싱 실력 향상을 위해 악성코드 분석을 하던 중 랜섬웨어를 분석하게 되어 정리로 남겨둔다. 자동화된 도구의 사용을 최대한 배제하였다.(IDA Hex-Ray 등). 분석에 사용한 바이너리는 교내 사이버보안 연구센터에서 제공받았으며 블로그를 통해 공유하지 않는다.

 

랜섬웨어(Ransomware)

랜섬웨어는 컴퓨터 시스템을 감염시켜 접근을 제한하고 일종의 몸값을 요구하는 악성 소프트웨어의 한 종류이다. 컴퓨터로의 접근이 제한되기 때문에 제한을 없애려면 해당 악성 프로그램을 개발한 자에게 지불을 강요받게 된다. 위키백과

Petya

MBR Locker 랜섬웨어가 유행할때 등장하였다.
2016년 3월 25일부터 MBR 영역을 변조하여 정상부팅을 불가능하게 한다.
MBR 암호화 작업 후에 금전을 요구한다.

부팅 불가라는 파괴적 기능을 수행하지만 데이터의 암호화는 수행하지 않는다.(데이터의 복구는 가능)

1. 정적 분석(Static Analysis)

Virustotal

현재는 다수의 AV에서 진단하고있다. 

PE 정적 분석 도구로 보았을 때 "알려진" 패커 중에서는 사용된 것이 없다는 것을 확인할 수 있다. 각 섹션의 영역의 주소와 사이즈가 일반적인 PE파일과 유사하다.

 

2. 동적분석(Dynamic Analysis)

Entry Point에서 악의적인 행위를 시작하는 부분까지 진행한 모습이다. VirtualAlloc 함수를 이용하여 메모리를 할당(1000h = 4096)한다. 그리고 VirtualProtect를 이용하여 메모리 보호 설정 값을 변경한다.

새로운 PE파일 작성

정상 파일이 실행되던 중에 새로운 dll을 작성하는 모습이다. 

재작성된 DLL

재작성된 DLL의 모습을 보면 PE파일의 헤더의 형태와, 랜섬웨어 감염 이후 보이던 문자열들을 확인할 수 있다.

올리디버거에서는 Search For - All intermodular calls 메뉴를 이용하여 재작성된 dll에서 사용하고 있는 시스템 함수들을 확인할 수 있다. 확인한 결과는 아래와 같으며 악의적인 행위에 주로 사용되는 함수에 BP를 건 후 분석 하였다.

 

재작성된 DLL에서 호출하는 메소드

분석 결과 정리한 과정은 다음과 같다.

LoadLibraryA() 이용해 kernel32.dll을 준비

CreateFileA()를 이용해 C드라이브의 핸들을 얻음

“\\.\C:”, “\\.\PhysicalDrive0”를 통해 존재하는지, 핸들을 가질 수 있는지 검사

ReadFile() - 핸들을 얻는데 성공하면 MBR영역에서 0x200bytes 만큼 가져옴

XOR - 읽어온 영역에서 XOR 연산 수행

WriteFile() - 핸들을 얻는데 성공하면 MBR영역에서 0x200bytes 만큼 가져옴

kernel32.DeviceIoControl

DeviceIoControl은 해당 장치가 특정 작업을 수행하도록, 컨트롤 코드를 디바이스 드라이버로 전송한다. 

IoControlCode(0x70048) = IOCTL_DISK_GET_PARTITION_INFO_EX
파티션 정보를 얻고 PhysicalDrive 번호를 가져온다.

CreateFileA를 이용해 “물리디스크 0번째”의 핸들 얻기

 

XOR 연산

핸들을 얻은 후 MBR 영역을 반복하면서 다음의 과정을 수행한다.

XOR BYTE PTR SS:[ESP+ECX+248], 37 ; 스택에 저장된 MBR 값을 0x37 값으로 XOR연산하여 스택에 저장

INC ECX ; 반복문 수행을 위한 변수 증가 1++

CMP ECX, 200 ; XOR을 수행한 영역이 0x200보다 큰지 검사

JB SHORT 004D8D54 ; Jump if Below ; CMP 결과가 뒷 값이 크면 레이블로 JMP

여기서 왜 0x200 만큼만 진행하는지에 대한 의문이 들었다. 하드디스크 영역에는 마스트 부트 레코드(MBR) 영역이 정의되어 있는데 시스템이 부팅할 때에 이 영역의 값들을 참고하여 사용한다고 한다. 이 영역이 망가지게 되면 부팅이 불가능해지게 되는 것이다.

Size of MBR(0x200 = 512)

다시 SetFilePointerEx()파일포인터 가져와서 파일 포인터를 MOV EBX, 200을 통해 0x200만큼 이동시킨다. ReadFile()을 이용하여 읽는다.

XOR 0x37

CMP ESI, 22; 반복문 0->0x22(34)회 수행 (섹터 0 ~ 섹터 33 반복 위함)

JL SHORT 004D8DA3; MBR영역 읽고 쓰기

섹터의 데이터를 읽고 XOR 0x37한 결과를 작성하기

이후에 SetFilePointer를 이용하여 MBR 0x0 위치로 이동시킨 후 악성코드를 0x200 만큼 작성한다. 

암호화(?) 라기보다는 XOR 연산 작업이 완료된 후 MBR 영역을 비교해 보았다.

 

변경 전 후 MBR (0x0 ~ 0x200)

그 이후로는 계속 파일 포인터를 이동하고 악성코드를 작성하는 작업의 연속이었다. 

파일 포인터를 0x4400으로 이동 후 0x2000크기만큼 작성한다.

파일 포인터를 0x7000으로 이동 후 0x200 크기만큼 작성

암호화된 원본 MBR 이 위치에 작성된다.

암호화 후 하드디스크의 데이터 구조는 다음과 같다.

Disk 구조

암호화 작업을 완료한 후 로컬 시스템의 종료 권한을 얻기 위해 SeShutdownPriviledge를 사용한다.

얻어온 권한을 토큰에 적용

그 다음 Ntdll.NtRaiseHardError의 주소를 얻고 호출한다. 이때 하드디스크 에러 발생시키고, 재부팅 진행한다. 재부팅 시, 올바르지 않은 MBR로 부팅 불가하게 되는 것이다.

반응형

'Reversing' 카테고리의 다른 글

[Frida] Binary Hooking 2  (0) 2022.05.03
[Frida] Binary Hooking 1  (1) 2022.04.28
DLL Injection 실습  (0) 2020.12.14
[Reversing] Windows 10 Anti-Reversing 기법 2  (0) 2020.12.10
[Reversing] Windows 10 Anti-Reversing 기법 1  (0) 2020.12.09