DFIR/DFIR

[파일 시스템]FAT32 - 3편(Data Area, restore)

dotaky99 2021. 11. 12. 13:47
반응형

FAT32 - 3편에서 다룰 내용은 아래와 같습니다.
- 데이터 영역 찾기(파일 정보 담고 있는 곳)
- Data 영역에서의 시간 계산하기
- 파일의 직접 쓰여진 데이터 찾기(파일 내용을 담고 있는 곳)
- LFN(긴 파일 이름 엔트리)

FAT구조

FAT의 구조는 Reserved Area, FAT Area, Data Area로 나뉜다고 하였습니다. 또한, FAT Area에는 FAT Area#1, FAT Area#2 두 개로 구분되며, FAT Area#2는 FAT Area#1의 백업본이 있기 때문에 FAT Mirror라고 불린다고 했습니다.

FAT 데이터 영역

그렇다면 Data Area는 어떻게 구성되어 있을까요? 실제로 우리의 눈에 보이는 영역이라고도 할 수 있을 것 같습니다. 루트 디렉토리와 서브 디렉토리, 각종 파일정보들(파일 이름, 시간 정보, 클러스터 위치, 타입, 크기 등)이 존재합니다.

2편에서 알아봤듯이, 파일이 클러스터보다 사이즈가 크면 크기가 같은 클러스터를 더 할당 받는 것을 확인했습니다. 데이터 영역 또한 파일 크기에 따라서 클러스터를 추가로 할당 받습니다. 루트 디렉토리는 우리한테 익숙한 C드라이브라고 생각하시면 됩니다(맨 처음 디렉토리 라고 생각하시면 될 것 같아요). 루트 디렉토리는 FAT32에서 일반 디렉토리 영역이므로 데이터 영역의 어디에든 존재 가능합니다. 하지만 실무에 계신 전문가분들 께서는 거의 흔하지 않다고 합니다.

더불어 한 가지 더 알아야 하는 것은, 파일이랑 디렉토리는 저장방식이 다릅니다. 파일은 클러스터에 직접적으로 기록이 되지만, 디렉토리는 디렉토리 엔트리(Directory Entry)라는 구조체 형식으로 저장이 됩니다. 그 구조는 아래와 같습니다.

추가로 맨 처음 0x00 위치에 특수한 값들이 존재할 경우가 있다. File Name or Status Byte에 일본 간지(σ)가 있을 경우 0xe5로 표현이 된다. 0x05대신  0xe5로 표현. 또한, 파일 이름에 값이 깨져보인다거나 하는 것들은 한글이 유니코드로 작성되어있을 수도 있습니다.

이제 FAT Data 영역을 Hex Editor로 들여다 보자. 아래의 사진은 첫 FAT Data 영역을 캡쳐한 사진이다. 몇가지 예시를 들었습니다. 예시는 총 6개로. 볼륨 이름, LFN(긴 파일 이름 엔트리), 일반파일(삭제된 것, 존재하는 것), 디렉토리(삭제된 것, 존재하는 것). 한 번 봅시다.

맨 위에서 부터 차례대로 빨간네모부터 봅시다.
- 08 : 볼륨 이름
- 0F : LFN(긴 파일 이름 엔트리)
- 20 : 일반 파일
- 10 : 디렉토리

그 중에서 삭제되지 않았고, 일반파일인 것을 예시로 분석해보겠습니다. 가운데 살색이 되겠네요. 시간 계산 법은 아래에 설명하였으니 참고해주시기 바랍니다. 똑같은 예시가 아닌 볼륨 이름 수정시간을 예시로 하겠습니다.

이게 어떻게 나온건지는 차근차근 알아보도록 합시다. 우선 Hex값으로 적혀있는 시간은 어떻게 해석이 되는걸까요?

데이터 영역 시간 및 날짜 표현 방식

