FAT(File Allocation Table) 파일 시스템은 MS-DOS 파일 시스템 중 하나로, 크게 FAT12 / FAT16 / FAT32 등으로 나눌 수 있습니다. FAT 뒤의 숫자는 '클러스터 번호의 비트'와 같기 때문에 종류 별로 파일 시스템에서 관리하는 '최대 클러스터의 개수'가 달라집니다.
예를 들어, FAT12는 FAT 뒤에 '12'가 붙었기 때문에 클러스터 번호를 12비트로 표현합니다. 여기에 미리 예약된 클러스터가 12개 있기 때문에 최대 4,084(2^12 - 12 = 4096 - 12 = 4084)개의 클러스터를 관리/표현할 수 있습니다. 같은 원리로 FAT16과 FAT32도 클러스터 번호를 각각 16비트 / 32비트로 표현하기 때문에 최대 2^16 / 2^32 개에서 예약된 영역을 제외하면 관리할 수 있는 최대 클러스터 개수를 구할 수 있습니다.

FAT 파일 시스템의 구조는 크게 3가지 영역으로 나뉩니다. FAT 내에서도 종류에 따라 각 영역이 가지는 크기, 오프셋이 다르지만 공통적으로 Reserved Area, FAT Area, Data Area를 가집니다.

그럼 Reserved Area부터 하나씩 공부해봅시다. FAT32를 위주로 설명할 것이기 때문에 중간 중간 FAT32로 포맷되어있는 'Vol32' 파티션의 헥스값을 볼 텐데, 해당 파티션은 다음과 같이 세팅되었습니다.
https://hec-ker.tistory.com/267
Reserved Area
Reserved Area는 파일 시스템 구조에서 가장 앞에 위치하며, Reserved Area의 크기는 가변적입니다. 일반적으로 FAT32는 첫 32개의 섹터가 Reserved Area로 사용(FAT12 / FAT16은 1개 섹터)되는데, 그 중에서도 0번, 1번, 2번, 6번, 7번, 8번 섹터에는 어떤 데이터를 담을 지 미리 정해져있습니다.

이렇게 0번과 6번은 Boot Sector, 1번과 7번은 FSINFO, 2번과 8번은 Boot Strap에 관련한 내용을 저장합니다.
Reserved Area - Boot Sector (0번 섹터, 6번 섹터)
FAT32의 Reserved Area인 첫 32개의 섹터 중 첫 섹터인 0번 섹터를 'Boot Sector'라고 부릅니다. 'Boot Sector'라고 불리는 이유는 이 섹터가 'Boot Code'를 포함하고 있기 때문입니다. 6번 섹터는 이 Boot Sector의 백업본입니다. 즉 아래에서 설명하는 모든 구조가 6번 섹터에서도 동일합니다.

▧ Jump command to Boot Code, 0x0000 ~ 0x0002

Boot Sector의 처음 3 bytes는 Boot Code로 점프하기 위한 Jump command가 위치합니다. 즉, Boot Code는 Jump command에 의해 실행되고 이 때 BPB를 참조하여 File System이 부팅됩니다.
이 Jump command to Boot Code 값은 파일 시스템 마다 값이 다릅니다.

▧ BPB (BIOS Parameter Block), 0x0003 ~ 0x0059

BPB는 FAT32 기준 총 87 bytes(OEM ID를 제외하면 79 bytes)입니다. 위에서 설명드린 것처럼 Boot Code는 이 BPB를 참조하여 부팅을 준비하고, 부팅에 실패하면 에러 메세지를 띄웁니다.
전체적인 BPB의 구조는 다음과 같습니다.


이 중 몇 가지만 골라 자세히 설명하겠습니다.
▧ BPB (BIOS Parameter Block) - OEM ID (0x03 ~ 0x0A)
사실 이 부분을 BPB에 포함시키느냐 마느냐에 대해서는.. 여러 블로그나 책을 참조했을 때 글 쓴 사람마다 다르게 분류하는 것 같습니다. 개인적으로는 포함되지 않는다고 생각하지만 확실치 않아 일단 포함시켜 설명드립니다. BPB 영역 첫 8 bytes에는 OEM ID가 옵니다. 이 파일 시스템은 FAT32이기 때문에 'MSDOS5.0'이라는 문자열이 보입니다.

