
이번엔 NTFS 구조에 대해 설명하겠습니다.
1. NTFS(New Technology File System)
Microsoft Windows 의 파일 시스템 입니다. MS-DOS부터 쓰인 FAT의 확장성, 보안, 및 제한 사항을 극복하기 위해서 1993년 Windows NT 3.1과 함께 발표되었습니다. FAT에 비해 여러가지 개선 되었습니다.
| NTFS Version | First OS | Release data |
| 1.0 | Windows NT 3.1 | 1993 |
| 1.1 | Windows NT 3.5 | 1994 |
| 1.2 | Windows NT4.0 | 1996 |
| 3.0(5.0) | Windows 2000 | 2000 |
| 3.1(5.1) | Windows XP | 2001 |
다음은 NTFS Cluster Size 입니다.
| Volume Size | Windows NT 3.51 | Windows NT 4.0 | Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, Windows 2000 |
| 7 MB ~ 512 MB | 512 bytes | 4KB | 4KB |
| 512 MB ~ 1 GB | 1KB | 4KB | 4KB |
| 1GB ~ 2GB | 2KB | 4KB | 4KB |
| 2GB ~ 2TB | 4KB | 4KB | 4KB |
| 2TB ~ 16TB | Not Supported | Not Supported | 4KB |
| 16TB ~ 32TB | Not Supported | Not Supported | 8KB |
| 32TB ~ 64TB | Not Supported | Not Supported | 16KB |
| 64TB ~ 128TB | Not Supported | Not Supported | 32KB |
| 128TB ~ 256TB | Not Supported | Not Supported | 64KB |
| 256TB ~ | Not Supported | Not Supported | Not Supported |
NTFS 파일 시스템도 전반적인 구조는 FAT32와 크게 다르지는 않습니다. MFT(Master File Table)이라는 별도의 구조를 두어서 MFT에 모든 파일의 메타데이터를 저장합니다. 그리고 VBR은 볼륨의 맨끝에 Backup VBR 을 별도로 복구가 가능하도혹 했습니다.

1.1 VBR
NTFS의 VBR은 아래와 같은 구조를 가지는데 오프셋 차이만 있고 FAT32의 전반적인 구조와 유사성을 지닙니다.

| Name | Offset | Size | Description |
| Jump Command | 0x0 ~ 0x2 | 0x3 | Boot Code로 점프 |
| BPB(Bios parameter Block) | 0x3 ~ 0x53 | 0x51 | 볼륨의 전반적인 설정을 포함 |
| Boot Code | 0x54 ~ 0x1FD | 0x1AA | 볼륨 부트코드 |
| Signature | 0x1FE ~ 0x1FF | 0x2 | 고정값 |
1.1.1 BPB(Bios Parameter Block)

NTFS VBR의 BPB 영역 구조를 살펴보겠습니다.
| Name | Offset | Description |
| OEM ID | 0x03 ~ 0x0A | NTFS로 고정된 값 입니다. |
| Bytes Per Sector | 0x0B ~ 0x0C | 한 섹터 당 할당되는 Byte 크기 입니다. |
| Sector Per Cluster | 0x0D ~ 0x0D | 한 클러스터당 할당되는 섹터 수 입니다. |
| Reserved Sector Count | 0x0E ~ 0x0F | FAT Area가 나오기 전의 섹터 수 입니다. |
| Unused | 0x10 ~ 0x14 | 사용되지 않습니다. |
| Media | 0x15 ~ 0x15 | 대부분 0xF8 : 고정 디스크입니다. |
| Unused | 0x16 ~ 0x27 | 사용되지 않습니다. |
| Total Sectors | 0x28 ~ 0x2F | 볼륨의 총 섹터 수 입니다. |
| Start Cluster for $MFT | 0x30 ~ 0x37 | 해당 값 기반으로 MFT 영역 찾아갈 수 있습니다. |
| Start Cluster for $MFTMirr | 0x38 ~ 0x3F | $MFTMirr 영역에 찾아갈 수 있습니다. |
| Cluster Per Entry | 0x40 ~ 0x40 | MFT Entry 크기 입니다. |
| Unused | 0x41 ~ 0x43 | 사용되지 않습니다. |
| Cluster Per Index | 0x44 ~ 0x44 | 디렉토리 공간 할당을 위해서 사용하는 인덱스 버퍼 크기 입니다. |
| Unused | 0x45 ~ 0x47 | 사용되지 안습니다. |
| Volume Serial Number | 0x48 ~ 0x4F | 볼륨의 식별하는 8byte로 구성되어있는 시리얼 넘버 입니다. |
| Unused | 0x50 ~ 0x53 | 사용되지 않습니다. |
1.2 MFT(Master File Table)
MFT 파일은 NTFS 파일, 디렉토리, 메타데이터를 모두 파일 형태로 관리하는 파일입니다. 이러한 데이터는 MFT Entry라는 구조를 통해서 저장이 됩니다. MFT Area는 파일 시스템 파일 수에 따라서 동적 할당을 합니다. MFT Entry의 0~15번은 시스템 메타데이터를 저장하기 위해서미리 예약된 영역 으로 사용 됩니다.
$MFT 영역 주소 계산법입니다.
[+] MFT Address = Start Cluster For MFT * Cluster Size(0x1000)
[+] Start Cluster For $MFT(Sector) = Start Cluster For MFT * Sector Per Cluster
[+] Start Cluster For $MFTMirr(Sector) = Start Cluster For MFTMirr * Sector Per Cluster
구한 값을 보면


