이번 글에서 다루는 내용
NTFS 구조
NTFS 부트섹터
MFT 찾아가기
VBR 복원
NTFS 구조
모든 데이터는 파일 형태로 관리되며, VBR의 위치는 고정되어 있다. MFT의 시작은 일반적으로 VBR이후지만, 크기가 커지면서 데이터 영역에 추가로 할당되기도 한다. 참고로, NTFS는 N번 클러스터 * SPC하면 섹터위치로 이동한다.
MBR ~ MBR slack : ROM BIOS가 사용한다(섹터 단위).
클러스터는 OS 포맷할 때 쓴 것.
VBR(Volume Boot Record)
NTFS VBR의 구조는 다음과 같습니다. NTFS는 클러스터 단위를 사용한다고 했었습니다. VBR도 할당될 때 기본 클러스터 크기만큼(512) 할당이 됩니다. 보통 4K이므로 8개 섹터를 할당 받습니다.
Boot Sector
다음으로 Hex Editor로 열어본 NTFS 파일 시스템 입니다.
Jump Instruction : 첫 3바이트의 Jump Instruction은 NTFS "EB 52 90"이며, FAT12/16은 "EB 3C 90", FAT32는 "EB 58 90"입니다. FAT1편에 나와있습니다([파일 시스템]FAT32 - 1편(Reserved Area) (tistory.com)) BootStrap부분은 부트 섹터가 부족할 때 사용됩니다.
OEM ID(제조사 식별 값) : NTFS라고 표시. 가상 VMDK VBR도 나오곤 한다. 값이 바뀌면 마운트가 되지 않으니 수정하지 말 것. 문자열 NTFS검색으로도 찾아도 된다(하지만 무조건 부트섹터에 있는 것만은 아님). 정확도를 높이고자 하면 Jump Instruction 포함 11바이트 검색하면 정확도는 높아진다.
BIOS Parameter Block(BPB)
보통 BPB면 Bytes Per Sector부터 시작하지만 FAT에서도 그랬듯이 Jump Instruction부터 다 포함시켰다. 위 사진에는 봐야할 곳만 색칠을 해놓았다. Total Sectors는 4바이트에서 8바이트로 늘어났다. $MFT는 NTFS에서 제일 중요하다. 중요하다보니 $MFTMirr로 백업본을 두지 않았나 싶다. 모든 파일 및 폴더 정보를 가지고 있기 때문이다. 이 구조만 알면 모든 파일 테이블의 정보를 다 알 수 있다. 또한, BPB에서 중요하게 봐야될 정보는 Start Cluster for MFT 필드이다.
Bytes Per Secotr(BPS) : 보통 512
Sector Per Cluster : 보통 8(1 클러스터당 8섹터)
Reserced Sectors : NTFS는 없음(NTFS는 항상 파티션 맨 앞에 부트 섹터가 존재)
Media Description : 0xF8(고정식 디스크), 나머지 값은 플로피디스크 구분
Total Sectors : 해당 볼륨이 가지는 총 섹터 수
Start Cluster for $MFT : $MFT의 LBA 주소
Start Cluster for $MFTMirr : $MFTMirr의 LBA주소
Clusters Per MFT Record : MFT Record 크기, MFT Record는 MFT레코드의 묶음이다.
Cluster Per Index Buffer : 폴더 구조에서 사용되는 인덱스 버퍼의 크기
Volume Serial Number : 볼륨 시리얼 번호(포맷 때 마다 변경).
MFT Record : NTFS의 모든 파일은 반드시 하나의 MFT 레코드를 가진다. MFT Record로 자기 자신의 메타 정보를 표현한다.
그렇다면 이제 MFT 시작위치를 따라가볼까요? FAT편을 보고 오신 분은 물리디스크로 열어서 실습을 했었는데요, 이번에는 논리디스크로 열어서 실습하도록 하겠습니다.
MFT 클러스터 시작은 0x0C0000 클러스터부터 시작이군요. 섹터단위가 아니라서 한 번 더 계산을 해주어야 합니다. 1클러스터는 8섹터라고 했었죠? 0x0C0000 * 8을 해주면 0x600000(6,291,456)섹터가 됩니다. 만약 바이트로 넘어가고 싶다면 8섹터는 4096(0x1000)바이트이므로 0x0C0000 * 0x1000 = 0xC0000000(3,221,225,472) 값으로 이동하시면 됩니다. 아래 표를 참고해주세요. 원하시는 단위로 계산하시고 이동해주시면 됩니다. 물론 논리로 열었을 때 입니다. 물리로 여셨으면 기존 VBR위치를 더해주셔야 합니다.
위와 같이 계산하고 이동하시면 결과는 아래와 같습니다. 이 구조만 살아있다면 100% 복구가 가능합니다. 이 구조가 없다면 손상된 것이죠. 손상안된 부분만 복구가 가능하고, 나머지는 카빙해야 합니다. $MFT는 MFT 레코드의 연속이라고 했습니다. MFT 레코드의 시그니처는 FILE 이다. FILE을 시작으로 1024바이트(2섹터) 만큼 점프하면 FILE이 또 나온다. 이들을 묶은 것을 $MFT라고 한다.
그렇다면 MFTMirr는 어디에 있을까? BPB에서 MFT다음 8바이트가 MFTMirr 위치였다. MFTMirr의 값은 0x02이므로 섹터로 계산하면 8을 곱해주어야 한다. 즉 16섹터로 이동하면 된다.
MFTMirr는 MFT수 만큼 다 백업하지 않는다. MFT 위치가 0x0C0000으로 거의 고정되는 것처럼 MFTMirr도 특별한 이유가 없으면 2번째 클러스터에 위치한다. MFTMirr도 1024바이트 만큼 뒤에 반복적으로 4개가 나온다.
MFTMirr는 $MFT의 가장 앞쪽의 하나의 클러스터만 백업한다(4096바이트 - 4K). 제일 중요한 것은 MFT의 첫 레코드이기 때문이다.
NTFS VBR 복원
VBR-BS가 손상된 경우
백업 BS 존재 하는 경우
VBR-BS가 손상되었을 경우 볼륨 끝 백업 BS를 활용해준다. 백업 BS는 볼륨 마지막 섹터에 있으니 찾아가면 된다. 그러면 찾아가는 방법을 안내하고자 한다. 파티션 테이블 구조에서 마지막 4바이트가 크기인 것을 기억해야 한다.([Digital Forensic] MBR이란? (tistory.com)) 필자의 DOTAKY99의 파티션 테이블은 아래와 같다.
다시 설명하자면, VBR 위치에서 LBA 총 섹터 수 더하고 -1을 해주면 백업 BS가 나온다. 복사하여 그대로 붙여넣어주면 복구가 된다. 하지만 망치려고 하는 나쁜 사람들이 백업이 있다는 정보를 모르진 않을 것이다.
결론적으로 VBR BS 백업을 찾았으면 그대로 덮어써주면 복원이 된다. 중요한 부분은 백업 BS가 없을 때 이다.
백업 BS가 존재하지 않는 경우
이럴 때는 볼륨 내 BS를 검색해보는 방법을 가져야 한다. 사이즈가 크면 클수록 시간이 오래걸린다. 검색은 Jump Instruction부터 OEM ID를 포함시켜 검색하여 준다(EB 52 90 4E 54 46 53 20). 또는 직접 값을 필드에 하나하나 넣어주는 수동으로 복원하는 방법도 있다.
FAT32복원 글을 보신 분은 아시겠지만, NTFS도 마찬가지로 모든 필드를 다 채워줄 필요가 없습니다. 핵심만 잘 수동으로 입력해주면 FKT에서 마운트가 됩니다. 복구할 필드는 다음과 같습니다.
OEM ID : NTFS입니다. FAT32는 MSDOS5.0이었고, exFAT은 "EXFAT"입니다!
Bytes Per Sector : 보통 512(0x200) 입니다.
Secotors Per Cluster : 2GB이상 볼륨의 기본 클러스터 크기는 4096-byte입니다.
Total Sectors : 각 볼륨 구간을 식별하여 할당해주어야 합니다(BS탐색).
Start Cluster for $MFT : VBR이후 "FILE" 시그니처 검색하여 $MFT위치를 알아내야 합니다.
Start Cluster for $MFTMirr : $MFT와 같은 방법으로 찾아주시면 됩니다.Clusters(Bytes) Per File Record : 항상 F6(-10) 2의 10승 = 1024-byte입니다. FF가 -1로 표시 되므로 F6은 -10이 됩니다!
STEP 0 - VBR 위치 찾기
파티션 테이블에 의하면 128번 섹터에 위치하고 있다고 합니다. 백업 BS를 찾으려고 했지만 VBR위치 + 해당 파티션 크기 -1을 해도 백업본은 보이지 않습니다..!
다음은 NTFS라고 적혀 있어야 하는 곳이 말끔하게 비워져 있습니다. 이제부터 하나하나 채워나가 봅시다.
STEP 1 - OEM ID, Bytes Per Sector, Sector Per Cluster 채우기
OEM ID는 0x03~0x0A까지 채웠으며, BPS는 512바이트(0x200) 값으로 채웠고, SPC는 4096바이트 즉, 클러스터당 8섹터를 잡아먹고 있기 때문에 0x08로 채웠습니다. Reserved 는 안쓰니 당연히 0입니다.
STEP 2 - Start Cluster for $MFT, $MFTMirr 위치 찾기, Clusters Per MFT Record(F6)
$MFTMirr는 보통 2번 클러스터에 있다고 했습니다. 즉, 0x02 * 8섹터를 해주면 16섹터가 나오고, 기존 128섹터 위치에 더해주면 144섹터가 나옵니다. 이렇게 $MFTMirr도 확인해주실 수 있습니다. 한 번더 검색을 해봅시다.
$MFTMirr의 첫 레코드는 $MFT 첫 부분과 같을 것이라 생각하여 아래 해당 값을 검색하여 329168섹터를 찾아냈습니다. 기존 BS위치를 빼줘야 하므로 329,168 - 128 = 329,040이 나오며 여기서 나누기 8을 해주면 클러스터 값이 됩니다. 즉, Start Cluster for $MFT는 0xA0AA값이 나오게 됩니다.
마지막으로 Clusters Per MFT Record 값인 F6을 넣어주면 다음과 같이 마무리가 됩니다.
STEP 3 - Total Sectors
990,865 - 128 (VBR만 계산)을 계산하면 0x0F1E11 값이 나옵니다.
그러면 최종적으로 마지막 결과값은 아래와 같이 쓰여지게 됩니다.
마지막 2바이트 시그니처 55AA도 적어주는거 잊지마세요!
NTFS 2편은 MBR에 대해서 다루겠습니다!
'DFIR > DFIR' 카테고리의 다른 글
[파일 시스템]NTFS - 3편(Attributes, $속성들) (0) | 2021.11.12 |
---|---|
[파일 시스템]NTFS - 2편(MFT, Fixup array) (0) | 2021.11.12 |
[Digital Forensic] GPT란? (0) | 2021.11.12 |
[Digital Forensic] MBR이란? (0) | 2021.11.12 |
[디지털 포렌식] - PC 절전 모드 행위(2) (0) | 2021.11.12 |