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 데이터 구조 - 인덱스 속성과 데이터 구조 본문

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

NTFS 데이터 구조 - 인덱스 속성과 데이터 구조

Pikigod 2020. 3. 13. 18:07

13.3 인덱스 속성과 데이터 구조

- 이전 절에서는 모든 파일에 적용한 속성과 개념을 다루었다. 이번 절에서는 데이터 구조체 및 인덱스와 관련있는 속성들에 대해 상세히 살펴본다. 인덱스의 기본 개념은 정리된 트리에 데이터 구조체가 있다는 것이다. 그 트리는 한개 이상의 노드를 갖고, 각 노드는 한개 이상의 인덱스 엔트리를 갖는다. 트리는 루트 $INDEX_ROOT 속성에 위치하고, 다른 노드는 $INDEX_ALLOCATION 속성에 있는 인덱스 레코드에 위치한다. $BITMAP 속성은 인덱스 레코드들이 할당상태를 관리하기 위해 사용된다. 속성을 먼저 설명하고, 그 이후에 데이터 구조체를 설명한다.

 

 

$INDEX_ROOT 속성

- $INDEX_ROOT는 거주속성이고, 144타입 식별자를 갖는다. 이것은 항상 인덱스 트리의 루트이고, 오직 인덱스 엔트리들의 작은 목록만 저장할 수 있다. $INDEX_ROOT 속성은 16바이트 헤더를 갖는데, 노드헤더와 인덱스 엔트리 목록이 그 다음에 온다.

 

$INDEX_ROOT 속성의 내부 레이아웃

 

$INDEX_ROOT 헤더값은 아래 표와 같고, 속성 내용의 바이트 0에서 시작한다.

-> 데이터 구조체는 인덱스 엔트리가 저장할 속성 타입을 구별하고 그것들이 $INDEX_ALLOCATION 속성에서 어떻게 정렬되고 각 인덱스 레코드 크기가 얼마인지 알려준다. 바이트 8~11에 값은 바이트 크기이고 바이트 12는 크기의 로그이거나 클러스터 수이다. "$BOOT 파일" 절에서 이 인코딩 방법을 자세히 설명한다. 인덱스 레코드 크기 또한 부트섹터에서 주어진다. 

 

- icat 도구를 144타입을 지정해서 예제 이미지의 $INDEX_ROOT 속성 내용을 보도록하자.

 

#icat -f ntfs ntfs1.dd 7774-144 | xxd 

-> 바이트 0~3은 인덱스에 있는 속성이 $FILE_NAME 인 타입 48(0x30)이라는 것을 보여주고, 바이트 8~11은 인덱스 레코드가 4096바이트라는 것을 나타낸다.

 

 

▶ $INDEX_ALLOCATION 

- 큰 디렉토리는 인덱스 엔트리가 거주 $INDEX_ROOT 속성에는 적합하지 않기 때문에 비거주 $INDEX_ALLOCATION 속성이 필요하다. $INDEX_ALLOCATION 속성은 인덱스 레코드로 채워진다. 인덱스 레코드는 고정된 크기이고, 정렬된 트리에 한 노드를 저장한다. 

- 인덱스 레코드 크기는 $INDEX_ROOT 속성 헤더에 정의되어있고, 보통 4096바이트이다. 그 $INDEX_ALLOCATION 속성은 타입 식별자가 160이고, $INDEX_ROOT 속성 없이는 존재할 수 없다. 

- 각각의 인덱스 레코드는 특별한 헤더 데이터 구조체로 시작하고 다음으로 노드헤더와 인덱스 엔트리의 목록이 온다. 노드헤더와 인덱스 엔트리의 구조체는 $INDEX_ROOT 속성에서 사용된 구조체와 동일하다.

 

※ 다음 그림은 두 인덱스 레코드가 있는 $INDEX_ALLOCATION 속성을 나타낸다.

$INDEX_ALLOCATION 속성의 내부 레이아웃 - 여러개의 인덱스 레코드를 갖는다.

 

※ 인덱스 레코드 헤더의 값들은 아래 그림에서 볼 수 있다.

-> 첫 4개 필드는 MFT 엔트리를 위한 필드와 동일하지만, 시그니처는 다르다. (INDX) 관련 내용은 Fixup배열을 설명했던 이 장의 시작 부분을 보자.

-> 바이트 16~23 VCN값은 이 레코드가 어느 트리에 적합한지 알려준다. $INDEX_ALLOCATION 속성은 순서가 없는 인덱스 레코드들로 채워졌다. 헤더에 있는 VCN값은 이 인덱스 레코드들이 더 큰 버퍼 어디에 맞는지 구분해준다. 인덱스 레코드들이 자식 노드를 가리킬때 노드의 인덱스 레코드 헤더의 VCN 주소를 사용한다. 

 

※ INDEX_ROOT 조사시 보았던 디렉토리를 대상으로 $INDEX_ALLOCATION 속성 내용을 보도록하자.