2개의 값들을 보면 $파일이 같은것은 알 수 있을겁니다. MFT 영역에서 MFT Entry에 대해서 구조를 봐보겠습니다.

MFT Entry 0~15번까지는 파일시스템의 Reserved Area로 정해져있다.
| Entry Num | Entry Name | Description |
| 0 | $MFT | 모든 파일의 MFT Entry정보를 담고있습니다. |
| 1 | $MFTMirr | $MFT 파일의 일부 백업 데이터를 담고 있습니다. |
| 2 | $LogFile | Meta Data의 트랜잭션 정보를 담고 있는 파일 입니다. 파일 수정, 생성 등과 같은 이벤트 발생시 기록됩니다. |
| 3 | $Volume | 볼륨의 버전 정보 식졀자와 같은 정보를 담고 있습니다. |
| 4 | $ArrtDef | 속성의 식별자, 이름, 크기, 등의 정보를 담고 있습니다. |
| 5 | $ | 볼륨 루트디렉토리 정보를 담고 있습니다. |
| 6 | $BitMap | 볼륨의 클러스터 할당 정보를 담고 있습니다. |
| 7 | $Boot | 부트섹터 정보를 담고 있습니다. |
| 8 | $BadClus | 배드 섹터를 가지는 클러스터의 정보를 담고 있습니다. |
| 9 | $Secure | 파일의 보안, 접근 제어와 관련한 정보를 담고 있습니다. |
| 10 | $Upcase | 모든 유니코드의 대문자를 저장 합니다. |
| 11 | $Extend | 파일의 추가적인 정보를 저장하는 영역 입니다. |
| 12~15 | 예약된 영역 입니다. | |
| 16~ | 포맷후 생성되는 파일의 정보를 위해 사용하는 영역 입니다. | |
| - | $ObjID | 파일 고유 ID정보 담고있습니다 |
| - | $Quota | 사용량의 정보를 담고 있습니다. |
| - | $Reparse | Reparse Point에 대한 정보를 담고 있습니다. |
| - | $UsnJrnl | 파일, 디렉토리 변경 정보를 담고 있습니다. |
다음으로 MFT Entry의 영역을 알아보겠습니다. MFT Entry 구조 입니다.

| Name | Offset | Description |
| MFT Entry Header | 0x0 ~ 0x2F | MFT Entry의 메타 데이터 |
| Fix-up Array | 0x30 ~ 0x37 | NTFS의 신뢰성을 높이기 위한 구조 |
| Attribute Area | 0x38 ~ 달라질 수 있습니다 | 파일 이름, 변경 시각 등 속성 들이 나열되는 영역 |
| End Marker | 이후 | MFT Entry 끝을 알리는 데이터 |
1.2.1 MFT Entry Header
MFT Entry Header는 MFT Entry의 메타데이터 정보를 담고 있는 48바이트 영역입니다. MFT Entry Header의 Layout을 확인해 보겠습니다.

