본문 바로가기

Security/Forensic (practice)

[File System] FAT 32 이론 및 수동 분석

1. 실습 환경


Version
Host PCWindows 7 64bit
Guest PCWindows xp sp2
Hex Editor
HxD
Perl Coding
Edit Plus3

[표 1-1] 실습 환경

2. FAT 32 개요

File Allocation Table 이라는 파일 시스템으로 Windows 기반의 주로 작은 용량의 HDD에서 사용되었던 간단한 파일 시스템이다. 
하지만 현재는 NTFS 등이 등장하면서 FAT 파일 시스템은 USB 등의 이동식 저장 장치 등과 같은 용량이 작은 장치의 파일 시스템으로 사용이 되고 있다.

3. FAT 32 구조

[그림 3-1] FAT 32 구조


- Boot Record : 1 Sector, Boot Record는 볼륨의 첫 번째 섹터이자 Reserved Area의 첫 번째 섹터이다.
   이 영역에는 부팅하기 위한 Boot Code와 함께 FAT 파일 시스템의 값들이 저장되어 있으며 BIOS Parameter       
   Block(BPB)라고도 한다.
- Reserved Area : 32 Sector(이중 맨처음 1 Sector는 Boot Record), 나중을 위해 비워둔 예약된 공간이다.
- FAT #1 / FAT #2 : 클러스터를 관리하기 위한 테이블이 모여 있는 공간으로 이 공간은 HDD 내의 파일들과 연결된 
   클러스터에 대한 정보들이 있으므로 만약 손상이 되면 해당 파일을 사용할 수 없게 된다.
   이 때문에 FAT #1과 동일한 정보를 FAT #2에 백업하여 두게 된다.
- Root Directory : Data Area 내의 아무 곳에나 존재해도 관계 없으며 그 위치를 Boot Record에 기록하게 된다.
  하지만 FAT 32 이전의 파일 시스템 즉 FAT 16등에는 FAT 영역 바로 다음에 Root Directory 가 존재하였으므로 
  일반적으로는 FAT 32에서 역시 FAT 영역 바로 뒤에 둔다.
- Data Area : 파일 또는 디렉토리가 저장되어있는 영역으로 이전 영역과의 차이는 이전 영역의 경우 Sector 단위로 
   읽기 쓰기를 하지만 Data Area의 경우 Cluster 단위로 읽기와 쓰기를 진행한다.

4. FAT 32 분석
(1) Boot Record


[그림 4-1] Boot Record 구조


FAT 32의 구조는 [그림 4-1]과 같으며 36 Bytes 는 FAT 16 과 공통 적인 부분이며 FAT 32 에만 포함되는 영역은 그 이후에 존재한다.
- Jump Boot Code : Boot Code 로 점프하기 위한 코드
- OEM Name : OEM 회사를 나타내는 문자열이 들어있음
- Bytes per Sector : 한 개 섹터를 구성하는 바이트 수
- Sector per Cluster : 한 개 클러스터를 구성하는 섹터 수
  => Sector Per Cluster * Bytes Per Sector = Cluster 의 크기
- Reserved Sector Count : [그림 3-1]의 Reserved Area 의 섹터 개수
- Number of FATs : 해당 볼륨에 존재하는 FAT 영역의 개수
- Root Directory Entry Count : Root Directory 내에 몇 개의 파일/디렉토리를 수용할지에 대해 기록하는 항목으로 
  반드시 Bytes Per Sector의 짝배수로 구성이 되어야 한다.
  하지만 FAT 32에서는 반드시 0으로 채워져야한다.
- Total Sector 16 : FAT 16에 해당되는 항목으로 FAT 32에서는 0으로 채워진다.
- Media : 해당 볼륨에 어떤 미디어가 저장되어있는지 기록되며 플로피 디스크를 제외한 모든 장치의 경우 0xF8로 
   기록이 된다.
