다음은 MBR의 부트코드에 어떤식으로 ASM코드를 쓰는지(Overwrite)하는지에 대해 코드를 보고 예제 코드이 API의 사용법에 대해 새새하게 정리해본다.
우선 MBR을 공부하게된 Petya 랜섬웨어를 예로 들면 다음과 같인 API을 대표적으로 사용하는 것을 확인할 수 있다.
CreateFileA - 파일에 접근하기 위해 사용되는 API
DeviceIoControl - MBR 섹터에 대한 정보를 확인하는데 이용
SetFilePointEx - 파일의 포인터를 이동 시기킄데 사용
WriteFile / ReadFile - MBR 섹터에 암호화된 데이터를 쓸 때 사용되는 API
이들 중 다음 세개 API에 대해서 좀 더 자세히 알아보고 들어가 보자.
CreateFile / DeviceIoControl / SetFilePointEx
CreateFile API - MSDN
해당 API의 함수 형태는 다음과 같은 형태를 갖고 있다.
HANDLE WINAPI CreateFile(
_In_ LPCTSTR lpFileName, #생성하고자 하는 파일
_In_ DWORD dwDesiredAccess, #파일에 대한 엑세스 권한 지정
_In_ DWORD dwShareMode, #파일의 공유 모드 지정
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, #보안속성 지정, SECRITY_ATTRITUBES 구조체 포인터
_In_ DWORD dwCreationDisposition, #파일을 생성할 것인지 열것인지 지정
_In_ DWORD dwFlagsAndAttributes, #생성 파일의 속성을 지정
_In_opt_ HANDLE hTemplateFile #생성된 파일의 속성을 제공할 탬블릿
);
보통 해당 함수는 다음과 같은 형태로 사용되며 목적은 PhysicalDrvie0에 접근하기 위해 사용된다. (MBR Handle 획득)
CreateFileA("\\\.\\PhysicalDrvie0", 0x40000000, 0x3, 0, 0x3, 0, 0)
FileName : "\\\.\\PhysicalDrvie0"
DesiredAccess : 0x40000000 => GENERIC_WRITE
0x00000001 => CREATE_ALWAYS
0x80000000 => GENERIC_READ
ShareMode : 0x3 = 0x00000003 => FILE_SHARE_WRITE(0x01) | FILE_SHARE_READ(0x02)
0x00000000 => NULL = File 또는 Device에 delete, read, write 접근이 가능
0x00000004 = FILE_SHARE_DELETE => DELETE 가능
0x00000001 = FILE_SHARE_READ => READ 가능
0x00000002 = FILE_SHARE_WRITE => Write 가능
SecurityAttributes : 0
CreationDisposition : 0x3 = > OPEN_EXISTING
0x2 : CREATE_ALAWAYS => 새로운 파일을 항상 만들 수 있음, Error code = 183
0x1 : CREATE_NEW => 같은 파일이 존재하지 않은 경우, 새로운 파일을 만듬. Error code = 80
0x4 : OPEN_SLAWAYS => 파일을 염, Error code = 183
0x3 : OPEN_EXISTING => 파일이나 디바이스에 아무 접근 없을 시, 파일을 염, Error code = 2
0x5 : TRUNACATE_EXISITING
FlagAndAttributes : 0
0x20(32) : FILE_ATTRIBUTE_ARCHIVE
0x4000(16384) : FILE_ATTRUBYTE_ENCRYPTED
0x2(2) : FILE_ATTRIBUTE_HIDDEN
0x80(128) : FILE_ATTRIBUTE_NORMAL
0x1000(4096) : FILE_ATTRIBUTE_OFFLINE
0x1(1) : FILE_ATTRUBYTE_READONLY
0x4(4) : FILE_ATTRIBUTE_SYSTEM
0x100(256) : FILE_ATTRIBUTE_TEMPORARY
0x02000000 : FILE_FLAG_BACKUP_SEMANTICS
0x04000000 : FILE_FLAG_DELETE_ON_CLOSE
0x20000000 : FILE_FLAG_NO_BUFFERING
0x00100000 : FILE_FLAG_OPEN_NO_RECALL
0x00200000 : FILE_FLAG_OPEN_REPARSE_POINT
0x40000000 : FILE_FLAG_OVERLAPPED
0x01000000 : FILE_FLAG_POSIX_SEMANTICS
0x10000000 : FILE_FLAG_RANDOM_ACCESS
0x00800000 : FILE_FLAG_SESSION_AWARE
0x08000000 : FILE_FLAG_SEQUENTIAL_SCAN
0x80000000 : FILE_FLAG_WRITE_THROUGN
TemplateFile : 0
정리하면, 우선 CreateFile API은 PhysicalDrive에 접근하기 위해 주로 사용된다는 점을 알아두고 가자! 보통은 파일에 접근할 때 사용되지만, PhysicalDrive에 접근한다면, MBR 영역을 의심해보자!
주로 파티션의 갯수를 확인하고자 할 때 사용된다. API의 형태는 다음과 같은 형태를 가지고 있다.
BOOL WINAPI DeviceIoControl(
_In_ HANDLE hDevice, #CreateFile로 받은 값이 들어가고, 타겟이 된다.
_In_ DWORD dwIoControlCode, #전달된 I/O Control Code가 들어간다.
_In_opt_ LPVOID lpInBuffer, #InBuffer 설정
_In_ DWORD nInBufferSize,
_Out_opt_ LPVOID lpOutBuffer, #OutBuffer 설정
_In_ DWORD nOutBufferSize,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
해당 API에서는 IoControlCode에 따라 역할이 달라진다. IoControlCode는 다음과 같이 32bit 구조를 가지고 있다.
해당 API는 PhysicalDrive에 접근해서 PhysicalDrvie 번호를 설정하거나, 파티션의 정보를 읽어오거나 할때 사용된다.
IoControlCode -> 좀 정리되고 정의된 데이터가 있으면 좋겠는데 안보인다. 코드 볼때마다 IoControlCode 값이 어떤걸 의미하는지 검색해봐야겠다.
우선 내가 정의한 코드들은 다음과 같은 역할을 한다.
0x70000 => IOCTL_DISK_GET_DRVIE_GEOMETRY, 디스크 타입, 실런더 갯수, 실린더 당 트랙, 트랙당 섹터, 섹터당 바이트 등
0x90020 => FSCTL_DISMOUNT_VOLUME, FSCTL의 마운트를 해제하는 역할
0x560000 => IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, PhysicalDrvie 번호를 설정할 때 사용
0x70048 => IOCTL_DISK_GET_PARTITION_INFO_EX, 파티션 정보를 읽어옴
이정도 인듯 하다. 위에 사용된 IoControlCode를 보면 알 수 있듯이, DeviceIoControl API는 MBR의 정보를 획득하기 위해 사용되는 것을 알 수 있다.
SetFilePointerEx - MSDN
개발자 시선에서 의 파일 포인터
- 파일을 열면 초기 파일 포인터는 0이다.
- ReadFile, WriteFile 등의 함수를 이용하면 파일 포인터는 자동으로 증가한다.
- 이러한 파일 포인터를 이동시킬 때 사용되는 API가 SetFilePointer다.
- 오프셋이 32비트
BOOL WINAPI SetFilePointerEx(
_In_ HANDLE hFile, #File handle
_In_ LARGE_INTEGER liDistanceToMove, #이동할 거리
_Out_opt_ PLARGE_INTEGER lpNewFilePointer, #옮겨진 포인터를 확인, 확인할 필요 없을 경우 NULL
_In_ DWORD dwMoveMethod #어디로 이동할 것인지
);
dwMoveMethod Flag
FILE_BEGIN : 파일 처음부터
FILE_END : 파일 끝에서
FILE_CURRENT : 현재 위치에서
idb랑 pdf는 못올리는군...ㅠㅠ
답글삭제