IT 그리고 정보보안/Knowledge base

FAT (File Allocation Table) 16

plummmm 2021. 4. 10. 06:15
반응형

FAT(File Allocation Table)란 무엇인가

FAT 파일시스템은 1976년 MS에서 개발한 파일시스템이다. 빌 게이츠가 플로피디스크를 관리하기 위해 처음 고안하였는데 이것이 FAT의 시초이다.
이 때만 해도 FAT이 파일시스템으로써의 기능을 하진 않았고, 1980년대에 MS-DOS가 나오면서 운영체제에 탑재되어 FAT12 라는 이름으로 파일시스템의 기능을 하게 된다. 그 이후에 HDD의 사용이 점점 증가하자 MS-DOS 4.0 버전에 처음으로 FAT16 개념이 등장한다. 그러나 2GB가 넘는 HDD를 사용하고자 한다면 어쩔 수 없이 파티션을 나누어야 했다. 그래서 1995년 Windows 95 에서 처음으로 FAT32 가 등장한다.

용량의 한계 때문에 어거지(?)로 계속 확장시키다가.. 이제 OS가 설치된 메인PC에서는 거의 사용하지 않는 파일시스템이 되었다.
물론, 비교적 간단한 시스템 구조로 플래시 메모리, 디지털 카메라 등 수많은 휴대용 기기에서 아직도 사용되고 있다. (FAT32, exFAT)
여전히 휴대용 저장매체에서 FAT 파일시스템을 활용하기 때문에, 포렌식 관점에서 FAT 파일시스템에 대해 공부할 필요성이 존재한다.

FAT 파일시스템은 각 버전(12/16/32) 별로 구조는 대동소이하다.

Reserved Area(예약 영역)은 FAT 파일시스템의 가장 앞 부분에 위치하며, 파일시스템에 대한 각종 정보들이 담겨있다.
FAT Area #1, #2는 클러스터를 관리하기 위한 테이블이 담겨있고 그 백업본이 존재한다.

Data Area(데이터 영역)에는 파일에 대한 메타데이터(디렉토리 엔트리)와 파일 내용이 저장되어 있다.
기본 구조는 위 그림과 같은 형태를 따라가며, 세부적으로 할당된 크기나 내용이 다르다.

FAT16 분석

FAT16의 구조와 세부사항에 대해 알아보자.

포괄적인 FAT 파일시스템 구조

러프하게 나누면 위 그림처럼 구분할 수 있지만 우리는 FAT12 / FAT16 분석을 위해 구조를 알아보는 것이기 때문에 좀 더 디테일하게 알아보자.
FAT12와 FAT16는 클러스트를 표현하는 FAT Entry의 비트 수가 12개에서 16개가 된 것 외에는 동일 므로 FAT16에 대한 내용만 알면 충분하다.

FAT16 파일시스템 전체 구조


FAT16의 구조를 알아보면 위와 같다. 첫번째 그림을 좀 더 디테일하게 분할하면 아래와 같은 영역들이 보인다.
이번 Reserved Area(예약된 영역)과 FAT Area 까지 알아보도록 한다.

1. Reserved Area (예약된 영역) - 1 Sector
예약된 영역은 이름 그대로 미리 예약된 영역이다. 파티션의 가장 첫 부분에 위치하게 된다. VBR도 이 예약된 영역에 속하게 됨 
FAT32 분석에서 다시 언급하겠지만, FAT12/16과 FAT32가 가장 두드러지게 차이나는 부분이 '예약된 영역'이다. 기본적으로 FAT12/16은 1섹터 크기로 할당된다. (FAT32, NTFS는 추가적인 예약 영역을 가지므로 후에 다시 언급하도록 하겠음)
VBR 포스트에서도 언급했지만, 파티션의 가장 첫 부분 한 섹터에 부트섹터(=VBR)가 위치하는데,  FAT12/16의 예약된 영역 크기가 1섹터이다. 그 말인 즉슨 FAT12/16 에선 예약된 영역이 VBR이라는 말이다. 
(그렇기 때문에 내용이 VBR 포스트와 중복되는 부분이 있을 수 있음)