- FAT Size 16 : FAT 영역의 섹터 수를 저장하는 부분으로 FAT 32에서는 0으로 채워진다.
- Sector Per Track : Track 당 Sector의 개수를 의미하는데 Window 계열에서는 더이상 이 값을 참조하지 않는다.
- Number Of Heads : 해당 저장 장치의 헤더 수를 의미하며 Window 계열에서는 더이상 이 값을 참조하지 않는다.
- Hidden Sector : 해당 볼륨 앞의 숨겨진 섹터 수를 의미하며 Window 계열에서는 더이상 이 값을 참조하지 않는다.
- Total Sector 32 : 해당 볼륨 상의 총 섹터 수를 의미한다.
- FAT Size 32 : FAT 영역의 섹터 수를 의미하는데 이 수는 FAT #1 과 FAT #2의 합산이 아닌 한 개의    
  FAT 영역의 섹터 수를 의미한다.
- Ext Flags : FAT 테이블의 사용 여부 등의 여러가지 설정 값을 기록한다.
- File System Version : FAT32의 버전 정보로 상위 1Byte는 주, 하위 1Byte는 부 버전을 의미한다. 하지만 실제로는 
   특정 값이 적히지 않고 0x00으로 기록된다.
- Root Directory Cluster : FAT32는 이전 버전들과는 달리 Root Directory가 Data Area 내 아무 위치에
  와도 상관 없기 때문에 그 시작 위치를 Root Directory Cluster 에 기록한다.
- File System Information : File System 구조체의 위치가 기록되나.
- Boot Record Backup Sector : Boot Record 를 백업한 위치를 기록하는 것으로 일반적으로는 6번 섹터를 
  이용한다. 만약 이 위치에 0이 기록되어있다면 백업을 하지 않았음을 의미한다.
- Reserved : 예약된 영역으로 항상 0으로 채워진다.
- Dirve Number : Window 계열에서는 더 이상 참조하지 않는다.
- Reserved1 : Windows NT 계열에서 사용하려고 만든 예약된 영역이며 0으로 채워져 있다.
- Boot Signature : 확장 부트 서명으로 0x29 라는 값이 들어간다(이후에 3가지 항목이 더 존재함을 의미).
- Volume ID : 볼륨의 시리얼 번호
- Volume Label : 볼륨 레이블을 적어준다.
- File System Type : 항상 FAT32로 적혀 있다.

이러한 내용을 토대로 실제 FAT 32를 사용하는 Partition 의 Boot Record를 분석해보도록 하겠다.

[그림 4-2] Partition 2의 Boot Record Area 찾아가기

Boot Record 영역의 분석을 위해서는 이전에 분석했던 MBR 영역에서 Partition 2 의 Boot record 영역을 찾아가야 한다.
일반적으로 Boot Record의 경우 예약된 영역의 첫 번째 섹터, 해당 볼륨의 첫 번째 섹터에 존재하기 때문에 이를 이용하면
해당 파티션의 첫 번째 섹터를 찾아간다고 생각하면 된다.

[MBR - Partition Table - LBA Starting Address] -> 10진수 변환 -> 이동

위의 방법 대로 MBR의 Partition Table 내에 존재하는 LBA Startin Address 를 찾아보니 0x009C263D 임을 확인할 수 있다.
이를 10진수로 변환하면 10233405 이며 이 단위는 섹터이므로 HxD 에서 10233405 번째 섹터를 찾아가면 [그림 4-2]와 같이 Partition 2의 Boot Record를 확인할 수 있다.

[그림 4-3] Partition 2의 Boot Root Area

Partition 2의 BR Area 영역은 [그림 4-3]과 같은데 이를 상세히 분석해보도록 하겠다.
단, 굵게 표시된 항목은 주요 항목으로 일반적으로 분석 시에는 이 값을 많이 참고한다.

EB 58 90 4D 53 44 4F 53 35 2E 30 00 02 08 20 00
02 00 00 00 00 F8 00 00 3F 00 FF 00 3D 26 9C 00
9C BF A3 00 DC 28 00 00 00 00 00 00 02 00 00 00
01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 29 8E D8 6B F8 4E 4F 20 4E 41 4D 45 20 20
20 20 46 41 54 33 32 20 20 20

- Jump Boot Code : 0x9058EB
- OEM Name : 0x302E35534F44534D
- Bytes per Sector : 0x0200, 512Byte
- Sector per Cluster : 0x08, 1 Cluster == 8 Sector
  => Cluster Size : 512 * 8 = 4096 Byte