실습에 앞서서 FAT 파일 시스템 갱신 지연시간을 말씀드리겠습니다.
생성 시간 : 10밀리초(ms)
수정 시간 : 2초(sec)
접근 시간 : 1일(day)
접근 시간은 거의 갱신이 안됩니다. 갱신할 때마다 파일시스템을 변경하는 빈도가 너무 많아서 퍼포먼스가 떨어지게 됩니다. NTFS부터는 사용이 안됩니다. 다음으로는 사용자 행위에 따른 파일 시스템 시간 변경입니다.

이제 본격으로 16진수로 적혀있는 값이 어떻게 시간으로 해석이 될까요? 먼저 알아야할 부분은 다음과 같습니다.
Created Time에서는 상위 5-bit은 초(Sec), 다음 6-bit는 분(Min), 마지막 5-bit는 시(Hour)를 의미합니다. 초의 경우 5-bit면 30초 밖에 할당을 못하게 됩니다. 때문에 초 같은 경우는 1증가할 때마다 2초씩 증가하게 됩니다. 아래는 예시입니다.

Created Date는 상위 5-bit는 일(Day), 다음 4-bit는 월(Month), 마지막 7-bit는 년(Year)를 의미합니다. 년도의 경우 1980년이 오프셋이기 떄문에 값이 2라면 1980+2 = 1982년을 의미하게 됩니다. 값이 10이라면 1990년을 의미하게 됩니다. 아래의 표는 예시입니다.

볼륨 이름 및 시간 확인하기

내 컴퓨터 혹은 내 PC를 들어가보면 로컬 디스크 혹은 이동식 디스크 혹은 사용자가 수동으로 이름을 변경한 디스크 이름들이 보이게 됩니다. 루트 디렉토리에는 볼륨 이름 또한 적혀있습니다. 즉, 다시 말하자면 루트 디렉토리의 첫 번째 디렉토리 엔트리를 사용하는 것이죠. 또 다른 점이 있다면 속성과 마지막 수정 시간(볼륨 이름 수정시간)만 빼고 나머지 필드는 사용 안합니다. 아래 사진을 보시죠.

볼륨의 이름 같은 경우는 Name 필드와, Extension(확장자) 필드를 함께 사용합니다. 다음으로 자몽색은 시간이고, 녹색은 날짜라는 것은 위에서 이미 다 봤기 때문에 알고 계실 겁니다. 볼륨이름을 DOTAKY99로 언제 바꾸었는지 알아보도록 합시다.

시간에서 초 * 2를 하는 것은 위에서 설명하였고, 년도에서 1980에 시간 값을 더해야 한다는 것도 설명하였습니다. USB의 볼륨이름을 dotaky99로 바꿨는데 그 날짜와 시간은 2020년 12월 25일 20시 29분 18초라고 나옵니다.

실습 파일 분석하기

위에서 파일 테스트 했던 파일을 그대로 들고왔습니다. 하지만 여기서는 이 파일의 엔트리를 통해서 안에 내용물이 어떻게 적혀있는지를 보고자 합니다. 그러려면 주의깊게 봐야할 부분은 Starting Cluster High와 Low입니다.

우리가 만들고 작성했던 이 메모장안에는 어떤 내용이 들어있을까요? 사실 특별한 어떤 메시지는 안 적었고 A로 도배를 했습니다. 아래와 같이 말이죠. 그렇다면 이 A로 가득찬 내용은 Starting Cluster High와 Low를 통해 알 수 있습니다. 기존 실습용 DOATKY99 USB를 통해서 계속 진행하겠습니다.

기존 DOTAKY99의 루트 디렉토리는 67584섹터에 있습니다. Starting Cluster High와 Low를 합쳐서 보면 총 값은 6이 나오게 됩니다. 하지만 클러스터는 이미 2개가 앞서 예약 되어있는 상태입니다. 때문에 6-2를 해주어 값은 4가 됩니다. 단위가 클러스터이기 때문에 Sector Per Cluster 값을 확인해주어야 합니다. 이는 FAT 1편 BPB 영역에 있으니 확인해주시면 됩니다. DOTAKY99의 Sector Per Cluster(SPC) 값은 0x08입니다.
즉, 4 * 8 = 32가 나오게 되며, 현재 위치 + 나온 값을 해주면 67616 섹터에 값이 쓰여져 있는 것을 확인할 수 있습니다.
정리하자면 (Starting Cluster-2) * Sector Per Cluster를 통해서 구하실 수 있습니다.