1.1. Jump command to Boot code = CPU Jump command  (0x0000 - 0x0002, 3 byte)
CPU명령 실횅 분기를 부트코드로 옮기는 명령이다. FAT12/16은 [EB 3C 90], FAT32는 [EB 58 90], NTFS는 [EB 52 90] 등 형태가 다양하다. 중간에 위치한 값이 Jump할 부트코드의 Offset 주소이다.

* FAT16 File System Format Disk dump - Jump command to Boot code

위 그림은 내 PC에서 496MB 정도 떼어내어 FAT16으로 포매팅한 파티션 덤프를 뜬 것이다.
MBR 영역에서 LBA주소를 확인하여 섹터로 이동하니 FAT16의 내용이 나왔다..



1.2.  BPB = BIOS Parameter Block  (0x0003 - 0x003D, 59 byte)
바이오스 파라미터 블록.. 여기에는 파티션의 정보들이 포함되어 있다. BPB에 포함된 정보를 참조하여 파일시스템이 부팅과정을 수행하게 된다.
(VBR 포스트에서는 OEM ID와 BPB를 따로 구분했는데, OEM ID만 따로 빼서 설명하기 귀찮아서 ..같이 한다. 사실 큰 의미는 없다..)

* FAT16 File System Format Disk dump - BIOS Parameter Block


BPB에 어떤 내용들이 포함되는지 한번 확인해보자.

Address range size Field Name Description
 0x0003 – 0x000A 8 byte  OEM ID   OEM(Original Equipment Manufacturer) 식별자.
 이 영역을 참조하는 작업은 없음, 단지 OEM을 나타내는 부분
 0x000B – 0x000C 2 byte  Bytes per sector  한 섹터 당 할당되는 byte 크기
 0x000D – 0x000D 1 byte  Sectors per cluster  한 클러스터 당 할당되는 섹터 수
 0x000E – 0x000F 2 byte  Reserved sector count  FAT Area가 나오기 전에 예약된 영역의 섹터 수
 0x0010 – 0x0010 1 byte  Number of FAT  FAT Area의 개수, 통상 #1, #2로 두개 있음
 0x0011 – 0x0012 byte  Root directory entry count   FAT12 / FAT16의 할당된 루트 디렉토리 엔트리 개수
 (FAT32 0으로 세팅)
 0x0013 – 0x0014 byte  Total sector 16   볼륨 상에 있는 총 섹터수
 0x0015 – 0x0015 byte  Media Type  볼륨에 어떤 미디어가 저장되어 있는지 나타냄.
 (
플로피디스크를 제외하고 모두 0xF8)
 0x0016 – 0x0017 byte  FAT size 16   FAT Area의 섹터 수를 나타냄.(FAT32에는 쓰이지 않음)
 0x0018 – 0x0019 byte  Sector per track  트랙 당 섹터 수 
 0x001A – 0x001B byte  Number of heads   헤더 수
 0x001C – 0x001F byte  Hidden sectors  볼륨 앞에 숨겨진 섹터 수
 0x0020 – 0x0023 byte  Total sector32  볼륨 상에 있는 총 섹터수
 (Total sector 16에서 표현이 불가능하면 이 필드를 쓰는듯..)
 0x0024 – 0x0024 byte  INT 0x13 drive number   x86 계열에서 사용하는 INT 0x13 사용시 필요한 필드
 (Floppy=0x00, Hard Drvie=0x80)
 0x0025 – 0x0025 byte  Reserved  사용하지 않는 예약 영역
 0x0026 – 0x0026 byte  Boot signature  확장 부트 서명
 0x0027 – 0x002A byte  Volume serial number  해당 볼륨의 고유 시리얼 번호가 기록됨
 0x002B – 0x0035 11 byte  Volume label  윈도우에서의 해당 볼륨 레이블
 0x0036 – 0x003D byte  File system type  파일시스템 형식
BIOS Parameter Block Total 0x0003 - 0x003D (Size : 59 byte)

여기까지 BPB(BIOS Parameter Block)의 각 필드들이 의미하는 내용들이다. FAT32와 중복되는 부분이 많지만 내용이 헷갈릴 수 있어서 그냥 일단 FAT32 내용은 제외시켰다. 이제 BPB 다음 영역 부터는 부트코드 에러메시지가 자리한다. 그 뒤에는 어김없이 Signature 0x55 0xAA가 위치함.