- Reserved Sector Count : 0x0020, 32 Sector
- Number of FATs : 0x02, FAT #1, FAT #2 2 개 FAT 영역 보유
- Root Directory Entry Count : 0x0000
- Total Sector 16 : 0x0000
- Media : 0xF8, 고정식 디스크
- FAT Size 16 : 0x0000
- Sector Per Track : 0x003F
- Number Of Heads : 0x00FF
- Hidden Sector : 0x009C263D
- Total Sector 32 : 0x00A3BF9C, 10731420 Sector
- FAT Size 32 : 0x000028DC, 10460 Sector 
- Ext Flags : 0x0000
- File System Version : 0x0000 
- Root Directory Cluster : 0x00000002, Cluster 2
- File System Information : 0x0001, Sector 1
- Boot Record Backup Sector : 0x0006, Sector 6
- Reserved : 0x000000000000000000000000
- Dirve Number : 0x80
- Reserved1 : 0x00
- Boot Signature : 0x29
- Volume ID : 0x2020454D
- Volume Label : 0x2020414E204F4EF86BD88E
- File System Type : 0x2020203233544146, FAT32

(2) Reserved Area

예약된 영역의 첫 번째 섹터는 Boot Record로 바로 이전에 분석한 내용이다. 그리고 나머지 영역은 비어야 하지만 일반적으로는 Boot Record 에 기록된 것과 같이 Sector 1와 Sector 6
에는 File System Information 구조체와 Boot Record Backup 이 각각 기록되어있다.

[그림 4-4]  Reserved Area(FS Info 구조체) 구조

- Lead Signature : FSInfo 구조체가 기록된 섹터임을 알려준다. 0x41615252로 고정되어 있다.
- Reserved 1 : 예약 영역으로 해당 섹터의 대부분을 차지하고 있으며(479Byte) 전부 0으로 채워져있다.
- Struct Signature : 실제 FSInfo 구조체의 시작을 알려주는 항목으로 0x61417272 로 고정되어 있다.
- Free Cluster Count : 볼륨 상에 존재하는 빈 클러스터의 수
- Next Free Cluster : 가장 마지막에 할당된 클러스터의 값이 저장되며 이 바로 뒤에 오는 클러스터는 비어있는 클러스터라고 
   할 수 있다.
- Reserved 2 : 이 역시 예약된 영역이며 0으로 채워진다.
- Trail Signature : FS Info 구조체 섹터의 끝을 알려주며 0xAA550000로 고정되어 있다.

이 내용을 토대로 실제 Partition 2의 Reserved Area를 분석해보도록 하겠다.

[그림 4-5] Partition 2 의 Reserved Area

Boot Record 에서 FS Info 구조체의 위치는 Sector 1로 나와있었다. 
하지만 이는 섹터 번호가 0부터 시작하기 때문에 첫 번째 섹터가 아니라 해당 파티션의 두 번째 섹터를 의미하게 된다.
위에서 확인한 것과 같이 섹터의 시작은 0x41615252로 채워져있다.

00 00 00 00 72 72 41 61 B7 6D 14 00 03 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA

- Struct Signature : 0x61417272
- Free Cluster Count : 0x00146DB7, 1338807 개 클러스터가 비어있다.
- Next Free Cluster : 0x00000003, Cluster 3 번이 가장 마지막에 채워진 클러스터이다.
- Trail Signature : 0xAA550000

(3) FAT Area

FAT 영역은 FAT 파일 시스템에서 주요 정보를 담고 있다. 그 중에는 파일/디렉토리 의 할당에 대한 정보를 클러스터 단위로 관리한다.

[그림 4-6] FAT Area 의 구조

[그림 4-6]은 FAT Area 의 구조로 최소 8Byte를 제외하고는 전부 클러스터 단위로 파일을 관리하는 것을 확인할 수 있다.
Cluster 2부터 시작하는 이유는 이전에 Cluster 0과 Cluster 1는 이미 다른 용도로 사용되었기 때문인데 이는 차후에 알아보도록 하겠다.