LFN(긴 파일 이름 엔트리)

파일 이름을 보면 'SYSTEM~1' 이라고 적혀있습니다. 할당 되어있는 8-bit를 다 사용하고 그 기준을 넘겼을 때 '~1' 라는 것이 추가가 됩니다. 우선 LFN의 엔트리를 볼까요.

Sequence Number of Status Byte
- 255자 이하의 파일 이름 표현을 위해 하나 이상의 LFN 엔트리를 사용(1부터 시작)
  마지막 값은 '증가값 | 0x40' 으로 순서번호 생성
- 0xE5는 삭제된 LFN 엔트리
Attributes
- LFN 엔트리이므로 항상 0x0F값을 지님
- Checksum : 파일 이름의 체크섬
LFN Character
- 유니코드(5글자, 6글자, 2글자) : 하나의 LFN 엔트리는 유니코드 13글자 표현 가능
- 최대 255글자 할당시 14개의 LFN엔트리를 필요로 한다(할당 안되면 0xFF로 패딩)

총 32바이트씩 끊어서 보면 편합니다(사실 이렇게 밖에 못보죠). 맨 아래서부터 파일 이름은 확장자 포함하여 'so_long_file.txt' 입니다. 하지만 처음 8-bit만 파일 이름을 할당한다고 했었죠?
네 그래서 LFN을 생성하게 됐습니다. 빨간색 네모의 Attributes를 보면 일반파일로 시작하여 LFN 값으로 변한 것을 이론으로 배웠고, 실제로 파일을 생성하여 실제로보니 그대로 적혀있습니다. 또한, 마지막 LFN엔트리에서는 유니코드로 표현 안되는 부분, 즉 할당이 안되는 부분들은 '0xFF'값으로 채워져 있는 것을 확인할 수 있습니다.

이 글을 읽는 대부분 독자분들께서는 영어가 아닌 한글이름이라면 정상적으로 볼 수 없으십니다. 유니코드표를 참고하셔서 해석해주시면 되겠습니다. 참고로, Hex값 2바이트로 한글이 표현됩니다.

이제 녹색 네모를 보시면 아래서부터 01 이라는 LFN값이 생깁니다. 하지만 길이가 부족하여 위에 초록색 네모 '42' 값을 보실 수 있습니다. 이는 마지막 LFN 값이 02여야 하는데, 0x40과 OR 연산을 한다고 했었죠? 그래서 0x42값으로 끝을 나타내주고 있습니다. 만약 더 길어진다면 끝이 0x43, 0x44로 늘어가겠죠?

FAT32 복구

FAT복구에 대해서는 어떻게 진행이 될까요? FAT32의 백업 부트섹터가 있는 경우와 없는 경우로 나뉠 수 있습니다.

백업이 있을경우

부트섹터와 +6 위치에 백업부분이 있다고 했습니다. FTK이미저로 손상된 FAT32를 열어보았습니다. 정상적으로 사이즈는 인식하나 내용물은 확인이 어렵습니다.

이런 경우에는 Hex Editor로 열어서 확인 해보는 것이 좋겠습니다. X-way나 다른 도구를 이용하셔서 보셔도 좋습니다.

128섹터로 이동하면 되겠네요 :) 다들 어떻게 보시는지 아시죠?

하지만 128섹터에는 아무내용도 적혀있지 않습니다. 원래는 MSDOS5.0이라도 적혀있어야 하는데 말이죠. 하지만 걱정없습니다. 저희에겐 백업영역이 있습니다. 128+6 으로 이동해봅시다. 왜 +6인지 모르면 1편부터 다시보고 오세요!