Address range size Field Name Description
 0x003E – 0x01FD 447 byte  Boot code Error massage 부트코드 에러 메세지
 0x01FE – 0x01FF 2 byte  Signature 서명 0x55 0xAA

여기까지 예약된 영역을 알아보았다. 이제 FAT Area가 나올 차례인데, 위 표에서 Reserved sector count 필드 할당된 값만큼의 섹터를 건너 뛰어야 FAT Area가 나타난다. 위 파티션 덤프 화면에서는 해당 필드가 0x06 0x00 (= 6) 이므로 현재 Reserved Area의 1섹터 포함해서 5개 섹터를 건너뛰면 된다.

2. FAT(File Allocation Table) Area #1, #2 - "FAT size 16"필드 참조 
FAT 영역을 한번 알아봅시다. FAT 파일시스템으로 불리는 이유가 이 FAT 영역에 의해 영역이 관리되기 때문에 그 이름을 따서 FAT 파일시스템이라 불리는 것이다. FAT 영역은 두가지로 나뉘는데, FAT영역 하나와 그 영역의 백업본으로 구성돼있다. 똑같은 값을 가진 두 영역이 존재한다.
실제 파일시스템에 저장돼 있는 파일 데이터들의 클러스터 관련 정보가 들어있는 중요한 영역으로 백업을 해두어야 하는 것임
FAT 영역을 찾는 방법은 간단하다. BPB 필드 중 "Reserved Sector count" 필드를 확인하면 된다. 위 예제 캡쳐화면에서 0x0006 으로 세팅돼 있으므로 시작지점에서 +6 sector 하게 되면 바로 FAT영역이 등장한다.

FAT 영역의 크기는 예약된 영역의 " FAT size 16 " 필드에서 확인이 가능하다. (예제 덤프에서는 0x00F9 = 249 Sector) 
파일시스템의 구조와 각 영역들의 위치와 찾는 방법을 익혀야 하는 이유는.. 분석을 해야하는데 내가 사용하는 Tool 사용이 제한되는 경우가 발생하기때문이다.

이 영역에는 후에 나오는 데이터 영역(실제 데이터 클러스터들이 존재하는 영역)에 할당된 클러스터들의 상태를 표시한다. FAT16은 각 클러스터의 할당정보를 16bit(=2byte) 크기로 사용해 나타낸다.(FAT12는 12 bit를 사용하겠죠) 특별한 구조체가 있는게 아니고, 클러스터들을 관리하는 테이블이 열거돼있는 형태다.
해당 테이블들은 클러스터를 Linked List 형태로 관리한다.

* FAT16 File System Format Disk dump - FAT Area

위 그림 내용을 한번 보겠다. FAT Area 에서는 처음 2개의 엔트리에 특별한 값을 저장하고 그 뒤에 클러스터를 관리하는 테이블들이 나열돼있다.

* FAT Area Layout