즉 파일 시스템의 종류를 대강 알려주는 곳입니다. 아래와 같이 파일 시스템 종류에 따라 OEM ID 영역에 오는 값이 다릅니다.

▧ BPB (BIOS Parameter Block) - Reserved Sector Count (0x0E ~ 0x0F)
이 부분은 FAT32의 예약 영역 크기를 나타냅니다. 포맷 소프트웨어에 따라 예약 영역의 크기가 조금씩 차이가 나기 때문에 기본적인 윈도우즈 포맷 방법을 사용해도 기본값이 아닐 수 있습니다. 따라서 이 부분을 꼭 확인하여 예약된 섹터 값을 확인해야 합니다. 또 이 부분은 FAT Area의 시작 위치를 알려주기도 합니다.

▧ BPB (BIOS Parameter Block) - FSINFO offset (0x30 ~ 0x31)
FSINFO 구조체는 OS에게 미할당된 클러스터의 첫 위치와 전체 미할당 클러스터의 수를 알려주어, 새로 저장할 데이터의 할당을 빠르게 할 수 있도록 합니다. 이 부분은 FSINFO 구조체의 오프셋을 저장하는 곳으로 기본적으로 1번 섹터에 저장되어 있고 백업은 7번 섹터에 있습니다. 하지만 이 부분을 통해 임의로 변경 가능합니다.

▧ BPB (BIOS Parameter Block) - Backup boot sector offset (0x32 ~ 0x33)
Backup boot sector는 부팅을 위한 0번 섹터인 부트 섹터의 백업용 섹터입니다. 기본적으로 6번 섹터임을 위에서 설명드렸습니다. 역시 이 부분을 통해 임의로 변경 가능합니다.

▧ BPB (BIOS Parameter Block) - Signature (0x01FE ~ 0x01FF)
부트 섹터의 마지막 2bytes는 부트 섹터의 시그니처를 나타내는 부분으로, "55 AA"라는 16진수 값을 볼 수 있습니다. 이 시그니처를 마지막으로 섹터가 끝납니다.

Reserved Area - FSINFO (1번 섹터, 7번 섹터), Boot Strap (2번 섹터, 8번 섹터)
FAT32의 Reserved Area 중 1번과 7번 섹터는 'FSINFO' 영역입니다. 역시 7번 섹터는 1번 섹터의 백업용이며 이 곳은 미할 당 클러스터에 관련한 정보를 OS에게 알려주어 빠른 데이터 할당을 돕습니다.

▧ Signature, 0x0000 ~ 0x0003
FSINFO 구조체의 시작을 나타내는 시그니처는 4 bytes의 "RRaA"입니다. 이 구조체에는 시그니처가 총 3번 등장합니다.

▧ Signature, 0x01E4 ~ 0x01E7
FSINFO 구조체가 끝나기 전, 두 번째 시그니처가 등장합니다. 첫 시그니처인 "RRaA"의 대/소문자를 뒤집은 "rrAa"입니다. 역시 4 bytes입니다.

▧ Number of free cluster, 0x01E8 ~ 0x01EB
다음 4 bytes는 사용 가능한 클러스터 수를 나타냅니다.

0x0003E3D7은 10진수로 254,935입니다. 한 클러스터는 8개의 섹터로 이루어져 있고, 1개의 섹터는 512 바이트입니다. 따라서 254,935 클러스터 = 2,039,480 섹터 = 1,044,213,760 바이트. 실제 해당 파티션의 사용 가능 공간과 일치합니다.

▧ Next free cluster, 0x01EC ~ 0x01EF
다음 4 bytes는 사용 가능한 클러스터의 시작 위치를 나타내줍니다.

▧ Signature, 0x01FE ~ 0x01FF
FSINFO의 마지막 시그니처는 마지막 4 bytes에 위치합니다. 부트 섹터와 같은 "55 AA" 값을 가집니다.

