Ⅰ. 개요
DISK 샘플 이미지로 MBR, VBR 복원 실습을 해볼 예정이다. 복원한 후 FAT와 NTFS의 Data Area를 찾는 과정을 실습하고 구조가 어떻게 되어 있는지 살펴본다.
Ⅱ. DISK 실습 - MBR, VBR 복원
샘플 DISK 이미지를 가지고 HxD를 통해 VBR 백업을 통해 MBR, VBR을 복원해 볼 예정이다.


위 두 사진을 보면 MBR, VBR이 손상된 모습을 볼 수 있다. 보통 0번 섹터가 MBR 정보가 들어가 있는데, 512Byte로 구성된 MBR의 마지막 Partition 관련 정보가 다 날아간 것을 볼 수 있다. 이번 복원 실습은 첫 번째, VBR의 백업 섹터를 찾아간다. 두 번째, VBR에서 해당 파티션이 NTFS인지 FAT인지 구분한다. 세 번째, VBR에서 해당 파티션의 전체 섹터 크기를 구해서 계산을 통해 원본 VBR의 위치를 구한다. 네 번째, 백업 VBR 섹터를 원본 VBR 위치에 복사해서 되살리고 관련 정보를 바탕으로 MBR의 파티션 정보를 복구한다. 이 순서대로 진행될 예정이다.
VBR 백업 섹터 찾기
VBR의 백업 섹터를 찾는 방법은 여러 가지 있을 것이다. 그 중에 시그니쳐(Signature)를 통해 찾는 방법을 소개하고자 한다. HxD에서 16진수 55 AA를 검색해보면

이렇게 나온다. 검색된 것들을 하나씩 찾아가다 보면

이렇게 마지막 2Byte가 55 AA이고 'Uª'를 볼 수 있는 데 이게 바로 시그니쳐이다. 단순히 문자 형태를 볼 게 아니라 16진수 55 AA가 시그니쳐임을 기억하면 좋다. 위에 빨간색 부분을 보면 NTFS임을 알 수 있는데, NTFS VBR 구조는 관련 블로그들이 많으니 참고하면 더 잘 이해할 수 있을거라 생각한다.
NTFS VBR 복원하기
NTFS의 경우 일반적으로 백업 섹터가 NTFS 파티션의 가장 마지막 섹터가 된다. 그래서 해당 백업 섹터에서 파티션 섹터 크기를 구할 수 있으면, 원본 백업 섹터의 위치를 알 수 있다.

이 구조를 보면, VBR의 0x20의 8~15사이의 총 8Byte길이로 Total Sectors의 정보가 담겨 있는 모습을 볼 수 있을 것이다.

그렇다면 위 사진에서 리틀 엔디안으로 A67FF가 해당 파티션의 총 섹터 수 인데 계산해보면, '681,983'이란 값이 나온다. 현재 백업 섹터의 위치가 '682,111'이므로 이 값에서 총 섹터 수를 빼보면, '128'이 나오는 데 이게 원본 VBR의 시작 섹터이다.


이렇게 백업 VBR을 복사 후 섹터 128 위치에 붙여 넣어주고 저장하면 된다.
NTFS 파티션 MBR 복원하기
이제 이 값들을 가지고 MBR을 복원할 예정이다.
[SK쉴더스 SeSAC 성동1기] ZIP 구조체, DISK
지난 게시글을 참고해보면, MBR의 446Byte부터 510Byte까지 각 파티션의 정보가 16Byte 단위로 들어가 있다고 했다. 128 섹터부터 시작하는 NTFS 파티션을 MBR의 첫 번째 16Byte에 각각 필요한 정보를 대입해줄 예정이다. 사실 16Byte에서 1Byte, 4Byte, 8~11Byte, 12~16Byte외에는 필요없으므로 이 정보들만 다시 입력해줄텐데, 1Byte의 Boot Flag는 80으로 바꿔주고, 4Byte의 파일 시스템 타입은 NTFS를 의미하는 07로 바꿔준다. 8~11Byte의 파티션 시작 주소는 128 섹터를 16진수로 변환한 80을 넣어줄 예정이고 마지막 12~16Byte는 파티션의 크기인 A67FF를 넣어줄 예정이다.
※ 대입할 때 주의할 점은 지금 리틀 엔디안으로 읽은 것이기 때문에 실제로 표기하는 방식은 빅엔디안이다.

