Test
$MFT, $LogFile, $J의 구체적은 구조, 생성, 삭제 과정을 확인하기 위해 파일 생성 및 삭제 과정을 시나리오 테스트로 진행하였다.
구체적인 시나리오는 'logo_image.png'라는 해당 블로그의 로고 이미지를 저장, 삭제, 휴지통 삭제의 세 가지 과정으로 진행하였다.
0. NTFS 구조
아래는 디스크의 MBR로 1번 Partition Table Entry만 존재하며, 해당 파티션의 Partition Type이 0x07(NTFS) 임을 확인할 수 있다. 추가로 Start Sector는 0x80(128) 번 섹터이다.
128번 섹터에 NTFS의 VBR이 존재한다. VBR의 BPB에서 $MTF Start Cluster 값(0x63 00 = 25,344)을 참조하여, $MFT 영역으로 접근한다. 202,880((25,344) x 8 + 128) 번 섹터이다.
202,880 섹터로 이동해 보면, $MFT Entry가 존재한다. $MFT Entry의 $DATA(0x80)은 Non-Resodent 속성으로 RunList(0x21 40 00 63)가 존재한다. RunList를 해석하면, $MFT의 데이터영역은 202,880(25344 x 8 +128) 번 섹터부터 + 512 섹터까지임을 알 수 있다. 202,880 섹터부터가 MFT Area이므로, $MFT Entry의 $DATA는 자기 자신을 가리킨다는 사실을 확인할 수 있다.
$LogFile의 MFT Entry는 2번 째로 생성되는 MFT Entry 이므로, 202,884(202,880 + (2 x 2))섹터에 존재한다. $LogFile의 MFT Entry에서 $DATA(0x80) Attribute를 참조하면 $LogFile의 실제 내용이 존재하는 영역에 접근할 수 있다. $DATA(0x80)은 Non-Resodent 속성으로 RunList(0x22 FC 02 00 60)가 존재한다. RunList를 해석하면, $LogFile의 데이터영역은 196,736(24,576 x 8 +128) 번 섹터부터 + 6,112 섹터까지임을 알 수 있다.
$J의 MFT Entry는 $UsnJrnl의 ADS로 저장되어 $J영역에 접근하려면 먼저 $UsnJrnl의 MFT Entry에 접근해야한다. $UsnJrnl의 MFT Entry는 202,952(내리면서 찾아야 한다.) 섹터에 존재한다. $UsnJrnl의 MFT Entry에서 $DATA(0x80) Attribute를 참조하면 $J의 실제 내용이 존재하는 영역에 접근할 수 있다. 추가적으로 $Max $DATA(0x80)은 Non-Resodent 속성으로 RunList(0x21 40 88 05)가 존재한다. RunList를 해석하면, $J의 데이터영역은 11,456(1416 x 8 +128)번 섹터부터 + 512섹터 까지임을 알 수 있다.
획득한 정보를 아래의 표로 정리해 보았다.
Starting Sector | Name |
202,880 | $MFT |
196,736 | $LogFile |
11,456 | $J |
1. 파일 저장
파일 저장 MFT 분석
파일 저장 전 마지막 MFT Entry는 202,958번 섹터에 존재했다. 'logo_image.png'파일을 저장하고, 4개의 MFT Entry가 생성되었다. 아래는 새롭게 생성된 MFT Entry의 섹터 번호와 이름을 정리한 표이다. 디스크를 초기화하고 처음으로 파일을 저장될 때, 자동으로 생성되는 3개의 MFT Entry로 추측된다.
Starting Sector | Name |
202,960 | logo_image.png |
202,962 | $RECYCLE.BIN |
202,964 | S-1-5-2-1-2943158171-4104640963-3374080612-1001 |
202,966 |
desktop.ini |
아래는 'logo_image.png'파일 저장 시 생성된 MFT Entry인 202,960번 섹터의 MFT Entry이다.
$STANDARD_INFORMATION(0x10): MAC time, MFT Modified time
$FILE_NAME(0x30): Parent File Reference Address가 0x05이므로 다섯 번째 $MFT Entry가 해당 파일의 상위 디렉터리임을 의미한다. 5번째 MFT Entry는 Root Directory로 해당 예시에서는 Root Directory에 바로 저장하였음을 알 수 있다. 추가적으로 202,890(202,880 + (2 x 5))의 MFT Entry에서 $INDEX_ALLOCATION(0xA0) 속성의 RunList(0x11 01 24)를 찾아가보면 'logo_image.png'파일이 Index로 생성되었음을 확인할 수 있다.
$DATA(0x80): 이미지 파일은 데이터가 크기때문에, Non-Resident 속성임을 확인할 수 있다. 추가로 해당 파일의 실제 데이터가 존재하는 영역의 주소를 담는 RunList(0x21 22 C8 05)가 존재한다. RunList를 해석하면, 11,968((1480 x 8) + 128) 번 섹터이다. 해당 섹터에 png파일의 헤더시그니처가 존재하는 모습을 확인할 수 있다.
$RECYCLE.BIN의 특징으로 $INDEX_ROOT(0x90) 속성에 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'가 존재한다. 이를 통해 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'가 휴지통 Root Directory이하에 존재하는 파일임을 확인 할 수 있다.
'S-1-5-2-1-2943158171-4104640963-3374080612-1001'의 특징으로 $INDEX_ROOT(0x90) 속성에 'desktop.ini'가 존재한다. 이를 통해 'desktop.ini'가 'S-1-5-2-1-2943158171-4104640963-3374080612-1001' Root Directory이하에 존재하는 파일임을 확인 할 수 있다. 또한 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'의 File Reference Address가 0x29인 점을 통해 상위 디렉터리가 '$RECYCLE.BIN'임을 추가 확인 할 수 있다.
'desktop.ini'의 특징으로 $DATA(0x80) 속성에 'ShellClass~'가 존재한다. 또한 'desktop.ini'의 File Reference Address가 0x2A인 점을 통해 상위 디렉터리가 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'임을 추가 확인 할 수 있다.
파일 저장 $LogFile 분석
먼저 $LogFile의 변화이다. Undo Op값이 MTF Entry의 신규 할당을 의미하는 값인 0x02(연두색) 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x05로 Root Directory라는 점과 파일의 이름이 'logo_image.png'라는 사실을 확인할 수 있다. 또한 중요한 정보인 RunList(연두색) 정보 또한 확인할 수 있다. 이는 파일이 삭제되고 MFT Entry가 덮어 씌어 MFT 분석이 불가능 한 상황에서 파일 복구를 가능하게 해주는 중요한 정보가 된다.
파일 저장 $J 분석
각각의 Record(파란색)를 구분해 두었다.
Record 1: Flag(연두색) 값이 파일 혹은 디렉터리 생성을 의미하는 0x100 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x05로 Root Directory라는 점과 파일의 이름이 'logo_image.png'라는 사실을 확인할 수 있다.
Record 2: Flag(연두색) 값이 $Data에 데이터 작성을 의미하는 0x02 값을 가지는 Record(파란색)가 새롭게 생성된다. 이전의 Record Flag값(0x100)에서 현재 Record Flag값을 빼서 계산해야 한다. 이때 Parent File Reference Address와 파일의 이름은 동일하다. (이하 동일 부분 생략)
Record 3: Flag(연두색) 값이 데이터 Over Write를 의미하는 0x01값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 4: Flag(연두색) 값이 속성변경을 의미하는 0x8000값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 5: Flag(연두색)값이 파일 혹은 디렉터리 닫힘을 의미하는 0x80000000 값을 가지는 Record(파란색)가 새롭게 생성된다.
2. 파일 삭제
파일 삭제 MFT 분석
202,960번 섹터 'logo_image.png'파일을 저장하는 MFT Entry가 '$R + [Random string]'을 이름으로 저장하는 MFT Entry로 변경되었고, 202,968번 섹터가 새롭게 '$I + [Random string]'을 저장하는 MFT Entry로 생성되었다. '$R + [Random string]' 파일과 '$I + [Random string]'파일은 특정 파일을 삭제할 때마다 생성되는 파일로, 운영체제가 식별을 위해 [Random string]을 사용하며 하나의 파일은 동일한 쌍의 [Random string]을 갖는다. '$R + [Random string]' 파일은 실제 파일 데이터와 실제 파일의 메타 데이터를 저장하고, '$I + [Random string]' 파일은 실제 파일 이름과 삭제 시간 메타 데이터를 저장한다.
Starting Sector | Name |
202,960 | logo_image.png → $R [Random string] 변경 |
202,962 | $RECYCLE.BIN |
202,964 (0x2A) | S-1-5-2-1-2943158171-4104640963-3374080612-1001 |
202,966 |
desktop.ini |
202,968 | $I [Random string] 생성 |
$STANDARD_INFORMATION(0x10): MAC time, MFT Modified time
$FILE_NAME(0x30): Parent File Reference Address가 0x2A이므로 휴지통 이하의 디렉터리인 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'가 해당 파일의 상위 디렉터리임을 의미한다. 해당 상위 MFT Entry에서 $INDEX_ALLOCATION (0xA0) 속성에 '$R', '$I'파일이 Index로 생성되었음을 확인할 수 있다.
$DATA(0x80): 이미지 파일은 데이터가 크기때문에, '$R'파일이 Non-Resident 속성임을 확인할 수 있다. 추가로 해당 파일의 실제 데이터가 존재하는 영역의 주소를 담는 RunList(0x21 22 C8 05)가 존재한다. RunList를 해석하면, 11,968((1480 x 8) + 128) 번 섹터이다. 해당 섹터에 png파일의 헤더시그니처가 존재하는 모습을 확인할 수 있다. '$I'파일은 파일의 삭제 시간과 파일의 원래 저장 경로를 저장 한다. Parent File Reference Address가 존재하지 않는 특징이 있다.
파일 삭제 $LogFile 분석
먼저 $LogFile의 변화이다. Undo Op값이 MTF Entry의 신규 할당을 의미하는 값인 0x02(연두색) 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x2A로 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'라는 점과 파일의 이름이 '$I8IOOA3.png'라는 사실을 확인할 수 있다.
Undo Op, Redo Up값이 파일명 변경을 의미하는 값인 0x05, 0x06(연두색)값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x05에서 0x2A로 변경되었음을 알 수 있다. 또한 Root 디렉터리의 MFT 엔트리 $Index 속성에 인덱스 레코드 추가를 의미하는 0x0C(연두색)값을 가지는 Record(파란색)가 새롭게 생성된다.
파일 삭제 $J 분석
각각의 Record(파란색)를 구분해 두었다.
Record 1: Flag(연두색) 값이 파일 혹은 디렉터리 생성을 의미하는 0x100 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x2A로 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'라는 점과 파일의 이름이 '$I8IOOA3.png'라는 사실을 확인할 수 있다.
Record 2: Flag(연두색) 값이 $Data에 데이터 작성을 의미하는 0x02 값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 3: Flag(연두색)값이 파일 혹은 디렉터리 닫힘을 의미하는 0x80000000 값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 1: Flag(연두색) 값이 파일 이름 변경 전을 의미하는 0x1000 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x05로 Root Directory에 속해있는 파일이라는 점과 파일의 변경전 이름이 'logo_image.png'라는 사실을 확인할 수 있다.
Record 2: Flag(연두색) 값이 파일 이름 변경 후를 의미하는 0x2000 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x28로 'logo_image.png'파일이라는 점과 파일의 변경후 이름이 '$R8IOOA3.png'라는 사실을 확인할 수 있다. 이는 '$R8IOOA3.png'의 MFT Entry가 새롭게 생성된 것이 아닌, 'logo_image.png'의 MFT Entry가 '$R8IOOA3.png'로 이름이 변경되었다는 사실을 알 수 있다.
Record 3: Flag(연두색)값이 파일 혹은 디렉터리 닫힘을 의미하는 0x80000000 값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 4: Flag(연두색) 값이 파일 접근 권한변경을 의미하는 0x800값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 5: Flag(연두색)값이 파일 혹은 디렉터리 닫힘을 의미하는 0x80000000 값을 가지는 Record(파란색)가 새롭게 생성된다.
3. 파일 휴지통 삭제
파일 삭제 MFT 분석
202,960번 섹터 '$R + [Random string]'파일을 저장하는 MFT Entry와 202,968번 섹터 '$I + [Random string]'파일을 저장하는 MFT Entry가 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'이하 디렉터리 Index Attribute에서 삭제된다. 이는 $RECYCLE.BIN Directory이하에서 제외되었음을 의미한다.
Starting Sector | Name |
202,960 | logo_image.png → $R [Random string] 변경 |
202,962 | $RECYCLE.BIN |
202,964 (0x2A) | S-1-5-2-1-2943158171-4104640963-3374080612-1001 |
202,966 |
desktop.ini |
202,968 | $I [Random string] 생성 |
아래는 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'이하 디렉터리 Index Attribute에 'desktop.ini'만 있는 상황이다.
파일 삭제 $LogFile 분석
먼저 $LogFile의 변화이다. Undo Op, Undo Op값이 MTF Entry의 파일 삭제를 의미하는 값인 0x03, 0x02(연두색) 값을 가지는 Record(파란색)가 새롭게 생성된다. 이때 Parent File Reference Address는 0x2A로 'S-1-5-2-1-2943158171-4104640963-3374080612-1001'라는 점과 파일의 이름이 '$I8IOOA3.png', '$R8IOOA3.png'라는 사실을 확인할 수 있다. 즉 'S-1-5-2-1-2943158171-4104640963-3374080612-1001' 폴더 이하의 '$I8IOOA3.png', '$R8IOOA3.png'파일이 순차적으로 삭제되었다.
파일 삭제 $J 분석
각각의 Record(파란색)를 구분해 두었다.
Record 1: Flag(연두색) 값이 파일 혹은 디렉터리 삭제를 의미하는 0x200 값을 가지는 Record(파란색)가 새롭게 생성된다.
Record 2: Flag(연두색)값이 파일 혹은 디렉터리 닫힘을 의미하는 0x80000000 값을 가지는 Record(파란색)가 새롭게 생성된다.
Conclusion
NTFS의 파일 생성, 삭제과정은 복잡하기 때문에 최종적으로 분석 결과를 정리 요약해 보았다.
1. 파일 저장
디스크를 처음 초기화하고 파일을 저장하면, 4개의 MFT Entry가 생성된다. 이때 가장 먼저 생성되는 MFT Entry가 파일을 저장하는 MFT Entry이고, 나머지 3개의 MFT Entry는 휴지통 관련 MFT Entry이다. 3개의 MFT Entry는 서로 상위 구조로 연결되어 있다. 이때, $LogFile에 해당 파일의 실제 데이터 위치를 의미하는 RunList를 포함한 Record가 생성된다. 해당 레코드만 덮이지 않는다면 데이터 복구는 가능하다.
[그림 1]과 [그림 2]는 각각 MFT Entry 구조와 B-Tree의 Index 형태로 시각화 한 모습이다. B-Tree Index의 회색 Index는 새롭게 생성된 Index를 의미한다.
2. 파일 삭제
파일을 삭제하면 기존의 파일이 삭제되고, '$R' 파일, '$I' 파일이 'S-1-5-2-1-2943158171-4104640963-3374080612-1001' 폴더 이하에 생성된 것처럼 보이나, 실제로는 삭제된 파일의 MFT Entry가 '$R' 파일로 변경된 것이고, '$I' 파일만이 실제로 생성된 것이 정확한 설명이다. 이는 $LogFile, $J를 상세분석하면 알 수 있다.
3. 파일 휴지통 삭제
파일을 휴지통에서 추가적으로 삭제하면, 'S-1-5-2-1-2943158171-4104640963-3374080612-1001' 폴더 이하에 '$R' 파일, '$I' 파일이 Index에서 사라짐을 확인할 수 있다. 이때 '$R' 파일, '$I' 파일의 MFT Entry는 존재하나 새로운 MFT Entry가 할당되면 바로 덮어 써진다. 만약 '$R' 파일, '$I' 파일의 MFT Entry가 덮이고, $LogFile의 기록도 없다면, 복구는 처음부터 헤더 시그니처를 찾는 방법밖에 없어 보인다. 어떠한 이유로 복구해야 하는 파일의 MFT Entry가 덮이거나 사라졌다면, 복구하려는 파일에 해당하는 Record를 $LogFile에서 추가 분석하여, 복구에 성공할 수 있다. 또한 $J 파일을 통해 사용자의 정확한 Log기록을 분석할 수 있다.