▧ BootStrap
BootStrap은 2번 섹터와 8번 섹터 영역입니다. 이 곳은 부트 섹터의 부트 코드 영역이 부족할 경우, 추가적으로 사용할 수 있도록 존재하는 영역입니다. 따라서 추가적 작업이 필요하지 않을 경우 보통 비어있습니다. 그래서 이 부분에 데이터가 존재한다면 은닉된 데이터일 가능성도 있습니다.
FAT Area
FAT(File Allocation Table) Area는 데이터 영역의 클러스터 할당 상태를 표시합니다. 파일 시스템 종류에서 "FAT" 뒤에 붙은 숫자를 기준으로 할당 상태를 표시하므로, FAT32는 32 bits(= 4 bytes)로 데이터 영역의 시작 클러스터부터 마지막 클러스터까지의 할당 상태를 표시합니다.
FAT Area는 일반적으로 2개입니다. 각각을 FAT Area #1, #2라고 했을 때 #2는 #1을 위한 백업용입니다.

FAT Area - FAT Area의 위치와 크기 찾기
FAT Area가 어디에 있는지 한 FAT Area의 크기가 무엇인지는 위에서 언급한 Reserved Area의 BPB에서 찾을 수 있습니다. 아래 두개의 부분이 그것입니다.
첫 번째는 Offset 0x0E ~ 0x0F입니다. 이 곳은 BPB의 Reserved sector count였습니다. 즉 예약된 영역의 크기를 나타냅니다. 0x106E는 10진수로 4,206으로, 4,206 섹터가 FAT Area의 시작이라고 볼 수 있습니다.

4,206번 섹터에 가보면 FAT Area가 있네요.

다음으로는 크기를 찾을 것입니다. 아래 하이라이트된 영역은 BPB의 FAT32 Size입니다. 0x07C9는 10진수로 1,993입니다. 즉 FAT Area #2의 시작 위치는 'FAT Area #1의 시작 위치인 4,206번 섹터 + FAT Area의 길이인 1,993번 섹터 = 6,199 번 섹터'임을 알 수 있습니다.

6,199번 섹터에서 FAT Area #2 역시 발견할 수 있습니다.

FAT Area Structure
위에서 FAT32 파일 시스템은 4 bytes로 클러스터의 할당 유무를 표시한다고 하였습니다. 이 4 bytes를 'FAT Entry(또는 클러스터 번호)'라고 하며, FAT32에서는 한 섹터 당 128개의 FAT Entry를 표현할 수 있습니다. 각 FAT Entry는 Data Area의 클러스터와 대응됩니다. 하지만 FAT Entry 0번부터 대응되는 것은 아닙니다.
▧ Media Type 0x00 ~ 0x03, Partition Status 0x04 ~ 0x07
아래와 같이 FAT Area의 첫 4 bytes와 그 다음 4 btyes, 총 8 bytes는 예약된 영역입니다. 각각 FAT Entry 0번은 Media Type, FAT Entry 1번은 Partitinon Status를 나타냅니다. 그리고 FAT Entry 2번부터 실제 Data Area의 클러스터와 대응됩니다. 즉, FAT Entry 2번부터 Data Area의 각 클러스터가 사용되고 있는지의 유무와 특정 파일이 점유하고 있는 클러스터의 위치를 나타냅니다.

▧ 각 4 bytes, FAT Entry #2(Cluster num. #2) ~
FAT Entry 2번부터는 대응되는 Data Area의 클러스터가 할당 클러스터인지, 미할당 클러스터인지, 배드 섹터가 포함된 클러스터인지에 따라 다른 값을 갖게 됩니다. 값은 아래와 같습니다.

▧ 각 4 bytes, FAT Entry #2(Cluster num. #2) - "0x0FFF FFFF"
아래에서의 FAT Entry 2번, 3번, 4번, 5번의 값은 0x0FFF FFFF이므로 해당 클러스터를 사용하는 파일은 하나의 클러스터만 사용하는 것을 알 수 있습니다. 즉 해당 영역의 1개 파일 크기는 1개의 클러스터 크기보다 작다는 뜻입니다.