이렇게 대입하고 저장해주고 FTK Imager로 복원이 잘 되었는지 확인해보면,

이렇게 복원이 잘 된 모습을 볼 수 있다. 그렇다면 FAT도 마찬가지로 진행해주면 될텐데,
FAT 복원 진행

이렇게 백업 VBR을 찾고 여기서 -6만큼 이동한 '682,112'에 백업 VBR을 복사해서 붙여준다.

그 후 다시 MBR을 복원해보면, 부팅 플래그 80, 타입을 0B 혹은 0C, 시작 주소인 '682,112'를 변환한 A6880과 섹터 크기를 입력해주면 되는데,

출처 hec-ker.tistory.com / 아래 경로 첨부
위 구조에서 0x20에서 4Byte만큼 파티션 전체 섹터 크기가 있는 것을 보아 계산해보면, A6800이다. 이제 값을 MBR에 입력해보면,

이렇게 입력할 수 있을 것이다. 이제 저장 후 다시 FTK Imager로 확인해보면,

이렇게 잘 복원된 모습을 볼 수 있다.
Ⅲ. DISK 실습 - Data Area 찾기
먼저 FAT32의 DataArea를 찾는 방법은 지난 게시글에 잠깐 팁으로 남겼긴 했지만, FAT32는 구조가 VBR - 예약 영역 - FAT1 & FAT2 - MFT가 나온다. 그렇다면 VBR의 시작 섹터에서 예약 영역과 FAT1 & FAT2 섹터 크기를 더해준다면 Data Area의 위치가 나오는 것인가?

계산해보면, 예약 영역 섹터 수에 대한 정보는 0x0E~F가 가지고 있고 6,874이다. FAT 섹터 크기는 0x24~7이기 때문에, 659가 된다. 그러나 FAT1과 2가 있으므로 곱하기 2를 해준다면, 1,318이 된다. 이제 이 값을 모두 더하면 6,874 + 1,318 + 682,112(FAT - VBR의 시작 섹터) 690,304의 값이 나온다. 이제 그 섹터로 가보자.

이렇게 복원한 FAT32의 Data Area를 찾을 수 있었다. FAT32의 경우 Data Area의 구조는

출처 dotaky99.tistory.com / 아래 링크 첨부
[파일 시스템]FAT32 - 3편(Data Area, restore)
이렇게 되어 있다. 주의할 점은 SFN(Short File Name) 구조와 LFN(Long File Name)구조를 구분해야 하는데, 12Byte의 값을 통해 구분이 가능하다. 이 두 가지를 구분하는 이유는 구조가 달라지기 때문이다.

출처 blog.forensicresearch.kr / 아래 링크 첨부
디렉터리 엔트리 분석 [Directory Entry Analysis] - SFN, LFN
기본적으로 32Byte씩 구분되는데, SFN 구조는 아래와 같이 되어 있기 때문에 살펴보면 되겠지만 LFN의 경우 고려해야 할 게 늘어난다. 우선 32Byte 중에서 11Byte의 값이 0x0F라면 그 32Byte는 LFN 구조이다. 그 후 0x0 위치의 1Byte를 보면 Sequence Number라는 것을 알 수 있는데, 이 값이 중요하다.

위 사진을 보면, 시작 SeqNum이 42이인걸 알 수 있다. 그리고 12Byte는 0x0F인 걸 알 수 있다. 그렇다면 현재 표시한 위에서 부터 2줄은 LFN구조로 되어 있다. 밑에 32Byte도 마찬가지인데, SeqNum이 1인걸 알 수 있다. 이를 통해 결론부터 말하자면 LFN 구조가 2개로 구성된 파일인 것이다. 알 수 있는 방법은 SeqNum을 통해 알 수 있는데 여러 LFN 구조의 파일의 경우 제일 마지막에 32Byte 구조의 SeqNum이 0x40 or 연산이 되어 있다. 나머지 LFN 구조의 SeqNum은 0x01부터 1씩 증가하기 때문에 0x40이 넘는 값들은 0x40 or 연산을 통해 해당 파일의 LFN 구조가 몇 개인지 알려준다고 보면 된다. 그래서 0x42를 다시 XOR 연산을 해보면 2가 나오는 걸 알 수 있고 LFN 구조가 2개인 파일인 것이다.

