2020. 1. 30. 11:30ㆍ디지털 포렌식
이 글에서는 FAT32만 다루기 때문에 다른 FAT형식은 다루지 않습니다.
FAT(File Allocation Table)은 Microsoft에서 개발되었으며, 과거에 주로 사용하던 파일시스템입니다. 이 파일 시스템은 이름 그대로 파일의 할당 정보를 표현한 테이블입니다.
FAT는 구조가 간단하여 용량이 적은 USB등에서 주로 쓰고 있습니다. FAT는 FAT12, 16, 32 exFAT를 구분할 수 있는데 FAT뒤의 숫자는 비트 수로 최대 클러스터의 수를 의미합니다.
exFAT(Extended File Allocation Table)는 FAT64로도 불리며 윈도우 비스타, 7, 2008이상의 운영체제에서 호환하기 위해 만들어진 파일시스템입니다. ms에서 라이센스를 가지고 있습니다.
FAT 형식 | 최대 표현 가능한 클러스터 수 |
FAT12 | 4,084(2^12 - 12) |
FAT16 | 65,524(2^16 - 12) |
FAT32 | 268,435,444(2^28 -12) |
FAT32에서 보면 28비트만 사용하는걸 볼 수 있는데 이는 4비트가 사전에 예약되어 다른 용도로 사용하고 있기 때문입니다.
FAT는 MBR 구조의 비트 수 제한으로 최대 2TB까지 지원하고, 파일의 최대 저장 가능한 용량은 4GB입니다.
NTFS 등과 같은 파일시스템은 대부분 FAT와 그 형태가 유사합니다. FAT를 잘 알고있다면 다른 파일시스템은 무난하게 이해할 수 있습니다.
FAT 32 구조
- Boot Record : 이 영역은 "Reserved area"의 첫 번째 섹터를 의미합니다. 볼륨 인식을 위해 이 영역을 참조합니다.
- Reserved area : 이 영역은 예약되어 있는 영역입니다. FAT32는 이 영역에 일부 정보를 저장합니다.
- FAT #1, #2 : FAT 영역은 클러스터 관리 테이블이있는 영역입니다. 이 영역을 통해 특정 파일에 연결된 클러스터를 파악할 수 있습니다. 이 영역이 손상되면 해당 파일을 파악할 수 없게 되어 사용할 수 없게됩니다. FAT #1의 복사(백업)된 내용은 FAT #2로 손상되지 않은 FAT32파일시스템은 FAT #1과 FAT #2의 값이 동일합니다.
- Root directory : 계층 구조의 최상위 디렉토리를 말합니다. 이 영역은 파일 수 제한 등 몇 가지 단점을 극복하고자 위치가 정해져 있지 않습니다. Boot Record에 손상이 있을 경우 Root directory를 찾기 어려운 문제가 있기 때문에 일반적으로 FAT #2영역 바로 뒤에 위치해 있습니다.
- Data area : 모든 파일, 디렉토리의 내용이 이곳에 저장됩니다. 이 영역은 클러스터 단위로 읽기/쓰기가 이루어집니다.
Boot Record
실제 사용중인 USB를 이용했습니다.
Jump boot code (0x9000EB) : 점프 코드로 점프하는 코드
OEM Name (0x2020202020202020) : OEM회사를 나타내는 문자열
Bytes Per sector (0x200) : 한 개 섹터를 구성하는 바이트 수
-> 1sector = 512Byte
Sector per Cluster (0x20) : 한 개 클러스터를 구성하는 섹터 수(2의 배수)
-> 1cluster = 32sector = 16,384Byte = 16KB
Reserved Sector Count (0x26) : Reserved area의 크기(단위 : sector)
-> 38sector = 19,456Byte
Number of FATs (0x02) : 이 볼륨에 존재하는 FAT 영역의 갯수
Root Directory Entry Count (0x00) : FAT16에서만 사용하는 영역, 루트 디렉토리에 몇 개의 항목이 있을 수 있는지 나타냄(호환성을 위해 Bytes Per sector와 크기가 동일 한 것으로 설정 권장). FAT32는 이 영역을 0으로 설정
Total Sector 16 (0x00) : FAT16에서만 사용하는 영역, 해당 볼륨의 총 섹터. FAT32는 이 영역을 0으로 설정
Media (0xF8) : 해당 볼륨이 어떤 미디어 장치에 있는지 나타냄. 0xF8은 고정 디스크를 말하며 이외의 값은 모두 플로피 디스크를 나타냄
FAT Size (0x00) : 해당 볼륨의 총 섹터, FAT32는 이 영역을 0으로 설정
Sector per track (0x3F) : x86계열의 인터럽트에 해당, windows는 이 영역을 참조하지 않음
Number of heads (0xFF) : x86계열의 인터럽트에 해당, windows는 이 영역을 참조하지 않음
Hidden Sector (0x20) : 해당 볼륨 이전의 섹터 수, x86계열의 인터럽트에 해당하며 windows는 이영역을 참조하지 않음
Total Sector 32 (0x1DCFFE0) : 해당 볼륨의 총 섹터, FAT32에서만 사용
-> 31,260,640sector = 16,005,447,680Byte
FAT Size 32 (0x1DCD) : FAT 영역의 섹터 수(FAT영역 2개중 한개), FAT32에서만 사용
-> 7,629sector = 3,906,048Byte
External Flags (0x00) : 이 영역에 여러 구성 매개 변수 저장, FAT32에서만 사용
File system version (0x00) : FAT32의 버전, Windows가 인식 하는 버전보다 높을 경우 인식하지 않음, FAT32버전은 증가하지 않았으므로 0x00이 저장
Root directory cluster (0x02) : root directory의 위치를 표시, FAT32에서만 사용, 기본 값은 2를 가짐(단위 : cluster)
File system info (0x01) : FSInfo의 위치, 일반적으로 볼륨의 첫 번째 섹터에 존재(단위 : sector)
Boot record backup (0x06) : 이 영역에 백업 부트 섹터의 위치 표시. 보통 6번 섹터에 위치(단위 : sector)
-> 3,072Byte
Reserved (0x00) : 예약영역, FAT32에서만 사용
Number of drives (0x80) : 0x13 인터럽트용으로 Windows는 참조 안함, FAT32에서만 사용
Reserved (0x00) : 예약영역, FAT32에서만 사용
Boot signature (0x29) : 확장 부팅 서명, 항상 0x29의 값이 존재하며 이는 부트 레코드의 끝이 아니고 부트 레코드에 이어 3개의 추가 필드가 있음을 의미
Volume ID (0xFB014BE2) : 볼륨 일련 번호. FAT16에서만 해당
Volume Label (0x20202020454D414E204F4E) : 볼륨 레이블로 Windows의 디스크 드라이브 이름, FAT16에서만 해당
File System Type (0x2020203233544146) : 파일시스템이름, Windows는 참조 안함
-> FAT32
FAT파일 시스템은 부팅 레코드의 끝 서명이 반드시 와야합니다. 이는 511~512에 위치합니다.
FAT 파일 시스템의 예약된 영역은 부팅 레코드 및 부팅 레코드 백업을 위해 사용합니다. Windows FAT32의 경우 예약 영역(Reserved)의 첫 번째 섹터에 부팅 레코드가 있습니다. boot record의 Boot record backup 항목에서 보면 6번째 섹터(0xC00=3072Byte)에서 부팅 레코드를 백업하는 것을 알 수 있으며 이는 일반적입니다.
FSInfo(File System Information) : 파일 시스템 정보
FAT의 FSInfo는 Reserved area영역 안에 존재합니다. Boot Record에서 File system info필드에 보면 해당 위치가 적혀있습니다. 확인해보면 1섹터에 위치해 있으며 이는 대부분의 경우에 해당합니다. 1섹터는 512바이트로 16진수로 변환하면 200이라는 값이 나옵니다. offset에서 200의 값으로 추적하면 FSInfo에 해당하는 내용이 나옵니다.
Lead Signature (0x41615252) : 이 영역은 이 섹터에 FSInfo 구조가 있음을 나타냄, 항상 0x41615252값을 가짐
Reserved (0x00) : 예약된 영역, 사용되지 않는 영역으로 마음대로 변경 가능
Struct signature (0x61517272) : 이 영역은 Lead Signature와 같이 이 섹터에 FSInfo 구조가 있음을 나타냄, 항상 0x61517272 값을 가짐
Free cluster count (0x76ECA) : 해당 볼륨에 사용 가능한 클러스터 수, 0xFFFFFFFF일 경우 사용 가능한 클러스터 수를 계산하지 않으며 이 값은 신뢰성이 떨어짐 -> 참고용으로만 사용
Next free cluster (0x7564) : 마지막에 위치한 클러스터의 위치, 위치를 알 수 없을 경우 0xFFFFFFFF값을 가짐
Trail signature (0xAA550000) : 해당 섹터에 FSInfo 구조가 있음, 항상 0xAA550000값을 가짐
FAT area
FAT area는 Reserved area의 바로 뒤에 있기 때문에 해당 영역으로 가기 위해서는 Reserved area의 크기를 알아야합니다. Reserved area의 크기는 Boot Record에 있으며, 크기만큼 이동하면 FAT area로 이동할 수 있습니다.
분석 결과 Reserved area의 크기가 19,456Byte 인걸 알았으니 바로 이동하겠습니다.
여기서 Boot Record가 1섹터를 차지하니까 FAT area는 1섹터를 더한 값으로 이동해야 하지 않는가를 생각하고 있다면 FAT의 구조를 이해하지 못했다는 뜻입니다. Boot Record는 Reserved area영역 안에 속해있는 내용이며, 구조상 같은 위치에 있습니다. 따라서 1섹터를 더할 필요가 없습니다. 실제 이동해보시면 알게됩니다.
FAT32는 4바이트를 통해 데이터 영역의 시작 클러스터부터 마지막 클러스터까지 할당 관계를 표시합니다. 이를 FAT Entry라고 합니다.
첫번째 엔트리(0xFFFFFF8)는 해당 미디어의 타입을 나타내고, 두번째 엔트리(0XFFFFFFFF)는 파티션의 상태를 나타냅니다. 이 두개의 엔트리는 예약된 내용이므로 파일 분석 시 무시할 수 있습니다.
3번째 엔트리(0x0FFFFFFF)는 파일의 끝을 나타내는데 이는 한 클러스터(16KB)보다 작다는 것을 의미합니다. 4번째 엔트리 또한 같습니다. 5번째 엔트리의 값이 5로 되어있는 것을 볼 수 있는데 이는 해당 파일이 한 클러스터(16KB)보다 크기 때문에 다음 클러스터(cluster 5)에도 이 파일의 내용이 있다는 것을 의미합니다. 파일의 끝을 나타내는 0x0FFFFFFF값이 있을 때 까지 다음 엔트리는 다음 클러스터의 값을 가지고 있습니다.
여기서 파일이 삭제가 된다면 디렉터리 엔트리에 삭제 플래그를 기록되며 FAT area의 영역은 0x00으로 초기화 됩니다.
하지만 데이터가 저장된 데이터 영역의 데이터는 접근하지 않아 이를 이용해 데이터를 복구할 수 있습니다.
지금까지 분석한 내용으로 클러스터 2,3,4~26번째에 있는 파일 갯수와 대략적인 크기를 알 수 있습니다.
cluster 2 = 16KB 이하
cluster 3 = 16KB 이하
cluster 4 = 352KB ~368KB
DATA area
모든 파일/폴더는 이 영역에 기록합니다. 이곳에선 클러스터 단위로 읽기/쓰기가 이루어집니다.
모든 파일/폴더는 Directory Entry라는 구조체 형식으로 저장합니다. 각각의 파일/폴더는 Directory Entry로 표현하며, 크기는 32Byte입니다.
DATA area 영역이 시작하는 위치는 2cluster부터 입니다.
- Name : 이름
- Extension : 확장자
- Attr : 속성
- Reserved : 12바이트의 내용은 windows NT의 예약 공간으로 0으로 채워짐, 13은 생성된 시간 기록(1/10초 단위)
- Create Time : 파일 생성 시간
- Create Date : 파일 생성 날짜
- Last Accessed Date : 가장 최근의 읽기/쓰기한 날짜(마지막 접근 기록)
- Starting Cluster Hi : 파일의 첫 번째 클러스터 번호의 상위 2Byte
- Last Written Time : 가장 최근의 수정한 시간
- Last Written Date : 가장 최근의 수정한 날짜
- Starting Cluster Low : 파일의 첫 번째 클러스터의 하위 2Byte
- File Size : 파일의 논리적 크기(단위 : Byte), 디렉터리의 경우 0x00의 값을 가짐
위와 같은 방법으로는 파일이름 8자, 확장자 3자의 한계가 생깁니다. 이를 보완하기 위해 LFNs(Long File Name Entrys)라는 방법을 만들었습니다. 이 방식은 UTF-16 인코딩을 지원하며 최대 255자까지 파일이름을 설정할 수 있습니다.
- Order : LFNs의 순서, 상태를 기록하는 항목(0xE5 : 삭제된 파일/폴더, 01 : 첫번째 순서)
- Name1~ : 파일/폴더 이름, 빈 영역은 0xFF로 채워짐
- Atrr : 0x0F일 경우 확장된 파일명이라는 뜻
- Type : 일반적으로 0x00의 값을 가짐
- Checksum : LFNs와 대응되는 Short Directory Entry 의 Checksum을 저장
- Start cluster low : 0x00으로 고정
Data area에 가기 위해선 FAT영역의 시작 주소와 그 크기를 알면 됩니다. 이 모든 정보는 Boot Reord에 있습니다.
FAT영역 시작 주소 = Reserved area의 크기 = 19,456Byte(0x4C00)
FAT영역 크기 = FAT Size 32 = 7,812,096Byte
Data area 시작 주소 = 19,456Byte + 6,291,456Byte = 7,831,552Byte(0x778000)
읽는 순서는 Directory Entry가 저장된 부분부터 order에 표시된 순서대로 읽기 시작합니다.
붉은 부분은 order에 0xE5로 표시된 것으로보아 삭제된 파일임을 확인할 수 있습니다.