대게 사용 중인 저장 장치를 덤프 떠보게 되면 다음과 같은 이미지 파일을 획득할 수 있을 것이다.
그리고 이를 FTK Imager와 같은 이미지 분석 도구를 이용하여 확인할 경우 아래와 같은 광경을 보게 될 것이다.
이 중 실제 USB 내 데이터를 확인할 수 있는 위치는 Partition 1의 [root] 폴더이다. 그런데 이 이미지 파일에는 실제 저장된 데이터에 대한 정보 이외에 FAT32 파일 시스템과 관련된 것으로 추측되는 파일들도 있었고, 아래 사진과 같이 File List로는 확인되는 것이 없으나 이미지 파일 자체의 시작 오프셋 위치에서 별도의 hex값도 확인할 수 있었다.
여러 차례 이미지 파일 분석을 돌려보는 과정에서 대체 이 내부의 구조가 어떻게 되어 있길래 이러한 구성을 갖게 되는 것일지 궁금했다. 그리고 이러한 궁금증을 해결하기 위한 리서칭 중 답은 저장 장치의 구조와 관련이 있을 것으로 파악하고 이를 공부하고자 이번 포스트를 작성하게 되었다.
Storage Structure
저장 장치는 기본적으로 다음과 같은 형태를 가진다.
이 구조는 파티션 관리를 위해 MBR을 사용하는 경우에 해당하는 구조이지만, 후반부에 정리된 GPT를 사용하는 구조에서는 조금 다른 형태의 구조를 볼 수 있다. 그럼에도 크게 “저장장치 구조” 라는 범주로 보았을 때, 저장장치 부트 과정에 관여하면서 파티션에 대한 정보를 저장하는 파트와 각 파티션 별로 데이터를 저장하는 파트로 구성되는 점은 공통적으로 확인되었다.
MBR(Master Boot Record)
MBR은 저장장치 단위로 제일 앞에 한번 위치한다. MBR에서는 저장장치가 사용되기 위해 필요한 정보들이 저장되어 있는데, 크게 Boot Code와 Partition Table로 이루어져 있다.
MBR의 파티션 테이블의 경우 최대 4개의 primary partition만 생성 가능한 구조로 이루어져 있다는 점에서 MBR이 GPT로 대체된 이유를 알 수 있다.
MBR의 세부적인 구조는 글의 중반부에서 별도로 다루어진다.
MBR Slack
MBR과 파티션의 VBR이 존재하는 위치 사이에 있는 여유 공간을 가리킨다. 이 공간은 말그대로 여유 공간이기 때문에 악성 코드에 의해 악용되기도 하는 공간이다.
VBR(Volume Boot Record)
VBR은 각 볼륨이 시작될 때 한번씩 위치하는 부분이다. VBR은 해당 볼륨에 액세스 하기 위한 정보를 가지고 있는데, 여기에는 파일 시스템 타입, 부트 코드, 에러 메세지 등이 포함된다. MBR의 파티션 테이블을 통해 부팅 가능한 파티션에 접근하게 되고, 그 후 VBR이 실행된다.
Volume Data
각 볼륨의 데이터가 저장되는 부분이다. 각 볼륨 마다 지정된 파일 시스템 형태로 포맷되어 있으며, 이에 저장된 각 파일은 메타 데이터와 파일 데이터 정보를 가진다. 이러한 구조에 따라, directory 탐색 시에는 메타 데이터 정보를 사용하고, 파일 내용에 접근하면서 파일 데이터 정보가 사용된다.
MBR(Master Boot Record)
초기의 저장 장치에서는 정상적인 부팅을 위해 매 저장 장치의 맨 앞에 위치한 MBR을 사용하였다. 이를 이용하여 장치의 부팅 뿐만 아니라 실제 데이터가 저장되어 있는 볼륨에 접근하기 위한 정보도 관리한다.
MBR Structure Overview
MBR은 다음과 같은 구조로 이루어져 있다.
가장 처음에 부트 코드가 위치해있고, 그 후에는 장치 내 할당된 파티션의 정보를 가진 Partition Table이 위치한다. 이러한 구조를 이용하여 BIOS의 POST(Power On Self Test) 단계 이후 Bootstrap 실행 시 MBR 내 저장된 부트 코드를 읽어올 수 있다.
부트 코드를 위해 할당된 446 바이트 이후에는 곧바로 파티션 테이블이 위치한다. MBR에서 파티션 테이블이 차지하는 크기는 총 64바이트인데, 각 테이블에 대한 정보를 16바이트 크기로 저장한다. 이에 따라 MBR을 채용한 저장 장치의 경우에는 최대 4개의 테이블만을 가질 수 있게 된다.
부트 코드와 파티션 테이블에 이어 2바이트 크기의 Signature를 확인할 수 있다. 이 값은 16진수로 55 AA 값을 가지며 MBR의 끝을 가리킨다.
Partition Table entry
각 파티션을 가리키기 위해 사용되는 파티션 테이블의 entry는 다음과 같은 구조로 이루어져 있다.
Offset 0x0 에 위치하는 Boot Flag는 1바이트의 크기를 가지는 필드이며, 해당 파티션에 할당된 볼륨이 부팅 가능한 상태인지 불가능한 상태인지를 나타낸다. 이 값이 0x80일 경우에는 부팅 가능 상태, 0x00일 경우에는 부팅 불가능한 상태를 가리킨다.
Offset 0x1과 0x5에 위치하며 총 3바이트의 크기로 각각 시작 CHS 주소와 끝 CHS 주소를 가지는 필드가 있다. 이들은 파티션의 위치를 CHS 주소 지정 방식을 사용하여 나타낼 경우에 파티션이 위치하는 처음과 끝 주소를 나타낸다.
Offset 0x4 위치에는 1바이트의 크기를 사용하여 파티션의 유형을 나타내는 필드가 있다. 각 파티션 유형에 따른 값은 아래 링크를 참조하여 알 수 있다.
Offset 0x8 위치에는 4바이트의 크기로 시작 LBA 주소를 가지는 필드가 있다. 이 필드는 CHS 주소 지정 방식과는 다른 LBA 주소 지정 방식을 사용할 경우의 파티션 시작 위치 주소를 가진다.
이 필드를 사용하여 파티션의 위치를 참조할 경우 파티션의 끝 위치는 Offset 0xC에 있는 필드값을 사용하여 알 수 있다. 이 필드는 해당 파티션에 할당된 크기를 나타내는 필드로 활용될 수 있는데, 정확히는 해당 파티션 내에서 사용 가능한 sector의 개수를 의미하는 필드이다.
이 필드는 4바이트로 표현됨에 따라 한 파티션에서 사용 가능한 sector의 최대 개수가 2^32 개가 되며, 한 sector는 512바이트의 크기를 갖는 것에 따라 계산해보면… 한 파티션 당 최대 2TB의 크기만을 가질 수 있게 된다.
GPT(GUID Partition Table)
GPT는 MBR의 한계를 해결하고자 등장한 구조이다. 최근의 대부분 PC에서는 GPT를 지원하고 있고 BIOS의 개선된 펌웨어인 EFI에서도 GPT를 지원하고 있다. MBR의 한계는 MBR 파트를 통해서도 설명했지만 이를 다시 한번 정리하면 다음과 같다.
- 최대 4개의 primary partition 생성 가능
- 각 파티션 당 최대 2TB의 크기 할당 가능
이러한 한계를 GPT는 다음과 같이 개선하였다.
- 최대 128개의 primary partition 생성 가능
- 각 파티션 당 최대 8ZB의 크기 할당 가능
뿐만 아니라 GPT는 MBR과는 달리 파티션 정보 이외에 디스크에 대한 다양한 정보들도 함께 저장한다는 특징을 가진다.
GPT Structure Overview
GPT를 채용한 저장 장치의 경우 다음과 같은 구조를 가진다. 앞서 MBR 사용 시 구조에서 몇 가지 사항이 추가된 것을 확인할 수 있다.
GPT는 각 부분을 sector(512바이트) 단위로 할당하여 사용한다.
GPT의 본격적인 구조는 Primary GPT Header 부터 이며, 그 전에 위치한 Protective MBR은 GPT를 지원하지 않는 장치에서 파티션을 접근할 수 있도록 하기 위해 사용된다. 뿐만 아니라 MBR 기반의 legacy 디스크에 의해 GPT 영역이 훼손되는 것을 막기 위한 기능으로도 활용된다. 이 Protective MBR의 경우 항상 LBA0의 위치에 존재한다.
GPT 구조의 하단에서 볼 수 있는 Secondary GPT는 Primary GPT에 문제가 생기는 등의 이슈로 Primary GPT를 사용할 수 없을 때 backup 용으로 사용하기 위한 부분이다.
Primary GPT Header
LBA1에 위치한 Primary GPT Header는 Signature 값을 시작으로 각 파티션의 정보만이 아닌 Disk GUID나 파티션 개수, entry 크기 등의 정보를 함께 관리한다.
Primary GPT Header의 세부 구조는 아래와 같다. Primary GPT Header의 크기는 0x5B에 불과하지만 이를 위해 할당된 크기는 0x200이기 때문에 나머지 부분은 0으로 채워져 있다.
Partition Table array
Primary GPT Header의 offset 0x48에 위치한 주소를 참조하면 partition table array의 시작 위치를 찾을 수 있다. 각 entry별로 일정한 크기를 가지고 있어 순차적으로 각 파티션의 정보를 조회할 수 있다.
Partition Table array의 각 entry의 세부 구조는 아래와 같다.
GPT의 이름이 가진 의미를 여기서 확인할 수 있다. GPT는 파티션 유형 별 GUID를 사전에 정해두고 각 파티션에 해당하는 GUID를 entry에 기입한다. 파티션 유형별로 구분짓기 때문에 같은 유형의 서로 다른 파티션이라고 하더라도 Partition Type GUID 필드는 같은 값을 가지게 된다.
물론 GPT에는 Partition Type GUID와는 별도로 각 Partition에 고유한 GUID도 부여한다. 이를 통해 같은 유형의 파티션이라고 하더라도 각각의 파티션을 구분할 수 있게 된다.
Partition type GUID에 기록될 수 있는 유형의 파티션과 이에 매칭되는 GUID는 아래 링크에서 확인할 수 있다.
이외에 Partition Table의 entry 내에 존재하는 Attribute flags라는 필드의 경우, 파티션의 세부 속성을 비트 플래그 형태로 표현하고자 하는 필드이다. 이 필드에서 주로 쓰이는 비트 플래그는 다음과 같다.
Bits | Name | Description |
0 | Platform required | 시스템에 의해 사용되는 파티션. 삭제 또는 수정 시 주의를 요함 |
1 | No Block IO Protocol | UEFI에서 이 파티션에 대한 파일 시스템 매핑 작업을 무시하도록 함. |
2 | Legacy BIOS bootable | |
3-47 | Reserved | 이후 UEFI specification 버전에서 사용될 수 있음을 고려하여 예약된 영역 |
48-63 | Partition type에 따라 다르게 사용 | PartitionTypeGUID의 소유자만이 사용할 수 있도록 할당해둔 영역 |
이 중 Bit 48-63이 일부 type에서 활용되는 예시는 다음과 같다.
Microsoft 사의 Basic Data Partition
Bits | Name |
60 | Read-only |
61 | Shadow copy |
62 | Hidden |
63 | No drive letter (not automount) |
ChromeOS kernel Partition
Bits | Name |
48-51 | Priority 0: not bootable, 1~15(highest) |
52-55 | Tries remaining |
56 | Successful boot flag |
'DFIR > Forensic Artifacts' 카테고리의 다른 글
Windows Prefetch 개요와 File Format (0) | 2023.09.18 |
---|---|
Windows AutoRun program 아티팩트 분석 (Win7/10) (0) | 2023.07.10 |
Windows Registry 개요 및 주요 아티팩트 정리 (0) | 2023.07.09 |
Windows Registry Timezone과 SYSTEM Control registry 백업 원리 분석 (0) | 2023.06.30 |
SQLite record 삭제 체계 분석과 record 복구까지... 하려다 안티포렌식까지 접하게 된 일 (0) | 2022.01.04 |