백업영역에 우리가 원하는 정보가 있습니다! 이걸 복사해서 그대로 덮어쓰면 될 것 같네요! 사진이 커서 일부만 캡쳐했습니다! 512바이트 전부다 복사해서 덮어써주세요!

FAT32가 잘 복원되었습니다 이제 다음으로는 백업이 없는 FAT32를 복원해보러 갑시다!

 

백업이 존재하지 않는 경우

백업이 있는 경우에는 128+6 섹터로 가서 백업을 복사해서 기존 부트섹터에 덮어 썼었습니다. 하지만 이번에는 128+6번 섹터에도 백업이 존재하지 않습니다. 혹시나 다른곳에 숨겼나해서 MSDOS5.0을 검색해도 나오지 않습니다. 그러면 어떻게 해야할까요? 수동복원을 해야하는데, 맞습니다. 직접 값을 입력해주어야 합니다. 필요한 값만 체크를 해보도록 합시다. 기존 FAT 1편에서 아래와 같은 사진을 보셨을 겁니다.

여기서 우리는 OEM ID, BPS, SPC, Reserved Sector Count, Number of FAT, Media, FAT Size 32, Root Directory Cluster랑 마지막 시그니처 55AA를 적어주면 되겠습니다.

1. OEM ID구하기 : 0x03부터 0x0A까지 MSDOS5.0(4D 53 44 4F 53 35 2E 30)을 적어주시면 됩니다. 이건 고정값이죠?
2. Bytes Per Sector(BPS) : 보통 한 섹터에 512바이트 입니다.
3. Sector Per Cluster(SPC) : 클러스터 값은 정확하게 맞지 않아도 됩니다. 약간 추측을 했습니다.
4. Reserved Sector Count : 이 부분은 어떻게 구할까요? 사실 OEM ID와 비슷합니다. FAT Area의 첫 시작 0번 클러스터와 1번 클러스터는 이미 고정되어 있다고 했습니다. 그 정보를 이용하여 값을 검색해주시면 됩니다. 그 값은 다음과 같습니다. (F8 FF FF 0F FF FF FF FF) 이 값을 찾기하시면 해당 위치가 나오게 됩니다.
지금까지 정리하면 첫 BS시작은 128(0x010000)섹터였으며, FAT#1의 시작은 6406(0x320C00)섹터입니다. 그러면 FAT#1의 위치는 BS + Reserved Sector Count 입니다. 즉, 0x10000 + X = 0x320C00 이 값이 나와야 합니다. 즉 Reserved Sector Count의 값은 0x310C00바이트 입니다. 섹터 값으로 변환하기 위해서 512를 나눠주시면 0x1886이 나옵니다.

이 참에 FAT 32 Size도 구해야 하니 FAT#2 까지 검색해보겠습니다.

5. Media는 F8로 넣어주시면 됩니다.

지금까지 종합하면 아래와 같이 적혀있어야 합니다. OEM ID를 적었고, BPS와 Reserved, FAT개수, Media 형식을 적었습니다. 이제 남은건 FAT Size와 Root Directory Cluster가 남았습니다.

6. FAT 32 Size : FAT#1은 0번과 1번 클러스터가 이미 고정된 값이라서 검색을 했었죠? FAT#2 또한 검색을 해서 위치를 찾아줍니다. 이번엔 Byte 단위가 아닌 Sector로 계산하겠습니다. 7363 - 6406을 하면 957이 나오고 이 값을 Hex로 환산하면 0x03BD가 나옵니다.

7. Root Directory Cluster : 값은 0x02만 써주시면 됩니다. 결과는 아래 사진과 같습니다. 참고로 마지막 2바이트에 55AA도 적어주셔야 합니다 ! 아 참고로 Sector Per Cluster는 8넣어주었습니다. 최종 결과는 다음과 같습니다.

FTK 이미저로 열어봤습니다. 잘 인식이 됩니다!

 

반응형