위 예시 이미지에서도 마찬가지로 계산할 수 있으며, 3개의 LFN 구조를 가진 파일임을 알 수 있다.
NTFS의 경우 조금 다르다. NTFS의 파티션은 VBR과 MFT, Data Area를 가지고 있을텐데 조금 더 자세히 살펴보면, 하나의 VBR과 MFT가 있는데, 실질적으로 MFT는 여러 MFT Entry의 집합이다. MFT Entry는 각각 파일과 디렉토리에 대응한다. MFT Entry의 시그니쳐는 FILE로 Header 구조를 조금 더 자세히 살펴보면,

이렇게 되어 있다.
그렇다면 MFT Entry를 찾아가는 방법을 소개하고자 한다. 위의 NTFS VBR 구조를 참고하면 좋은데, 우리가 필요한 값은 1개의 섹터 당 몇 Byte인지 1개의 클러스터 당 섹터는 몇 개 인지, MFT Entry의 시작 클러스터 위치를 알아야 한다.

이 예시에서 필요한 3가지의 값은 저렇게 되어 있는데, 우선 200으로 1개의 섹터 당 Byte는 512Byte이다. 1개의 클러스터 당 섹터의 개수는 8로 8개이다. 이제 MFT Entry 시작 클러스터 위치는 6F00으로 정수 값으로 28,416이다. 그렇다면 실제 MFT Entry 시작 섹터의 위치는 어떻게 될까? 1개의 클러스터 당 8개의 섹터가 포함되어 있으므로 시작 클러스터 위치에 8을 곱해야 한다. 그 값은 227,328이 되고 현재 128섹터에서 시작하고 있으므로 128을 더해주면 227,456이 된다. 이제 해당 섹터로 이동해보면,

이렇게 MFT Entry의 시그니쳐(Signature)를 볼 수 있다. 이제 이 MFT Entry의 Header부분을 살펴보면, 총 48Byte로 구성되어 있는데,

우선 이 두 값을 보면, 첫 번째 빨간색 부분 24~27Byte에 해당하는 부분은 MFT Entry가 실제 사용 중인 크기이고 그 뒤로 28~31Byte는 MFT Entry에 할당된 크기로 총 1,024Byte(보통 이렇게 되어 있기도 하다.)를 보여주고 있다. MFT Entry는 하나의 파일 혹은 디렉토리에 대응한다. 그리고 2섹터(1,024Byte) 뒤로 가보면

다시 이렇게 MFT Entry가 시작되는 것을 알 수 있다. MFT Entry는 신뢰성을 높이기 위해 Fixup 구조를 MFT Entry Header 다음 부분에 두었는데, MFT Entry의 4~5Byte, 5~6Byte가 각각 Fixup 배열이 위치한 값, 배열의 길이를 의미한다. 16진수로 30과 3이므로 48Byte부터 시작해서 2Byte의 길이만큼이 Fixup값이 되고 이 값 이후로 아까 구한 길이의 3과 Fixup값이 2Byte씩이므로 곱하게 되면 6Byte가 Fixup 값에 의해 대체된 값을 저장하는 공간이 된다. 이 Fixup 값은 섹터의 내용이 비정상적으로 변경되거나 데이터를 해석하기 전 오류를 사전에 찾기 위한 값이다. 그 다음으로 속성 헤더와 내용이란 게 반복되는데, 관련해서 좋은 블로그를 소개한다.
[파일 시스템]NTFS - 3편(Attributes, $속성들)
후기
아마 다음 게시글이 이번 주 마지막 내용이 될 것 같습니다. 아직 NTFS의 MFT Entry내의 속성 구조를 정확히 이해하지 못했기 때문에 아쉬움이 많이 들긴 하지만, 워낙 방대한 양을 배우고 있어 앞으로 계속 채워나가야 겠다는 생각이 듭니다..
Log in