Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

Piki's Play

NTFS 데이터 구조 - 파일시스템 메타데이터 파일 (1) 본문

포렌식/파일시스템 (파일시스템 포렌식분석)

NTFS 데이터 구조 - 파일시스템 메타데이터 파일 (1)

Pikigod 2020. 3. 15. 15:53

13.4 파일시스템 메타데이터 파일

- 앞에서 파일과 인덱스의 다양한 속성을 살펴보았고, 지금부터는 파일시스템 메타데이터 파일들에 대해 설명하겠다. 이들 대부분은 일반 파일 속성을 사용하지만 그 중 몇개는 자신만의 속성을 갖는다. 이 속성들에 대해서는 다음 절에 설명한다. 

 

 

$MFT 파일

- 속성 $MFT 파일은 MFT엔트리 0에 위치하고 파일 시스템 모든 파일에서 중요하기 때문에 이번 장 시작에서부터 언급을 하였다.

- $MFT의 고유한 한 속성은 MFT엔트리 할당상태를 관리하는 $BITMAP 속성이다. 그 속성들은 바이트들로 구성되고 한 비트가 1로 설정될 때 그 엔트리는 할당된 것이고, 그 반대로 비트가 0이면 엔트리는 할당되지 않은 것이다. icat 도구에 속성타입 176을 지정해서 $BITMAP 속성을 볼 수 있다. 

 

$MFT파일의 $BITMAP속성

-> 대부분의 비트들은 바이트 2를 제외하고 1로 설정되어있는 것을 확인할 수 있다. 이 바이트는 MFT엔트리 16~23에 해당한다. 

 

 

$Boot 파일

- $Boot 파일은 MFT엔트리 7에 해당하고 부트섹터와 $DATA 속성이 있는 부트코드를 포함한다. 이 속성은 항상 섹터 0에서 시작하고, 부트섹터 데이터 구조체가 위치한다.

<부트섹터의 데이터 구조체>

- 사용하지 않은 필드들은 FAT 부트섹터의 BIOS Parameter Block(BPB) 필드들에 해당한다. 윈도우는 이 값들이 0이아니면 디스크를 마운트 할 수 없다.

- 부트섹터에서 가장 중요한 값은 각 섹터와 클러스터 크기이다. 이것들 없이는 어떠한 위치도 확인할 수 없다. 다음으로 중요한 값은 MFT의 시작위치와 각 엔트리의 크기이다. 지금까지 MFT엔트리들은 항상 1024바이트였지만, 앞으로는 그 크기를 쉽게 변경할 수 있도록 이 필드가 존재한다. 또한 $MFTMirr의 $DATA 속성의 주소가 주어진다. 이 주소는 복구도구들이 $MFT엔트리의 백업본이 어디에 있는지 결정하도록해서 MFT의 위치를 판단할 수 있도록 한다. 

- MFT엔트리와 인덱스 레코드를 보여주는 특별한 필드들은 특별한 형식을 갖는다. 만약 그 값이 0보다 크면 각 데이터 구조체에서 사용되는 클러스터 수를 나타낸다. 만약 그 값이 0보다 작으면 각 데이터 구조체에 있는 바이트 수의 밑이 2인 로그를 포함한다. 

- 예를들어 그 값이 -10이면 데이터 구조 크기는 210=1024바이트이다. 이것은 클러스터 크기가 단일 MFT엔트리나 인덱스 레코드보다 클때 일어나는 일이다. 

 

부트섹터를 확실히 분석해보자. 12장에서 $Boot 파일에 istat 결과를 봤고 지금부터는 $DATA 속성(타입128)을 보기위해 icat을 사용한다. 

-> 첫 줄의 몇개의 ASCII공백(0x20) 뒤에 오는 'NTFS'라는 OEM 이름을 볼 수 있다. 이것은 윈도우에서 할당한 표준이름이다. 바이트 11~12를 보면 각 섹터수는 512(0x0200)바이트이다. 바이트 13은 클러스터의 크기를 나타내고, 두 섹터가 할당되어있어 각 클러스터는 1024바이트라는 것을 알 수 있다. 

