NTFS 분석
포맷한 직후의 USB를 FTK Imager를 통해서 이미지로 만든다.
FTK Imager는 최대 1.5GB 단위로 파일을 쪼개 저장한다.
따라서 4GB의 파티션만 이미징하기 때문에 아래 사진과 같이 총 3개의 파일이 생성되며, .txt 파일은 이미지 세트에 대한 메타데이터가 적혀 있다.
FTK Imager에서는 .001 파일만 선택해도 자동으로 모든 파일을 합쳐서 하나의 완성된 디스크 이미지로 본다.
하지만 NTFS Parser를 만들 때를 위하여 하나로 합치는 방법을 사용하자.
copy /b USB_Initial_NTFS.001 + USB_Initial_NTFS.002 + USB_Initial_NTFS.003 USB_Initial_NTFS_combined.img
cmd에서 위 명령어를 통해 하나의 파일로 합칠 수 있다.
합친 파일을 HxD로 열어보자.
NTFS
NTFS는 VBR(Volume Boot Record)로 시작하는 데, VBR은 섹터 단위로 존재한다. NTFS에서는 보통 섹터의 크기가 512바이트이므로, VBR은 512바이트를 가진다.
VBR은 크게 Boot Sector와 NTLDR Information Boot Strap으로 나눌 수 있다.
Boot Sector는 BPB(BIOS Parameter Block)와 Bootstrap Code, Signature로 나뉜다.
BPB는 0x0B에서 시작하며 대략 0x50의 크기를 가지고, NTFS 구조(섹터 크기, 클러스터 수, $MFT 위치 등)를 정의하는 데이터이다.
Boot Code는 BPB 이후부터 0x1FD까지 차지하며, 실제 부트 과정에서 실행되는 코드이다.
위 내용을 가지고 VBR를 분석해 보자. 이때 리틀 엔디안으로 작성되어 있음을 유의하자.
다음은 BPB 영역의 중요 부분을 정리한 내용이다.
- 0x0B ~ 0x0C는 섹터당 바이트 수를 의미한다. 따라서 한 섹터당 0x200바이트(512)임을 알 수 있다.
- 0x0D는 클러스터당 섹터 수를 의미한다. 따라서 한 클러스터당 0x08개의 섹터임을 알 수 있다. 따라서 한 클러스터는 4096바이트(4KB)를 차지한다.
- 0x28 ~ 0x2F는 총 섹터 수를 의미한다. 따라서 총 섹터는 0x7FFFFF개(8,388,607)임을 알 수 있다. 이를 통해 전체 용량을 계산해 보면 8,388,607 x 512byte인 4,294,966,784byte가 된다. 따라서 초기에 설정한 4GB와 거의 일치하는 것을 볼 수 있다.
- 0x30 ~ 0x37은 $MFT의 시작 주소를 의미한다. (해당 값 x 클러스터당 섹터 수) + Boot Record의 위치로 계산할 수 있다. 값이 0x40000(262,144)이므로, (0x40000 x 0x08) + Boot Record 위치임을 알 수 있다. 여기서 VBR은 항상 파티션의 시작에 위치함으로 $MFT의 시작 주소는 0x200000번째 섹터임을 알 수 있다. 따라서 실제 주소는 여기에 512를 곱한 0x40000000(1,073,741,824byte = 1GB)에 위치한다.
0x54부터는 Boot Code에 해당한다. VBR은 마지막 2바이트(55 AA)의 시그니처를 통해 끝을 확인할 수 있다.
NTLDR Information Boot Strap은 Windows NT 계열(예: XP, 7 등)이 부팅할 때 필요한 부트로더(NTLDR, 이후 BOOTMGR)에 필수적인 정보를 담고 있는 특별한 데이터 영역을 말한다. 보통 BOOTMGR(Boot Manager)로 시작한다.
MFT
MFT는 NTFS의 핵심으로 파일 및 디렉터리의 변경 등 여러 정보가 기록되며 파일 레코드라고도 불린다.
MFT 영역은 각각 1024바이트인 여러 개의 MFT 엔트리로 이루어져 있다. MFT 엔트리는 파일이나 디렉터리가 생성될 때마다 생성되어 생성된 파일이나 디렉터리를 관리하기 위한 메타데이터를 저장하고 있다. 따라서 숨긴 파일을 찾거나, 파일의 복사, 삭제 등을 알아보거나 타임라인 분석 등 디지털 포렌식 조사에 있어 중요하다.
MFT Entry 0번에서 23번은 파일시스템 생성 시 파일시스템 자체의 메타데이터를 관리하기 위해 예약된 엔트리이다.
MFT 엔트리 0번부터 3번까지 살펴보면 MFT 엔트리 0번은 $MFT 파일로 MFT 영역의 크기, 위치, 할당 정보 등 MFT 영역 파일에 대한 MFT 엔트리이다.
MFT 엔트리 1번은 $MFTMirr으로 $MFT의 일부 백업본으로 $MFT의 0-3번의 엔트리를 복사, 저장하고 있다. $MFT가 손상이 되었을 때 이 $MFTMirr를 사용하여 복구하는 목적이다.
MFT 엔트리 2번은 $LogFile으로 파일의 생성, 변경, 삭제, 이름 변경 등 MFT 엔트리에 영향을 주는 사항을 기록해 두어서 트랜잭션이 정상 완료되지 못하는 경우 시스템 재부팅 시 복구에 도움을 준다.
이전에 계산해 두었던 $MFT의 시작 주소인 0x40000000에 가보자.
위 사진은 0번 엔트리인 $MFT 파일이다.
위 내용을 바탕으로 MFT를 분석해 보자.
- MFT Entry Header는 FILE로 시작한다.
- 0x2C ~ 0x2F는 MFT Entry Number를 의미한다. 따라서 0번 Entry임을 알 수 있다.
위는 1번 엔트리인 $MFTMirr임을 알 수 있다.
이제 파일을 생성한 뒤 다시 이미징하여 초기 이미징 파일과 비교해 보자.
다음과 같은 순서대로 파일을 생성, 삭제하였다.
- Hello NTFS 라는 내용을 가진 test1.txt 생성
- Go to Trash 라는 내용을 가진 test2.txt 생성
- test2.txt 삭제
26번 엔트리를 보면 작성한 test1.txt를 확인할 수 있다.
27번 엔트리에서는 test2.txt를 확인할 수 있다.
이때 0x16~0x17에 위치한 MFT Entry Flag가 0임을 통해 해당 파일이 삭제되었음을 알 수 있다.