## Why MFT is important? MFT에서는 모든 파일의 모든 정보를 확인할 수 있다. 여기서 말하는 정보는 파일과 연관된 시간값이 될 수도 있고, 파일이 담고 있는 데이터의 위치를 알아낼 수도 있다. 제일 중요하게 생각될 수 있는 것은 파일의 시간 값이다. 포렌식 분석에 있어 파일의 수정시각, 생성시각을 토대로 논리적인 결과를 도출해 내는 과정은 매우 중요하다. 다른 부가적인 영역에 의존하지 않고, 특정 파일이 언제 수정되고, 생성되었는지 확인해볼 수 있다는 것의 의미는 생각보다 중요하다. 파일의 크기가 작은 경우 $MFT내에서도 파일이 담고 있는 데이터를 확인해 볼 수는 있지만 $MFT 파일 만으로는 부족하다. 그래서 단순히 $MFT는 단독적으로 사용되는 것은 아니고, 다른 부가적인 아티팩트를 분석하기 위한 수단으로 쓰인다. 단순히 이를 넘어서 삭제된 파일에 대한 엔트리가 $MFT 내에 남아있는 경우 삭제된 파일의 정보를 얻을 수 있기 때문에 분석의 목적에 따라 필수적으로 참고되어야 한다. > [!NOTE] > 유료 도구를 사용하는게 아니라면 일반적으로 모든 파일을 리스팅해서 보기 쉽지 않다. MFT를 별도로 분석하여 파일 테이블에 대한 리스트를 만들어 놓는다면 꽤나 분석할 때 요긴하게 사용할 수 있다. > ## What is MFT? MFT는 Master File Table의 약자이다. NTFS에서 파일을 관리할 때 파일 크기, 파일의 시간값 같은 파일의 기본적인 속성을 담고 있다. 담고 있는 모든 속성을 나열한 것은 아니지만 차차 어떤걸 가지고 있는지 알아보도록 하자. 하나의 파일에 대한 속성을 가지고 있는 레코드들의 집합인 “Table”(표)로 구성되게 된다. 즉 하나의 파일이 하나 이상의 레코드를 가진다는 의미이다. 파일이 꽤 많이 존재한다는 점에서 레코드 크기를 모르더라도 적지 않은 저장공간을 요할 것 같은 느낌이 들어야 한다. > [!NOTE] > 왜 하나가 아닌 하나 **이상** 인지는 [[MFT Attribute (2)#$DATA(0x80)]]를 읽다 보면 파악할 수 있을 것이다. > ## MFT 구조 MFT의 구조는 아래 사진과 같이 여러 엔트리로 구성되어 있다. 하나의 엔트리는 헤더(HDR)와 여러 속성(Attr)로 구성되어 있는데 헤더를 MFT Entry Header라 부른다. 각 속성에 대해서는 별도의 게시글로 다룰 예정이다. (양이 꽤 많다) ![[Untitled 12.png]] ### MFT Entry Offset 위 사진만 가지고는 MFT의 위치를 정확하게 파악하기 쉽지 않다. VBR 다음 영역인 것 까지만 알 수 있다.정확한 MFT의 시작 위치는 VBR에서 찾아볼 수 있다는 의미이다. [[VBR]] 에 자세한 내용을 적어 놓았으니 참고해서 보도록 하자. 0x30 오프셋에 있는 값이 MFT의 시작 클러스터 이므로, 다음 공식을 통해 계산할 수 있다. $MFTstart * Size(Cluster)$ MFT의 시작 위치를 찾았다면 대략적인 구조를 설명해 보겠다. 이 페이지에서는 MFT Entry 헤더 까지만 다루도록 하고, Attribute에 관련된 내용은 [[MFT Attribute (1)]]에서 이야기한다. ### MFT Entry Header ![[Untitled 13.png]] |Offset|Size|Value|Description| |---|---|---|---| |0x00|0x04|“FILE”,”BAAD”|시그니처 값| |0x04|0x02||Fixup Values| |0x06|0x02||Number of Fixeup Values| |0x08|0x08||$Logfile Sequence Number (LSN)| |0x10|0x02||Sequence| |0x12|0x02||Refence Count| |0x14|0x02||첫번째 Attribute의 위치 (오프셋)| |0x16|0x02||MFT Entry Flag <br>0x01 → MFT_RECORD_IN_USE <br>0x02 → MFT_RECORD_IS_DIRECTORY <br>0x04 → MFT_RECORD_IN_EXTEND <br>0x08 → MFT_RECORD_IS_VIEW_INDEX| |0x18|0x04||사용된 엔트리의 크기| |0x1C|0x04||전체 엔트리의 크기| |0x20|0x08||Base record file reference| |0x28|0x02||첫번째 속성 ID| > [!NOTE] **MFT Entry SEQ** > Seq는 1 바이트씩 증가하는 값인데, > 해당 엔트리가 할당 해제되어 유효하지 않은 경우에도 증가한다. > > 간접적으로 파일이 할당된 파일인지 할당 해제 된 파일인지 확인할 수 있는 지표이다. > > 물론 Flag 값 참조하는게 가장 정확하다. > ### Base Entry & Non-Base Entry 특정 파일에 대한 MFT Entry 크기가 큰 경우, 2개 이상의 MFT Entry를 할당받는 경우가 존재한다. 이때 첫번째 Entry를 Base MFT Entry라 하고, 나머지 Entry를 Non-Base MFT Entry라 한다. ![[Untitled 14.png]] Base Entry 의 경우 `Base record file reference` 값이 0으로 표시되며 0이 아닌 경우 Base Entry의 주소 값이 기록된다. 이때 주소값은 `File Reference Address`양식에 의해 참조되는 주소를 찾아야 한다. 파일 참조 주소는 16비트의 Sequence 번호와 48비트의 MFT Entry Address로 구성되어 있으며, Base Entry 주소는 다음 공식을 통해 계산할 수 있다. $Base Entry Address = MFTEntry Address * Entry Size$ > [!Question] 주소를 계산하는데 Sequence Number는 참조하지 않는데 왜 있는건가요? > > MFT Entry에서는 파일이 삭제됨에 따라 할당 해제되고, 다른 파일에 의해 재할당되는 등 교체 행위가 자주 이루어진다. 따라서 Entry의 주소만으로 해당 파일과 일치함을 보증할 수 없으며 매번 파일을 새로 할당할 때마다 증가하는 Sequence 번호를 통해 해당 파일이 참조되는 파일과 일치하는지 확인하기 위해 있는 것이다. > > 따라서 Base Entry Address를 찾은 다음 Non-Base Entry와 Sequence 번호가 일치하는지 확인하는 과정이 수행되어야 한다. **Sample** Base Entry ![[Untitled 15.png]] ``` Sequence Number : 0x01 Address : 0xB000 ``` Non-Base Entry ![[Untitled 16.png]] ``` MFT Entry Address : 0x2C Sequence Number : 0x01 Base MFT Entry Address : 0x2C * 0x400 = 0xB000 ``` ### Fixup-Arrary Fixup Array는 각 섹터의 데이터 무결성을 판단하기 위해서 사용되는 영역이다. 랜덤한 2바이트 값인 Fixup Value와 각 섹터의 마지막 2 바이트를 활용해 Array를 구성한다. 이때 각 섹터의 마지막 2 바이트는 Fixup Value와 교체되고, 원래 2바이트가 배열로 구성되는 것이다. 파일을 다시 읽을 때는 이 2바이트 값을 다시 치환한 상태로 읽으면 된다. 자세한 구조는 아래 사진과 같다. ![[Untitled 17.png]] MFT Entry의 경우 2개의 섹터를 사용하므로 배열 내에 2개의 Array가 구성되어 있다. ![[Untitled 18.png]] 각 섹터의 마지막 부분을 보면 다음과 같이 치환된 것을 확인할 수 있다. ![[Untitled 19.png]] ### Fixed Entries 각각의 엔트리는 특정 파일을 가르킨다. 시스템에서 지정하는 몇몇 파일은 파일시스템이 생성됨과 동시에 생성되므로, 특정 엔트리들은 레코드 번호가 예약되어 있다. 하나씩 알아보고 간단하게 설명한다. - 0번(0x00) : Master File Table ($MFT) 0번 엔트리로는 $MFT파일 자체를 지정해놓는다. 이를 통해서 Master File Table 역시 파일의 형태로 존재한다는 것을 알 수 있다. - 1번(0x01) : Master File Table Backup ($MFTMirr) 0번 엔트리에 대한 백업 파일이다. - 2번(0x02) : Log File ($Logfile) 파일의 메타데이터에 대한 트랜잭션 정보를 담고 있는 파일이다. 파일 수정, 생성, 이름 변경과 같은 이벤트 발생시 기록한다. 추후에 자세히 다뤄볼 것 같다. - 3번(0x03) : Volume ($Volume) 볼륨의 버전 정보, 식별자와 같은 정보를 담고 있는 영역이다. - 4번(0x04) : Attributes Definition ($AttrDef) 속성에 대한 식별자, 크기, 이름과 같은 정보가 들어있다. - 5번(0x05) : Root File Name Index ($) 루트 디렉토리이다. - 6번(0x06) : 클러스터 비트맵 ($Bitmap) NTFS에서는 볼륨 내 클러스터들의 할당 여부를 비트로 표시한다. $Bitmap은 각 클러스터의 사용 여부에 따라 0/1로 표시해놓은 파일이다. - 7번(0x07) : 부트섹터 ($Boot) - 8번(0x08) : 볼륨 내 Bad Cluster 정보 ($BadClus) - 9번(0x09) : Security Descriptor ($Secure) - 10번(0x0A) : 모든 유니코드의 대문자를 저장 ($Upcase) - 11번(0x0B) : 파일의 추가적인 정보를 저장하는 영역 ($Extend) - 12 - 15번 : 사용하지 않는 영역 이외에도 $ObjId, $Quota, $Reparse, $UsnJrnl 과 같은 엔트리를 저장하고 있다. ## 분석 도구 1. FTK Imager** FTK Imager와 같은 파일시스템 분석 도구를 이용하여 $MFT를 파일의 형태로 추출할 수 있다. 2. **analyzeMFT** https://github.com/dkovar/analyzeMFT **3. MFTECmd** https://github.com/EricZimmerman/MFTECmd ## Conclusion 대략적으로 MFT가 무엇이고 어떤 상황에서 활용할 수 있는지를 알아보았다. 파일시스템 내부의 모든 파일에 대한 정보를 가지고 있는 영역으로, 포렌식 분석에 있어 필수적으로 다루어져야 하는 요소이다. 대부분의 도구들에서는 MFT에 대한 분석을 이미 지원하므로 접해보기 쉬웠을 것이나, 구체적으로 분석해 볼 필요가 있다고 느껴지는 영역이다. 다음에는 $MFT 파일의 각각의 구조와 속성에 대해서 자세하기 이야기해보도록 할 것이다.