-> 바이트 40~47는 파일시스템 전체 섹터수가 2056256(0x001f6040)라는 것, 즉 파일시스템이 1GB의 크기를 갖는다는 것을 알 수 있다. 바이트 48-55는 342,709(0x00053ab5)인 MFT의 시작 클러스터이고, 바이트 64는 각 MFT엔트리 크기를 보여준다. 이 값의 인코딩은 음수 또는 양수에 의존한다. 이 경우 1이므로 MFT엔트리의 클러스터 수는 1024 바이트이다. 바이트 68은 디렉토리에서 사용되는 각 인덱스 레코드 크기이다. 이 값은 4이므로 인덱스 레코드당 4개의 클러스터들이 있다. 바이트 72~79는 0x0450228450227c94인 파일시스템의 일련번호이다. 그 바이트들의 나머지는 부트코드이고, 바이트 510~511은 FAT에서도 보았던 0xAA55 시그니처이다.

 

 

$AttrDef 파일

- $AttrDef 파일시스템 메타데이터 파일은 MFT엔트리 번호가 4이고, 파일시스템 속성 이름과 식별자를 정의한다. 이 파일의 $DATA 속성은 엔트리의 목록을 포함하고 관련 필드들은 아래와 같다.

 

<$AttrDef 엔트리의 데이터 구조체>

-> 만약 속성크기가 제한되어있지 않다면 최소크기 0, 최대크기는 0xffffffffffffffff일것이다. 

 

플래그 필드는 아래표와 같은 값들을 갖는다.

<$AttrDef 엔트리 플래그 필드의 플래그 값>

- 속성이 인덱스에 있을 때 정렬규칙을 사용한다. 정렬 규칙은 속성이 어떻게 정렬되어야 하는지 결정한다.

 

※ $AttrDef 파일의 $DATA 속성은 다음과 같다.

-> 첫번째 속성은 $STANDARD_INFORMATION이다. 바이트 128~131은 16(0x10)이라는 속성 타입을 나타낸다. 바이트 140~143플래그는 이 엔트리가 항상 거주임을 나타낸다. 바이트 144~151은 이 속성의 최소크기가 48(0x30)바이트이고, 최대크기는 72(0x48)바이트라는 것을 보여준다. 

 

 

▶ $BITMAP 파일

- MFT엔트리 6에 위치한 $BITMAP파일은 클러스터 할당상태를 관리하고 $DATA 속성을 갖는다. 비트맵 데이터는 1바이트 값들로 구성되고, 각 바이트 최하위비트는 이전 바이트의 최상위 비트에 해당하는 클러스터 다음에 오는 클러스터에 해당한다. 

- 예를들어 바이너리 값 00000001 과 00000011을 고려해보자. 첫 바이트는 클러스터 0에 해당하는 최하위 비트가 1이다. 그다음 7개는 모두 0이기 때문에 클러스터 0에 해당하는 최하위 비트가 1이다. 그 다음 7개는 모두 0이기 때문에 1~7은 할당되지 않았음을 알 수 있다. 두번째 바이트의 최하위 비트 2개가 1이므로 클러스터 8과 9는 할당이 되었음을 알 수 있다. 최하위 비트에서 이것들을 확인하기 위해 오른쪽에서 왼쪽으로 읽고, 그러고나서 오른쪽 바이트로 이동한다.

- 주어진 클러스터의 할당상태를 결정하기 위해 그것이 위치한 비트맵의 바이트를 결정하는 것이 필요하다. 이것은 클러스터 주소를 8로 나누고, 나머지는 무시한다. 예를들어 클러스터 5는 비트맵 바이트 0에 있고, 클러스터 18은 비트맵 바이트 2에 있다. 그 클러스터에 해당하는 바이트에 그 비트를 찾기 위해 그 나머지를 조사한다. 예를들어 5를 8로 나누면 나머지 5를 갖고, 18을 8로 나누면 나머지 2를 갖는다. 

 

※ 아래 그림은 비트맵에 5와 74의 위치를 계산하는 예를 설명한다.

<비트맵에서 클러스터 5와 74의 할당상태를 찾기 위한 예>

 

※ 아래 그림은 icat을 이용해 $DATA 속성의 내용을 조사한 예이다.