| Name | Offset | Description |
| Signature | 0x00 ~ 0x03 | Signature: File |
| Offset to Fixup Array | 0x04 ~ 0x05 | Fixup 배열 시작위치 입니다. |
| Entries in Fixup Array | 0x06 ~ 0x07 | Fixup 배열 포함 항목 수 입니다. |
| $LogFile Sequence Number | 0x08 ~ 0x0F | $LogFile 존재하는 해당 파일 트랜젝션 위치 입니다. |
| Sequence Number | 0x10 ~ 0x11 | 순서 번호로 MFT Entry 생성 후에 할당/해제 시 1씩 증가 합니다. |
| Hard Link Count | 0x12 ~ 0x13 | 해당 MFT Entry에 연결된 하드 링크 입니다. |
| Offset to File Attribute | 0x14 ~ 0x15 | 해당 Entry의 첫번째 파일 속성 위치 입니다. |
| Flags | 0x16 ~ 0x17 | 0x01 사용중 / 0x02 디렉토리 (MFT Entry 속성) |
| Real Size of MFT Entry | 0x18 ~ 0x1B | 사용 중인 크기 입니다. |
| Allocated Size of MFT Entry | 0x1C ~ 0x1F | MFT Entry에 할당된 크기 입니다. |
| File Reference to Base Entry | 0x20 ~ 0x27 | Entry가 non-base일때 Base Entry 주소 입니다. |
| Next Arrtibute ID | 0x28 ~ 0x29 | 다음 속성 ID 입니다. |
| Align to 48 Boundary | 0x2A ~ 0x2B | xp만 존재합니다. |
| Number of this MFT Entry | 0x2C ~ 0x2F | xp에만 존재합니다. |
1.2.2 Base & Non-base MFT Entry
MFT Entry Header에서 Base Entry or Non-base Entry참조 주소를 담고 있는걸 알 수 있습니다. Base Entry는 파일의 기본 정보를 저장하고(크기, 시간 등등) 가장 중요한 속성들이 저장됩니다. 그리고 Non-base Entry들의 위치를 관리합니다. 반면에 Non-base MFT Entry는 추가 속성 정보를 저장합니다. 그리고 파일의 속성 내용이 클 경우 하나 이상의 MFT Entry를 사용하게 됩니다. Base MFT Entry는 파일의 첫 MFT를 사용하게 됩니다, Non-Base MFT Entry는 Base MFT Entry를 제외한 나머지 부분을 담고 있는 Entry입니다.
[+] 예시
[+] MFT Entry 100(base) 00 00 00 00 00 00 00 00
Stored contents:
File Name: test.txt
File Size: 10MB
...
[+] MFT Entry 105(Non-base) 64 00 00 00 00 xx xx
Stored contents:
Additional ACL information
Compression attribute
....
[+] MFT Entry 110(Non-base) 64 00 00 00 00 xx xx
Stored contents:
etc meta data
[+] (맨뒤에 있는 xx xx는 100번 Entry의 Sequence Number을 사용합니다.)
[+] File Reference to Base MFT Entry 자리가 00 00 00 00 00 00 00 00 이면 Base MFT Entry 구조 이고,
[+] 00 00 00 00 00 00 00 00 이 아니라면 Non-Base MFT Entry구조입니다.
1.2.3 File Reference Address
File Reference Address는 NTFS에서 파일을 가리키는 정확한 주소입니다.
- Size : 8byte(64bit)
- Composition : Sequence Number(16bit) + MFT Entry Address(48bit)
Sequence Number은 MFT Entry가 재사용 될때마다 값이 증가합니다. 파일이 삭제 되거나 그럴때는 증가하지는 않고, 새로운 파일이 해당 Entry를 사용할 때 증가합니다. Sequence Number에서의 목적은 Entry 재사용시 무결성을 보장하기 위해서 있습니다.
만약 Entry 100 에 password.txt 를 저장하고(sequence:0x0001), 다른 곳에서 Entry 100을 참조합니다. 그리고 password.txt 삭제되면(sequence: 0x0001유지) 해당 MFT Entry는 재사용을 위해 가용상태가 되며, Entry 100 에 old.txt 저장 합니다. 그럼 Sequence Number가 1 증가 됩니다.
MFT Entry Address은 MFT Entry의 물리적 위치를 나타내는 번호를 뜻합니다. MFT에서 몇번째 Entry 인지 나타냅니다.
File Reference Address 계산식은(Sequence Number은 MFT Entry Header 0x10~0x11에 위치합니다.)
[+] File Reference Address = Sequence Number + MFT Entry Address
1.2.4 Fixup Array
MFT Fixup Array Area는 데이터 무결성을 판당하는 영역입니다.(MFT Entry) MFT Entry는 2개의 섹터를 사용합니다. 해당 Fixup Array는 MFT Entry의 데이터 무결성을 가지고 있는지 확인하기 위해서 각 섹터의 마지막 2byte를 특정 Signature로 값을 대체하고 기존 값을 Array에 저장합니다.