위 그림은 FAT32의 FAT Area 레이아웃이다. FAT Area의 각 항목들은 FAT Entry 라고 부르며, 위 그림은 FAT32 기준으로 작성되었다.
어차피 FAT12, 16, 32 모두 해당 영역은 동일한 구조를 가지므로 그림만 참고하면 될 듯하다. (FAT Entry 크기 : FAT12는 12 bit, FAT16는 16 bit, FAT32는 32 bit

먼저 최초 2 byte(첫번째 엔트리)는 media type 이다. 위 파티션 덤프 화면에는 0xF8 0xFF 로 나와있는데, 0xF8은 하드디스크일 경우에 설정되고 만약 플로피디스크에 FAT 파일시스템이 적용돼 있다면 0xF0가 된다.
그 다음 두번째 엔트리에는 Partiton state 즉, 파티션의 상태를 나타내는 값들이 설정된다. 운영체제 종류별로 해당 엔트리에 들어가는 값이 다르지만
통상 0xFF 0xFF 값이 세팅되어 있다. Media type, Partition state 필드는 사실 분석할 때 크게 고려하는 부분이 아니므로, "FAT Area의 최초 2개의 엔트리는 예약된 것이다." 라고 생각하면 정신건강에 이롭다.

그 이후 영역들은 앞서 설명한 것과 같이 파일들이 할당되어 있는 클러스터 관리 테이블들이다.
Data Area에 존재하는 실제 파일 데이터들은 이 FAT Area에 있는 관리 테이블이 없다면 그저 바이너리 덩어리가 되어버리는 것이다.
하지만 반대로 FAT Area이 지워지고 Data Area에 파일 데이터들은 온전히 보존된다면, 복구의 실마리가 남아있다. (이 내용은 추후에 다루도록 하겠음)

위 표 내용대로 해당 값들을 맞추어보면 쉽게 FAT Area 분석이 가능하다. 가령, 0x0002 - 0xFFEF 사이의 값은 모두 해당 파일의 다음 클러스트의 위치를 가르키는 값이고 0x0000은 비어있는 클러스터, 0xFFF8 - 0xFFFF 값은 Last cluster in file 즉, 이 위치에 해당하는 파일은 1클러스터만큼의 크기만 할당된 것이다. 
FAT Area는 파일시스템 전체의 클러스터들을 순차적으로 나열시켜, 각 파일들에 할당된 클러스터의 갯수를 파악할 수 있게 해주는 것이다.

 

'예약된 영역', 'FAT 영역' 두가지를 알아보았는데, 이번에 나머지 하나 남은 Data 영역에 대해 알아보겠음
Data Area (데이터 영역) 부터 구조 파악을 해봄... FAT 영역이 끝나고 나면 곧바로 Data 영역이 나타난다. 


(예약된 영역의 ("FAT size 16"에 할당된 값 * 2) 만큼의 섹터를 이동하면 Data 영역이 나타난다)

3. Data Area (데이터 영역) 
데이터 영역은 FAT16 파티셔닝된 볼륨의 대부분을 차지하는 영역이다. 이름 그대로 데이터들이 저장되는 곳이며 Cluster(클러스터) 단위로 구성되어 있다.
지금까지 알아보았던 여타 하드디스크의 영역들이 Sector(섹터) 단위로 할당하는 것과 다르게 클러스터 단위로 할당한다. 빠른 읽기/쓰기를 위해서 인듯 하다.
데이터의 저장형식은 파일과 디렉토리 2가지 형태로 구분되는데, 디렉토리에는 파일, 하위 디렉토리에 대한 정보가 담겨있고 파일에는 오로지 파일내용(바이너리)만 담겨있다.  대부분의 파일시스템과 마찬가지로 FAT16 또한 디렉토리 관리에 트리구조를 사용한다. 그 디렉토리 트리의 최상단에 위치한 녀석이 루트 디렉토리이다. FAT32의 경우 데이터 영역 아무데나 루트 디렉토리를 위치시킬 수 있지만, FAT16의 경우 무조건 FAT영역 #2 바로 뒤에 위치해야 한다.
FAT32도 별도로 지정하지 않는 한 FAT영역 #2 뒤에 위치하긴 한다. 다만, FAT16 처럼 위치를 고정시켜 놓을 시에 루트 디렉토리의 위치는 금방 찾을 수 있지만 디렉토리 갯수 제한(최대 32개 섹터 사용가능) 등의 단점이 발생하여 FAT32에서 위치 변경이 가능하도록 바뀌었다고 한다.
서브 디렉토리는 루트 디렉토리의 하위 레벨 디렉토리이다. 구조 자체가 동일하기 때문에 크게 분리시켜놓고 이해할 필요는 없어 보인다.

FAT16의 루트 디렉토리의 갯수 제한은 512개이다. (최대 크기가 32 Sector(=16,384 byte) / Directory Entry size (32 byte) = 512개)
해당 값은 예약된 영역의 " Root directory entry count " 필드에서 확인이 가능하다. 통상 0x00 0x02 (=512)로 세팅돼있다.
FAT 영역 #2 끝에서부터  + 32 Sector 만큼은 루트 디렉토리 엔트리가 들어올 자리라는 것이다. 반면 서브 디렉토리는 개수 제한이 없다. 
여기에는 파티션의 최상위 디렉토리에 존재하는 파일 및 디렉토리가 존재한다. (e.g. C:\ 또는 D:\ 등)
만약 루트디렉토리에 존재하는 것이 디렉토리라면, 별도로 서브 디렉토리 영역을 가지게 된다.

일단, 내용에 들어가기 전에 전체 구성을 한번 보자. 이전 포스팅의 그림 한번 재탕하겠음

FAT16 File System Layout

 

데이터 영역은 Root Directory (루트 디렉토리), 파일데이터 저장영역, Sub Directory (서브 디렉토리), Unallocated Area (비할당 영역)으로 구성된다.
순서대로 각 영역에 대해 한번 알아보자. 분석 관점에서 중요도가 낮은 부분들은 간략하게 설명하고 넘어가겠다.

3.1. Root Directory (루트 디렉토리) / Sub Directory (서브 디렉토리)
데이터 영역에서 가장 먼저 등장하는 루트 디렉토리, 그리고 서브 디렉토리가 무엇인지 알아보자.
Directory Entry(디렉토리 엔트리) 라는 구조체로 이루어진 이 두 영역은 FAT16 파티션에 저장되어 있는 파일과 디렉토리에 대한 (Meta Data)메타데이터가 들어있는 영역이다. 파일 또는 디렉토리의 이름, 확장자, 생성 날짜/시간, 최종 실행 날짜, 최종 수정 날짜/시간, 할당된 클러스터 시작 위치 등과 같은 정보가 담겨있다.
모든 정보들은 디렉토리 엔트리 구조체의 Offset 값으로 설정되어 있다.

FAT16 File System Directory Entry layout

 

필드별로 내용을 한번 알아보자.

FAT16 File System Directory Entry - File name

0x00 - 0x07 (8 byte)는 파일이름이 있는 필드이다.  보통 ASCII 코드값이 들어있지만 특수한 값들이 존재한다.
아래 값들이 0x00 offset에 세팅되어 있는 경우가 있다. 내용을 알아보자.
 ㄴ 0x00 : 파일이름이 사용된적이 없음
 ㄴ 0xe5 : 파일이 이미 삭제되었지만 파일 이름은 확인이 가능한 상태
 ㄴ 0x05 : 파일명의 첫번째 문자가 ' σ ' 인 경우 (ASCII code value = 0xe5)

파일 이름 길이가 8 byte 미만인 경우, 위 예제 화면과 같이 0x20 으로 패딩 문자가 채워진다.
그리고 8 byte를 초과하는 경우에는  6 byte 까지 채우고 뒤에 '~1'을 붙인다. (이 부분은 뒤에 자세히 설명함)

FAT16 File System Directory Entry - File Extension

0x08 - 0x0A (3 byte)는 파일 확장자가 들어있는 필드이다. 특별히 설명할 내용 없다.

FAT16 File System Directory Entry - File Attribute


0x0B (1 byte)는 파일의 속성값이다. 해당 offset에 세팅되는 값에 따라 어떤 내용을 가르키는지 알아보자.
 ㄴ 0x01 : 읽기 전용 파일이다.
 ㄴ 0x02 : 숨김  파일이다.
 ㄴ 0x04 : 운영체제 시스템 파일이다.
 ㄴ 0x08 : 속성값 대신 디스크 볼륨 레이블을 포함한 엔트리임을 나타냄 (루트 디렉토리에서만 나타남)
 ㄴ 0x10 : 서브 디렉토리를 가짐 (= 디렉토리 파일임)
 ㄴ 0x20 : 일반 파일

FAT16 File System Directory Entry - Reserved


0x0C - 0x15 (10 byte)는 예약된 영역이다. 

FAT16 File System Directory Entry - Time Created of last updated


0x16 - 0x17 (2 byte)는 파일이 생성되거나 마지막으로 수정된 시간이 기록되는 필드이다.
<------------ 0x17 -------------> <------------ 0x16 ------------->
15 14 13 12 11  /  10 09 08 07 06 05  /  04 03 02 01 00
 h   h   h   h   h    m  m  m  m  m  m     x   x   x   x   x  
(h:시, m:분, x:초)

해당 필드의 값들을 이진수로 변환하여 나열하고, 각 필드에 값들을 읽으면 된다.
예시로, 위 캡쳐화면의 0x7CF6은 이진수로 변환하면 [ 0111 1100 1111 0110] 이다. 이진수로 변환한 값에서 '시'를 나타내는 부분은 01111 (=15시), '분'을 나타내는 부분은 100111, '초'를 나타내는 부분은  10110 이다. 해당 값을 십진수로 다시 변환하면 15시 39분 26초가 됨

FAT16 File System Directory Entry - Date Created of last updated


0x18 - 0x19 (2 byte)는 파일이 생성되거나 마지막으로 수정된 날짜가 기록되는 필드이다.

<------------ 0x19 -------------> <------------ 0x18 ------------->
15 14 13 12 11 10  /  09 08 07 06  /  05 04 03 02 01 00
 y    y    y    y    y    y      m  m  m  m       d   d   d   d   d   d  
(y:년도, m: 월, d:일)
마찬가지로 위 0x18 - 0x19 필드를 이진수로 나열하고 값들을 읽는다.
예시로  0x4A9B는 이진수로 변환하면 [ 0100 1010 1001 1011 ] 이다. 해당 값들을 십진수로 변환하여 년, 월, 일에 대입하면 37년 4월 27일이 나온다.
년도가 이상한데, FAT16은 해당값에 1980을 더하면 된다. 그러면 2017년 4월 27일이 됨

FAT16 File System Directory Entry - Starting Cluster # for file


0x1A - 0x1B (2 byte)에는 할당된 클러스터의 시작위치가 설정돼 있다.
0x0015 로 설정돼 있으면 해당 파일은 21번째 클러스터에 있는 것이다. 그럼 섹터 단위로 나누어져 해당 파일의 클러스터에 접근하려면 어떻게 해야할까.
먼저, 클러스터는 FAT 영역이 끝나고 데이터영역 부터 시작된다. (그 전에 예약된 영역, FAT 영역은 클러스터 계산하지 않음)
계산을 해보면 이렇다.
(클러스터 위치) * (한 클러스터 크기 in byte)  / (한 섹터 크기 in byte) + (데이터 영역 이전까지의 섹터수)
(21*8192)/512 + 504 = 840
계산해보면 840번 섹터에 파일이 위치한다. 실제로 해보면 정확히 떨어진다.

FAT16 File System Directory Entry - File size in byte


0x0C - 0x0F (4 byte)는 파일의 크기를 나타낸다.


이상 디렉토리 엔트리의 각 필드들이 의미하는 값들을 알아보았다. 이번에는 디렉토리 영역이 어떻게 구성되어 있는지 한번 알아보자.
FAT16에서 루트디렉토리는 FAT영역이 모두 끝난 바로 다음섹터에 위치한다. 그 뒤론 동일하게 디렉토리 엔트리 구조에 따른 파일들의 내용이 위치한다.

FAT16 Root Directory dump


먼저 위 캡쳐화면은 FAT16 파티션 샘플의 루트 디렉토리의 가장 처음 부분이다.
루트 디렉토리든, 서브 디렉토리든.. 디렉토리 영역의 모든 내용들은 방금 알아본 Directory Entry(디렉토리 엔트리) 구조를 따른다.
루트 디렉토리의 첫 부분에는 볼륨 이름이 나온다 (샘플 이름이 TEST_FAT16 이다.)

3.2.  Unallocated Area (비할당 영역)
비할당 영역은 디렉토리 엔트리 정보가 사라지고 파일 데이터만 남아있는 공간을 뜻한다. 이 곳에는 주로 포맷 이전의 데이터, 디렉토리 엔트리 정보 즉 메타데이터가 사라진 데이터들이 남아있다. FAT 영역에서 0x00의 값을 갖는 클러스터가 비할당 클러스터인데, 이 부분들을 순차적으로 연결하면 데이터 카빙이 가능하다.

 

 

 

# 참고 URL
http://forensic.korea.ac.kr/DFWIKI/index.php/%ED%8C%8C%EC%9D%BC%EC%8B%9C%EC%8A%A4%ED%85%9C
http://www.hanbit.co.kr/media/channel/view.html?cms_code=CMS5057501235&cate_cd=
http://hyd3.tistory.com/125

http://forensic-proof.com/archives/372
https://m.blog.naver.com/PostView.nhn?blogId=bitnang&logNo=70184195032&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system
http://hyd3.tistory.com/125
http://forensic.korea.ac.kr/DFWIKI/index.php/%EA%B5%AC%EC%A1%B0%EB%B6%84%EC%84%9D/FAT


# 참고 도서
<파일시스템 포렌식 분석> - 저자 : 브라이언 캐리어

<START UP 디스크 포렌식> - 저자 : 이별

반응형