▧ 각 4 bytes, FAT Entry #2(Cluster num. #2) - "0x?000 0002 ~ 0x?FFF FFEF", "0x0FFF FFFF"
아래의 FAT Entry 6번부터 할당된 파일은 6번 ~ 12번 클러스터까지 총 7개의 클러스터를 사용하는 파일임을 알 수 있습니다.

이렇게 FAT Entry를 통해 Data Area의 클러스터 정보를 대략 알 수 있습니다. 더욱 자세한 정보는 Data Area에서 볼 수 있습니다.
Data Area
트리 형태로 표현되는 FAT 파일 시스템에서, 가장 중요한 요소는 최상위의 Root Directory입니다. FAT12 / FAT16은 Directory Entry의 크기가 32 bytes이므로 최대 512개의 Entry를 나타낼 수 있습니다. 즉, Root Directory 내에 최대 512개의 파일 및 디렉터리를 생성할 수 있습니다. 하지만 FAT32에서는 Root Directory에 생성할 수 있는 파일, 디렉터리의 개수 제한은 없어졌습니다.
Data Area - Root Directory의 위치 찾기
FAT32의 Root Directory는 DATA Area의 어느 곳에나 올 수 있지만 기본적으로 FAT Area가 끝난 바로 다음에 옵니다. (FAT12 / FAT16은 항상 FAT Area 바로 뒤, Data Area의 첫 부분에 옵니다.) 만약 임의로 Root Directory의 위치를 변경한다고 해도 BPB의 Root Directory Cluster Offset (0x2C ~ 0x2F)에서 찾을 수 있습니다. 현재 값은 기본값인 FAT Entry 2번입니다.

Data Area Structure
Data Area에 저장되는 데이터는 크게 디렉터리 및 파일로 나뉩니다. 디렉터리는 디렉터리 내부에 포함되는 하위 디렉터리와 파일 이름, 확장자, 시간 정보, 크기 등을 표현하기 위해 Directory Entry라는 구조를 사용합니다.


▧ Data Area - File Name or Status, 0x0000
Directory Entry의 첫 바이트는 파일 이름이나 상태를 나타내기 위해 사용됩니다. 이 때 첫 바이트가 0xE5이면, 해당 Entry는 삭제되었다는 뜻입니다. 파일이 삭제될 경우 FAT 영역에서 파일에 할당되었던 클러스터에 대응되는 FAT Entry 값을 0x00으로 초기화하고, 해당 파일의 정보가 담긴 Director Entry의 첫 바이트를 0x05로 표시합니다. 말 그대로 첫 바이트 값만 변경되므로 파일의 정보와 내용 복구가 가능합니다.
첫 바이트가 0x00이면, 이 Entry는 사용되지 않습니다. 새로운 파일을 저장할 때 파일이 위치한 디렉터리에서 삭제된 Directory Entry를 찾고, 삭제된 Directory Entry가 없을 땐 사용되지 않은 Directory Entry에 파일 정보를 기록합니다. 이 때 기록되는 0x00 으로 표현된 Directory Entry는 가장 마지막 Entry이므로 그 이상은 검색할 필요가 없습니다.
▧ Data Area - Attributes, 0x000B
0x000B 부분은 Directory Entry의 속성을 나타냅니다. 이 속성값에 따라 해당 디렉터리 또는 파일의 자세한 정보를 얻을 수 있습니다.

위 표에서 0x0F라는 값을 가지면 'Long File Name'이라는 속성을 뜻합니다. 이는, File Name을 표현하기 위해 할당된 8 bytes를 넘어, 8 bytes 이상의 크기로 File Name을 표현해야 할 때, 즉 Long File Name일 때를 의미합니다.
이 구조를 SFN & LFN 이라고 하는데, 이에 대해서는 따로 포스팅하겠습니다.
'Forensics' 카테고리의 다른 글
$MFT로 파일의 절대 경로 찾기 (0) | 2021.03.28 |
---|---|
Fixup Array Structure Analysis (0) | 2021.03.14 |
$MFT Structure Analysis (0) | 2021.02.28 |
FAT32 포맷 VOL32 파티션 세팅 (0) | 2021.02.20 |
정보보안 SUA - [디포] "1주차 과제" (0) | 2021.02.06 |