위 hex값을 보겠습니다. 빨간 네모박스는 Offset of Fixup Array, 주황색 네모박스는 Number of Entries in Fixup Array이고 초록색은 Signature값 그리고 파란색은 기존 마지막 섹터 2byte를 백업하여 저장한 값입니다.
Fixup Array의 크기는 사실상 Signature는 2byte이기 때문에 Number of Entries in Fixup Array값에 따라 결정됩니다. 서로의 합이 Fixup Array크기 이기때문입니다. Offset of Fixup Array: 0x30이고 Fixup Array 크기를 구하면 0x03 * 2= 6byte이니 8byte의 크기가됩니다.
Signature value: 0x02 00
Fixup Array value : 0x42 35 29 30 00 00
그럼 Fixup Array 적용전 적용후를 얘기해 보겠습니다.
Fixup Array를 적용전에는 해당 Fixup Array에 42 35 29 30값이 저장되지 않고 저장되지 않고
Signature에 1섹터에 2byte씩저장됩니다.
Fixup Array값을 적용하면 Fixup Array에 값이 42 35 29 30 값이 저장되고
signature값과 똑같이 0x02 00으로 저장됩니다.
1.2.5 Attribute
Attributes Area는 MFT Area에서 가장 크게 차지하고 있습니다. 또한 중요한 영역 입니다. 그리고 모든 디렉토리 및 파일의 모든 내용을 담고 있습니다. 또한 Attribute Entry 는 Attribute Content로 이루어져있고 팡리의 메타데이터 정보와 일부 파일의 데이터 자체를 포함합니다.
Resident Attribute: 크기가 작은 파일이 해당되고, MFT Entry속성 헤더 바로 뒤에 속성 내용이 저장됩니다. MFT Entry 내부에 직접 저장되다보니 빠른 접근이 가능합니다.
Non-Resident Attribute: 크기가 큰 파일들이 해당되고, 속성의 내용의 크기가 너무 커서 별도의 클러스터에 저장됩니다. 그리고 MFT Entry에는 위치 정보만 저장됩니다. 이런 Non-Resident Attribute 는 파일시스템의 한도까지 저장 가능합니다.
Attributes Area는 여러개의 속성 구조로 관리가 됩니다. 하나의 속성 구조는 속성 헤더, 내용 을 가집니다. 그리고 각각의 Attribute Entry는 Attribute의 파일크기에 따라서 Resident 속성과 Non-Resident 속성 으로 나뉩니다. (하나의 파일을 저장할때 MFT Entry가 생성됩니다. 해당 내의 있는 Attribute Area는 여러개의 Attribute Entry가 생성됩니다.)
'File Size' < 700byte Resident Attribute
'File Size' > 700byte Non-Resident Attribute
1.2.6 Common Attribute Header
Attribute 의 가장 기본적인 포맷입니다. 구조를 보면

Common Attribute Header는 Resident Attribute Header 와 Non-Resident Attribute Header에 필수 적으로 0x00~0x0F까지 들어가는 구조입니다. 확인해보면

| Name | Offset | Description |
| Attribute Type ID | 0x00 ~ 0x03 | 속성 타입 식별값입니다. |
| Length of Attribute | 0x04 ~ 0x07 | 속성 전체길이 입니다. |
| Non-Resident flag | 0x08 ~ 0x08 | Non-Resident 인지 확인하는 flag값입니다. (0x00: Resident 속성 0x01: Non-Resident속성) |
| Length of Name | 0x09 ~ 0x09 | 자신의 이름 길이를 나타내는 부분 입니다. |
| Offset to Name | 0x0A ~ 0x0B | 해당 속성 이름이 저장된 곳의 주소를 나타내는 부분입니다. |
| Flags | 0x0C ~ 0x0D | 상태 표현하는 부분 입니다.(0x0001: 압축 속성/ 0x4000: 암호화 속성/ 0x8000: Sparse 속성) |
| Attribute identifier | 0x0E ~ 0x0F | 속성의 고유한 식별자로 MFT Entry에 같은 속성이 여러개 일 경우 구별하기 위해서 사용하는 부분입니다. |
1.2.7 Resident Attribute Header
해당 헤더는 Common Attribute Header의 0x00~0x0F 같은 값을 가집니다. 그 밑에 한줄이 추가되었습니다. 해당 Common Attribute Header 다음으로 나오는 영역의 크기는 8 아니면 16byte를 가진다 구조를 보면