-> 첫 줄에서 'INDX' 시그니처를 볼 수 있고, 바이트 4~5와 6~6은 fixup 레코드 값을 나타낸다. 바이트 15~23은 인덱스 레코드 VCN 0 버퍼인 것을 확인할 수 있다. 노드헤더는 바이트 24에서 시작한다. 그 $INDEX_ALLOCATION 속성 크기는 8192바이트이므로, 다른 인덱스 레코드를 저장할 수 있는 공간이 있다. 그것은 바이트 4096에서 시작한다.

 

-> 시그니처 'INDX'가 있으며, 바이트 4112~4119는 이것이 VCN 4 라는 것을 보여준다. 이 예제는 이후에 노드 헤더와 인덱스 엔트리를 언급할 때 다시 설명하겠다.

 

 

$BITMAP 속성

- 이전 절에서는 두개의 4096 바이트 인덱스 레코드가 있는 $INDEX_ALLOCATION을 보았다. 일부 인덱스 레코드들은 사용중이지 않을 수 있다. $BITMAP 속성은 $INDEX_ALLOCATION 속성이 인덱스 레코드에 할당되었는지 추적하는데 사용된다. 보통 윈도우는 필요할때만 인덱스 레코드를 할당한다.

- 많은 파일을 삭제한 후나, 또는 각 클러스터가 한 인덱스 레코드들보다 큰 경우 디렉토리는 불필요한 레코드들을 가질 수 있다. 이 속성은 또한 각 MFT엔트리가 할당되었는지를 추적하기 위해 $MFT에 의해서 사용된다. 

- $BITMAP 속성은 176 타입 식별자를 가지고 있고 바이트들에 의해 구성되며 또 각 비트는 인덱스 레코드에 해당한다. 

 

※ 이전 디렉토리를 위한 $BITMAP 속성을 icat을 사용해 볼 수 있다.

 

# icat -f ntfs1.dd 7774-176 | xxd 

0000000 : 0300 0000 0000 0000

 

-> 바이트 0에 0x30, 바이너리로는 0000 0011이라는 값을 볼 수 있고 인덱스 레코드 0과 1에 할당이 되어 있는 모습을 보여준다.

 

 

▶ 인덱스 노드 헤더 데이터 구조체

- $INDEX_ROOT와 $INDEX_ALLOCATION 속성을 둘 다 같은 헤더 데이터를 갖고, 그 뒤에 노드헤더와 인덱스 엔트리가 있는 것을 보았다. 이 절에서는 노드 헤더 데이터 구조체를 설명한다. 이 헤더는 $INDEX_ROOT와 각 인덱스 레코드 데이터 구조체에 있고, 인덱스 엔트리 목록이 시작하고 끝나는 위치를 설명하는 데 사용된다.

 

※ 아래 그림에서 헤더필드를 보자.

<인덱스 노드 헤더의 데이터 구조체>

-> $INDEX_ROOT 노드를 위한 인덱스 엔트리는 노드 헤더 다음에 시작하지만, 인덱스 버퍼에 있는 인덱스 엔트리는 fixup값들 때문에 그렇지 않다. 지워진 인덱스 엔트리의 남은 데이터를 찾을 때 그 버퍼에서 사용된 위치 마지막과 할당된 버퍼 끝 사이의 데이터를 조사해야 한다.

-> 플래그 필드는 오직 한 개의 플래그만 갖고, 0x01플래그는 이 목록에 있는 엔트리에 의해 지정된 자식 노드들이 있을 때 설정된다. 

 

※ 이전 속성들을 확인해보자 $INDEX_ROOT속성은 아래와 같다.

-> 노드 헤더는 바이트 16에서 시작한다.($INDEX_ROOT니까) 바이트 16~19는 필드가 16바이트(0x10) 떨어진 바이트 32에서 시작하고 160바이트 떨어진 바이트 176에서 끝난다는 것을 보여준다. 이 경우에는 거주 속성이고, 그래서 가능한 작아야 하는 $INDEX_ROOT 속성에서 비롯되었기 때문에 할당된 공간과 사용된 공간이 동일하다. 바이트 28은 0x01플래그이므로, 노드($INDEX_ALLOCATION에 위치한)에 대한 자식 노드들이 있다.

 

※ $INDEX_ALLOCATION 속성을 보도록 하자.

-> 첫 24바이트들은 인덱스 레코드 헤더를 위한 것이고, 노드 헤더는 그 다음에 시작한다. 바이트 14~27은 인덱스 엔트리 리스트가 바이트 오프셋 40에서 시작한다는 것을 보여준다. 이것은 노드헤더 시작에서 상대적이므로, 24를 더해 64이다. 이는 인덱스 엔트리 목록이 인덱스 목록 헤더 바로 다음에 오지 않는 경우인데, fixup 레코드 배열이 인덱스 엔트리 목록 헤더와 실제 목록 사이에 있기 때문이다. 인덱스 레코드 헤더의 바이트 4~5는 fixup 배열이 오프셋 40(0x28)에 위치한다는 것을 보여준다.