이때 각 클러스터를 관리하는 4Byte 단위의 항목들을 FAT Entry라고 하며 각각은 다음 클러스터 번호가 기록된다.
이를 분석하기에 앞서 알아둬야 할 점은 FAT Area 는 단일 링크드 리스트 방식으로 데이터를 저장했다는 것인데 이를 이용하여 각 클러스터는 한 개 클러스터로 해당 파일/디렉토리를 저장할 수 없는 경우에 한 개의 클러스터를 더 할당하고 이 두 번째 클러스터의 번호를 첫 번째 클러스터에 기록하게 된다.
그리고 마지막 클러스터에는 0x0FFFFFFF 를 기록하여 마지막을 표시한다. 

단순 설명으로는 이해가 되지 않기 때문에 예제를 들어 이해를 돕도록 하겠다.
※ FAT Area 영역의 경우 Reserved Area 바로 다음에 오게 되어있는데 Partition 2의 Reserved Area 크기는 32 Sector 로 이루어져있음을 이전에 분석해주었기 때문에 Reserved Area 의 시작위치에서 32 Sector 만큼 이동하면 [그림 4-7]과 같이 FAT Area로 이동하게 된다.

[그림 4-7] Partition 2의 FAT Area

[그림 4-7] 은 FAT Entry 가 어떻게 Cluster 단위로 파일/디렉토리를 관리하는지에 대한 예제이다.
한 개 클러스터 영역으로 저장이 가능한 클러스터 2와 클러스터 3과는 달리 클러스터 4에 저장된 파일의 경우 용량이 큰지 다음 클러스터 번호가 적혀있다.

[그림 4-8] Partition 2의 FAT Entry

[그림 4-7] 을 통해 Cluster 4에서 시작된 파일은 Cluster 16까지 연결 되는 것을 확인할 수 있으며 이를 그림으로 그려보면 [그림 4-8]과 같다.
Cluster 16에서는 0x0FFFFFFF 을 기록하여 파일의 끝을 알렸고 이를 EOC(End Of Cluster)라고 한다.

(4) Data Area

Data Area는 실제 데이터들이 저장되는 영역을 말한다.
데이터는 클러스터 단위로 저장이 되는데 데이터가 한 개 클러스터 보다 크게 되면 클러스터를 더 할당하여 저장하게 된다.
이 경우 만약 저장 후 클러스터의 공간이 남아있다하더라도 이미 사용한 클러스터이기 때문에 다른 파일/디렉토리의 데이터를 저장할 수 없다.
실제 데이터를 저장할때는 파일이냐 디렉토리냐에 따라 저장 방식에 차이가 있는데 만약 파일이라면 클러스터에 파일의 내용이 직접적으로 저장이 되며
디렉토리라면 Directory Entry 라는 구조체 형식으로 저장이 된다.

[그림 4-9] Directory Entry 구조

- Name : 파일/디렉토리의 이름, 대문자로 최대 8자까지 넣을 수 있으며 남는 공간은 0x20으로 채워진다.
   단 만약 해당 파일/디렉토리가 지워진 경우에는 최고 상위 bit가 0xE5로 채워진다.
- Extender : 확장자, 대문자로 최대 3자리까지 입력이 가능하며 이 역시 남는 공간은 0x20으로 채워지는데 디렉토리의 
   경우에도 이 공간이 0x20으로 채워진다.
- Attribute : 해당 Directory Entry의 용도를 기록하는 항목으로 System File은 0x04로, 서브 디렉토리의 경우 0x10, 일반 
   파일은 0x20, LFN 이 적용되었다면 0xF0로 채워진다.
- NT Resource : Windows NT 의 예약된 공간으로 항상 0으로 채워져 있다.
- Create Time Tenth : 파일이 생성된 시간을 1/10 초 단위로 기록하는 항목.
- Create Time : 파일 생성 시간으로 상위 5bit는 초, 다음 6bit는 분, 마지막 5bit는 시를 의미한다. 다른 값은 일반적으로 
   식별하는 시간이 맞으나 초의 경우 값이 1증가할때마다 2초씩 증가한다.