-> 부트섹터가 파일시스템의 첫 8KB에 위치하므로(?) 위 결과에서 초기 비트들은 모두 1이고 이것은 모두 할당됐다고 판단할 수 있다. 결과의 바이트 11에서 바이너리로 00111111 값 0x3f를 볼 수 있다. 이 바이트는 파일시스템 클러스터 88~95에 해당하고, 6개의 하위비트들은 할당 돼 1로 설정되어있다. 7번째와 8번째 비트들은 94~95에 해당하는 것으로 0으로 설정되어있다. 또 다음 6바이트들은 모두 0이므로, 이 비트들의 모든 클러스터들은 비할당 되어있다. 바이트 18에서 0xf0은 바이너리로 11110000인 것을 확인할 수 있다. 

 

 

$VOLUME 파일

- $VOLUME 파일은 MFT엔트리 3에 있고, 두 속성을 갖는다. 이 절에서는 $VOLUME 파일에 대해서 설명한다.

 

 

$VOLUME_NAME 속성

- $VOLUME_NAME 속성은 타입식별자 96을 갖고, 오직 $VOLUME 파일을 할당한 경우만 지원된다. UTF-16 유니코드 볼륨이름을 포함하는데 그 외에는 아무것도없다.  

 

※ 관련된 예제는 아래와 같다.

-> 이 파일시스템 볼륨이름은 'NTFS DISK 2'이다. 

 

 

▶ $VOLUME_INFORMATION 속성

- $VOLUME 파일에 두 번째 속성은 식별자 112를 갖는 $VOLUME_INFORMATION 속성이다. 이 속성은 파일시스템의 버전을 포함한다. 

 

아래 표에서 보자

<$VOLUME_INFORMATION 속성의 데이터 구조체>

 

- 윈도우 NT는 주버전 1과 부버전 2를 사용한다. 윈도우 2000은 주버전 3과 부버전 0을 사용한다. 윈도우xp는 주버전 3과 부버전 1을 사용한다.

 

아래에서 보여주는 플래그는 이 데이터 구조체에 적용된다.

 

※ 예제 파일시스템 $VOLUME_INFORMATION 속성은 다음과 같다.

 

# icat -f ntfs ntfs1.dd 3-112 | xxd

0000000 : 0000 0000 0000 0000 0301 0000 ...........

-> 바이트 8과 9는 이 파일시스템이 윈도우 xp 버전 3.1이라는 것을 확인할 수 있게 한다. 플래그들은 0으로 설정되어있다.

 

 

▶ $ObjId 파일

- 12장에서 파일이름 대신 오브젝트 ID를 통해서 파일을 식별할 수 있다고 하였다. 이 ID는 파일이름을 변경하더라도 여전히 그 파일을 찾을 수 있도록 한다. 그 인덱스는 일반적으로 $INDEX_ROOT와 $INDEX_ALLOCATION을 갖고 인덱스엔트리 필드는 아래와 같다.

 

- 자식노드가 존재하면 플래그는 0x01을 갖고, 인덱스 엔트리 목록에 마지막 엔트리일때는 0x02를 갖는다. 제거된 노드 헤더가 있는 $INDEX_ROOT 속성의 일부 인덱스들을 아래 예에서 볼 수 있다.

-> 바이트 8은 엔트리가 88바이트(0x58)인 것을 나타내고, 바이트 16~31에서 16바이트 오브젝트 id를 확인할 수 있다. 바이트 32~37은 이러한 오브젝트 ID를 위한 MFT엔트리 주소가 저장되어있다. 이것은 "$OBJECT_ID 속성" 절에서 보았던 $OBJECT_ID 속성의 인덱스 엔트리이다. ID필드의 나머지는 이 엔트리를 위한 것이고, 다음 엔트리는 바이트 88에서 시작한다.

 


p.s

 

1. $MFT 파일 : 모든 파일에서 중요함. 속에 bitmap같은 속성을 가진다.

2. $Boot 

3. $AttrDef : 파일 속성이름과 식별자를 정의

4. $Bitmap : 할당상태를 보여준다.

5. $Volume 파일