- 바이트 28~31은 마지막 엔트리 끝 오프셋이 2296(0x08f8)이라는 것을 보여주고, 바이트 32~35는 할당된 리스트 버퍼 마지막 오프셋이 4072 바이트 라는 것을 나타낸다. 따라서 이러한 노드 엔트리가 저장되어있는 이름들을 갖는 파일들에 대한 데이터를 포함하는 버퍼에 사용되지 않는 공간 1776바이트가 있다. 바이트 36~39는 플래그 값이 0이라는 것을 보여주므로, 이 노드에 자식 노드들은 없다. 

 

 

일반 인덱스 엔트리 데이터 구조체

- 지금까지는 NTFS 인덱스들의 전반적인 개념을 언급했고, 이 절에서는 인덱스 엔트리 데이터에 대한 일반적인 구조체를 설명하도록 한다.

 

※ 인덱스 엔트리에 대한 표준 필드는 아래와 같다. 

-> 첫 8바이트는 인덱스 엔트리 데이터를 저장하기 위해서 사용된다. 바이트 8~9는 인덱스 엔트리가 얼마나 큰지를 정의한다. 그리고 바이트 10~11은 바이트 16에서 시작하는 인덱스 엔트리 내용의 길이를 나타낸다. 그 내용은 어떠한 데이터도 될 수 있다.

 

<인덱스 엔트리 플래그 필드의 플래그 값>

-> 인덱스 엔트리가 자식노드를 가질 때 0x01 플래그가 설정되고 자식노드의 VCN 주소는 인덱스 엔트리 마지막 8바이트에서 찾을 수 있다. 각 인덱스 레코드는 한개의 VCN을 갖는다는 것을 유념하자. 0x02 플래그는 그 필드의 마지막 엔트리일때 설정된다. 

 

 

디렉토리 인덱스 엔트리 데이터 구조체 

- 파일이름을 사용하는 디렉토리 인덱스는 특정 인덱스 엔트리 데이터 구조체를 갖는다. 이전 절에서 개괄적으로 설명한 기본 템플릿을 사용하고 파일참조주소, $FILE_NAME 속성을 포함한다.

 

각 인덱스 엔트리 필드들은 아래와 같다.

<디렉토리 인덱스 엔트리의 데이터 구조체>

- 파일 참조값은 이 인덱스 엔트리에 해당하는 MFT엔트리를 가리킨다. 두 플래그 값들은 자식노드가 있으면 0x01인 이 에트니를 적용하고, 목록의 마지막 엔트리면 0x02를 적용한다. 

 

앞에서 이미 부분적으로 살펴본 $INDEX_ROOT와 $INDEX_ALLOCATION 속성의 나머지를 보도록하자. $INDEX_ROOT속성 내용은 아래와 같다.

-> 첫 32바이트는 이미 해석을 했는데, 첫 16바이트는 $INDEX_ROOT 헤더이고 두 번째 16바이트는 노드헤더였다. 바이트 32~37은 이 엔트리가 MFT엔트리 7877(0x1ec5)를 위한 것임을 확인할 수 잇다. 바이트 40~45는 인덱스 엔트리 크기가 120바이트 인것을 알 수 있으므로, 바이트 152에서 끝난다. 바이트 26~27 속성의 크기는 90바이트(0x5a) 이다. 바이트 28에 플래그는 자식노드가 있다는 것을 나타내고, 그 자식노드는 엔트리의 마지막 8바이트에 주소가 있다.

-> $FILE_NAME 속성은 바이트 48~137에 위치한다. 바이트 144~151은 인덱스 엔트리에 마지막 바이트이고, 클러스터 0인 자식노드 VCN을 포함한다. 파일이름으로 'MASTER~1.TXT' 이름을 볼 수 있다. 바이트 152~175는 비어있는 인덱스 엔트리를 포함하고, 바이트 164에 플래그는 3으로서 목록 마지막임을 나타내고, 자식을 포함하는 것을 나타낸다. 이것들은 $INDEX_ALLOCATION 속성에서 보았던 두 인덱스 레코드이다.

 

이 속성의 레이아웃은 다음과 같다.

<예제 디렉토리에 있는 $INDEX_ROOT 속성의 레이아웃>

 

- $INDEX_ALLOCATION 속성에서도 각 인덱스 레코드에 같은 과정이 반복되고, 노드 헤더 다음에 흥미로운 데이터를 볼 수 있다. 인덱스 레코드에 0에 인덱스 엔트리는 오프셋 2296에 끝나지만 그 노드에 할당된 남은 1776바이트가 있으므로 거기에 지워진 파일 이름 정보가 있을 수 있다. 사용되지 않은 영역에서 유효한 인덱스 엔트리를 찾을 수 있다. 바이트 오프셋 2400은 다음과 같다.

-> 위 결과는 MFT엔트리 7870(0x1ebe)에 있는 파일의 인덱스이고, 그 파일 이름은 아래 그림에 $INDEX_ROOT 인덱스 엔트리와 $INDEX_ALLOCATION 인덱스 레코드 사이의 관계를 보여준다. 인덱스 루트 노드에는 2개의 엔트리가 있는 것을 볼 수 있다.

 

<예제에 있는 인덱스 엔트리의 레이아웃>


p.s 경제야 살아나라..