| Name | Offset | Description |
| Length of the Attribute | 0x10 ~ 0x13 | 헤더 뒤에 오는 속성 내용 크기 입니다. |
| Offset to Attribute Data | 0x14 ~ 0x15 | 속성 내용 시작 위치 입니다. |
| Indexed Flag | 0x16 ~ 0x16 | 1이라는 값을 가지면 인덱스 된 속성임을 뜻합니다. |
| Unused | 0x17 ~ 0x17 | 사용되지 않는 부분 입니다. |
| Attribute Name | 0x18 ~ 0x1F | 속성 이름이 있는 경우 이고, 없으면 바로 속성 사용하는 부분입니다. |
1.2.8 Non-Resident Attribute Header
Non-Resident Attribute Header의 경우 Common Attribute Header 다음으로 나오는 영역은 0x30or0x38 크기 입니다. 해당 Common Attribute Header의 Non-Resident Flag값이 0x01이므로 Attribute Size가 0x50으로 이후에 Offset to RunList값이 0x40이며, 해당 0x40~0x4F까지 16byte입니다.
저장 구조
0x00~0x0F: Common Header(16Byte)
0x10~0x3F : Extended Header(48byte)
0x40~0x4F: RunList(16byte)
16 + 48 + 16 = 80byte


| Name | Offset | Description |
| Start VCN of the runlist | 0x10~0x17 | 속성 내용이 담긴 런리스트 시작 값입니다. |
| End VCN of the runlist | 0x18~0x1F | 속성 내용이 담긴 런리스트 끝 값입니다. |
| Offset to runlist | 0x20~0x21 | 속성 내부의 런리스트 시작 위치입니다. |
| COmpression unit size | 0x22~0x23 | 압축 속성일 경우 압축 단위 입니다. |
| Unused | 0x24~0x27 | 사용하지 않는 부분 입니다. |
| Allocated size of attribute content | 0x28~0x2F | 속성 내용에 할당된 클러스트 크기 입니다. |
| Real size of attribute content | 0x30~0x37 | 속성 내용의 실제 크기 입니다. |
| initialized size of attribute content | 0x38~0x3F | 속성 내용의 초기화된 크기 입니다. |
| Attribute Name | 0x40~0x47 | 속성 이름이 있는 경우 속성이름 없으면 바로 속성 내용으로 됩니다. |
1.2.9 Cluster Runs
Cluster Run : 데이터 저장 시에 클러스터가 연속/비연속 적으로 할당된 경우에는 할당된 크러스터 주소와 크기 정보를 포함하는 데이터 입니다.
RunList: Cluster Run의 데이터를 효율적으로 표기하는 방식입니다.
NTFS는 RunList를 참조해서 Cluster Run데이터를 추출하고, 추출된 Cluster Run 데이터로 할당된 클러스터에 접근합니다. Cluster Run 시작 주소는 Attribute 시작주소 + Offset of RunList 입니다.
이와 바탕으로 구조를 만들면..
이렇게 Data Run의 첫바이트 기준으로 Data Run Length, Data Run Offset의 길이가 정해집니다.

Logical Cluster Number : 볼륨의 첫 번째 클러스터 부터 순차적 번호 = Data Run Length
Virtual Cluster Number : 파일의 첫 번째 클러스터 부터 순차적 번호 = Data Run Length
첫 바이트가 위의 데이터 처럼 0x33이라 한다면 Data Run Length 길이는 3byte, Data Run Offset 도 3byte입니다.
'Field > Digital Forensic' 카테고리의 다른 글
| [Forensic] Registry (0) | 2025.10.01 |
|---|---|
| [Forensic] Windows Artifact (0) | 2025.09.29 |
| [Forensic] FAT32 Analysis (0) | 2025.09.19 |
| [Forensic] MBR, VBR (0) | 2025.06.18 |
| [Forensic] 파일 시스템 (1) | 2025.06.12 |