- Create Date : 생성 날짜로 상위 5bit는 일, 다음 4bit는 월, 마지막 7bit는 년을 의미한다. 단 년도의 경우 1980년으로 
   부터의 오프셋인데 만약 11이라면 1980+11=1991년을 의미한다.
- Last Access Date : 가장 최근의 읽기/쓰기를 한 날자를 의미한다.
- First Cluster High 2Byte : 파일의 첫 번째 클러스터 번호의 상위 2Byte를 말한다.
- Write Time : 최근 파일 수정 시간을 말하며 파일 생성 역시 쓰기로 간주하기 때문에 파일 최소 생성 시에는 이 Write 
   Time과 Create Time 이 일치한다.
- Write Date : 최근 수정 일자로 파일 최초 생성시에는 Create Date와 일치한다.
- First Cluster Low 2Byte : 파일의 첫 번째 클러스터의 하위 2Byte를 말한다.
- File Size : 파일의 크기를 의미하며 단위는 Byte이다. 만약 디렉토리라면 이 항목은 0으로 채워진다.

이를 토대로 실제 분석을 수행해보도록 하겠다.

[그림 4-10] Partition 2 Directory Entry 분석 예제

[그림 4-10]과 같이 F:\ 로 명명된 Partition 2의 Root Directory 에는 dirtest 라는 디렉토리가 있으며 그 내부에는 test04.txt 라는 파일을 갖고 있다.
지금부터 Root Directory Entry부터 이 test04.txt 라는 파일을 찾아가보도록 하겠다.

[그림 4-11] Partition 2 Root Directory Entry

[그림 4-11]은 Partition 2의 Root Directory Entry로 최상위 디렉토리를 의미하는데 이곳에 있는 Directory 중 Attribute 항목이 디렉토리로, 즉 0x10으로 표기된 항목을 찾으면 가장 하위에 있는 것을 확인할 수 있다.
이를 상세 분석해보도록 하자.

44 49 52 54 45 53 54 20 20 20 20 10 08 2A 17 89
03 45 03 45 00 00 18 89 03 45 07 00 00 00 00 00

- Name : 0x4449525445535420, 파일명 DIRTEST
- Extender : 0x202020, Directory
- Attribute : 0x10, Directory
- NT Resource : 0x08
- Create Time Tenth : 0x2A
- Create Time : 0x8917, 10001 001000 10111 => 17시 8분 46초
- Create Date : 0x4503, 0100010 1000 00011 => 2014년 8월 3일
- Last Access Date : 0x4503, 2014년 8월 3일
- First Cluster High 2 Byte : 0x0000
- Write Time : 0x8918, 10001 001000 11000 => 17시 8분 48초
- Write Date : 0x4503, 2014년 8월 3일
- First Cluster Low 2Byte : 0x0007 => High + Low = 0x00000007 => Cluster 7
- File Size : 0x00000000, Directory

분석 중 Dirtest Directory 의 위치는 7번 클러스터라는 것을 알게 되었으므로 해당 클러스터로 이동한다.
한개 클러스터는 8 Sector 이므로 (7-2) * 8 = 40 Sector 만큼 이동한다.
※ 현재 2번 클러스터라는 것을 기억하고 계산해야 한다.

[그림 4-12] "DIRTEST" Directory 의 Directory Entry

"DIRTEST" Directory 의 클러스터를 찾아가면 [그림 4-12]와 같은데 이 곳에서도 Attribute 항목에 0x20, 즉 일반 파일을 찾아서 확인해보면 TEST4.txt의 Directory Entry를 찾을 수 있다.
그 후 TEST4.txt 의 데이터 위치를 확인하려면 이 Directory Entry를 상세 분석해야 한다.

54 45 53 54 30 34 20 20 54 58 54 20 18 72 1C 89
03 45 03 45 00 00 22 89 03 45 0F 00 06 00 00 00

- name : 0x5445535430342020, 파일 명 TEST4
- Extender : 0x545854, 확장자 TXT
- Attribute : 0x20, Archive File
- Create Time Tenth : 0x7218
- Create Time : 0x891C, 10001 001000 11100 => 17시 8분 56초
- Create Date : 0x4503, 2014년 8월 3일
- Last Access Date : 0x4503, 2014년 8월 3일
- First Cluster High 2Byte : 0x0000
- Write Time : 0x8922, 10001 001001 00010 => 17시 9분 4초
- Write Date : 0x4503, 2014년 8월 3일
- First Cluster Low 2Byte : 0x000F => High + Low = 0x0000000F => Cluster 15
- File Size : 0x00000006

분석 결과로 TEST4.TXT 의 데이터 위치는 15번 클러스터로 확인 되었으므로 (15-2) * 8 = 104 Sector 만큼 이동해야한다.

[그림 4-13] TEST04.TXT 내용 확인

해당 섹터로 이동하여 파일의 내용을 확인해보면 실제 파일의 내용과 일치하는 것을 확인할 수 있다.

(5) LFNs (Long File Name Entrys) 

Long File Name Entrys란 기존의 파일 작명 방식은 이름 8자 확장자 3자의 한계를 보완하기 위해 생겨난 작명 방법이다.
이 LFNs 방식은 UTF-16 인코딩을 사용하여 다국어 지원이 가능해졌으며 최대 255자까지 작명이 가능하게 되었다.

[그림 4-14] LFNs 구조

- Order : LFNs 의 순서를 기록하는 항목으로 가장 처음은 0x01로 시작되며 가장 마지막은 0x40 과 OR 연산을 한 값으로 
   넣는다. 자세한 사항은 실습에서 설명하도록 하겠다.
- Name 1 : 1~5번째 문자열
- Attribute : 항상 0x0F 으로 고정되어 있다.
- Type : 일반적으로 0x00으로 채워진다.
- Checksum : 해당 LFNs 과 대응 되는 Short Directory Entry 의 Checksum 을 저장한다.
- Name 2 : 6~11번째 문자열
- First Cluster Low : 반드시 0이 들어간다.
- Name 3 : 12~13 번째 문자열

이를 토대로 실제 Partition 2의 LFNs를 사용하는 파일을 분석해보도록 하겠다.

[그림 4-15] LFNs 실습을 위한 파일명/내용 확인.

[그림 4-15]와 같이 F:\LFN Test\thislfntestfile 이라는 파일을 분석하여 LFNs 에 대해 확인하고자 한다.
파일 명은 thisislfntestfile 이며 확장자를 빼고도 16개 문자로 이루어져 있기 때문에 기존의 Short Directory Entry 로는 저장할 수 없다.

[그림 4-16] Partition 2 LFNs 확인

Test File 의 Directory Entry 로 이동해보면 THISIS~1TXT 로 파일명과 확장자가 표현 된 것을 확인할 수 있는데 그 윗쪽을 살펴보니 Attribute가 0x0F로 되어있는 2개의 Entry가 보인다.
이는 해당 Test File 의 LFNs 임을 알 수 있다. 

42 66 00 69 00 6C 00 65 00 2E 00 0F 00 43 74 00
78 00 74 00 00 00 FF FF FF FF 00 00 FF FF FF FF
01 74 00 68 00 69 00 73 00 69 00 0F 00 43 73 00
6C 00 66 00 6E 00 74 00 65 00 00 00 73 00 74 00

LFNs 에 대해서만 상세히 분석해보고자 하는데 우선 2개의 Order를 확인해보면 가장 처음은 01로 그다음에는 42로 시작하는 것을 확인할 수 있다.
이는 0x40 | 0x02의 결과로 해당 LFNs가 가장 마지막 LFNs 임을 의미한다.
그러므로 1번 Entry의 Name 1부터 Name 3까지 읽고 그 다음 2번 Entry 의 Name 1 부터 Name 3까지 읽으면 thisislfntestfiletxt로 정확히 파일 명과 일치하는 것을 알 수 있다.


'Security > Forensic (practice)' 카테고리의 다른 글

[WIndows] 00 개요  (0) 2014.10.16
[File System] MBR 분석  (1) 2014.08.03
[File System] Partition VS Volume  (0) 2014.07.29
[File System] file system 과 구성 요소  (0) 2014.06.28