Piki's Play
FAT 개념과 분석 - 파일 이름 범주 본문
9.5 파일 이름 범주
- 일반적으로 파일이름 범주 분석은 메타구조체를 이용해서 파일명을 확인시켜준다. FAT는 파일명주소와 메타데이터 주소를 구분하지 않는다. 이미 파일명이 메타주소로 사용되기 때문에 이미 메타데이터 범주에서 파일과 디렉토리 이름의 기본 내용을 설명하였다. 디렉토리 엔트리 구조체는 파일명으로 8문자, 확장자로 3문자를 이용해 8.3규칙을 통해 파일명을 저장한다. 이 절에서는 어떻게 FAT가 긴 파일명을 처리하는지 집중해서 다룬다.
- 파일명이 8문자보다 길거나 이름에 특별한 값이 있다면 디렉토리에 LFN(Long File name) 타입이 추가된다.
LFN이 있는 파일들 또한 SFN(Short File name) 디렉토리를 갖는다. LFN엔트리들이 시간, 크기, 시작 클러스터 정보를 포함하지 않기 때문에 SFN 엔트리들이 필요하다. LFN엔트리들은 단지 파일명만 포함한다. 비 할당시 첫 글자를 0xe5로 설정하는 것은 같다.
- SFN과 LFN 데이터 구조체는 같은 위치에 속성 필드를 가지며 LFN 엔트리들은 특별한 속성값들을 사용한다. LFN 엔트리에 나머지 바이트들은 2바이트, UTF-16으로 인코딩된 13개의 유니코드 문자들을 저장하는데 사용된다. 만약 파일명 길이가 13글자 이상이라면 추가 LFN 엔트리들을 사용한다. 모든 LFN 엔트리들은 디렉토리에서 SFN보다 우선하고 두 엔트리를 관련짓는데 사용하는 체크섬을 포함한다. LFN 엔트리들은 정렬순서가 반대이여서 파일명 첫부분이 LFN 마지막 즉, SFN 엔트리에 근접해 있다.
- 예제 그림은 이미지에 존재하는 디렉토리 엔트리 목록을 보여준다. 이 디렉토리에는 2개의 할당된 파일이 있다. SFN 앞에 두 LFN 디렉토리 엔트리들이 있고 그 엔트리들은 Long File Name.rtf라는 이름을 거꾸로 갖는다.
이 예제를 fls도구로 분석하면 다음과 같은 결과를 얻는다.
#fls -f fat fat-2.dd
r/r 3 : FAT DISK
r/r 4 : RESUME-1.RTF
r/r 7 : My Long File Name.rtf (MYLONG~1.RTF)
r/r * 8 : _ile6.txt
위 결과를 분석해보자.
3번째 줄(r/r 7)은 LFN이다. 또한 4번째 줄(r/r 8)은 지워진 파일이다. (첫 바이트가 0xe5로 되어있다.) r/r 4와 7사이에 5와 6이 없는 것을 알 수 있는데 이는 LFN이 들어가 있기 때문에 주소차이를 볼 수 있다.
- LFN 엔트리들은 영어문자 ASCII외에 국제적 문자를 지원하는 유니코드를 사용한다.
또한 국제 커뮤니티에서는 'Code Pages'를 사용해서 자신들의 모국어 문자로 파일명을 생성할 수 있도록 했다. ASCII는 256개 중 128개를 사용하고 'Code Pages'는 추가로 128개 엔트리를 사용하며, 그것들을 문자로 할당한다. -> SFN 엔트리는 ASCII 대신 Code Pages 값을 할당할 수 있다. (1 -> '가' 이런 느낌)
▶ 할당 알고리즘
- 파일명은 메타데이터와 같은 데이터구조체에 저장되고 파일 이름 범주의 할당 알고리즘도 메타데이터 범주와 같다. 차이점은 LFN이 SFN의 앞에 위치해야 한다는 것이고 운영체제는 모든 엔트리들이 들어갈 공간이 있는지 검색한다. 그래서 '첫 번째 적용'에서는 비할당 공간 주변에 다른 비할당 공간이 없으면 건너뛸 수도 있다.
- 삭제루틴은 이전에 언급한 것과 같고, 첫 바이트는 0xe5로 교체된다.
▶ 분석 기술들
- 파일 이름범주 분석은 특정 파일명을 찾는 것이다. FAT 버전에 따라 루트디렉토리의 위치가 다르기 때문에 이 루트디렉토리의 위치를 먼저 파악해야한다. (부트섹터에서 찾자)
- 구조체 속성이 LFN 엔트리로 설정되어 있으면 단계적으로 디렉토리를 처리하고 그 내용들이 저장되고 다음 엔트리가 조사된다. 이 과정은 일치하는 체크섬을 찾을 때까지 계속된다. 엔트리의 할당상태는 첫 바이트를 이용하여 결정된다.
- 메타데이터는 디렉토리 엔트리에 위치하기 때문에 확인하기 쉽고, 파일이 삭제되어도 동기가 유지된다.
▶ 분석 고려사항
- 파일명과 메타데이터는 같은 구조체에 존재하기 때문에 복구하고자하는 파일명이 비할당 엔트리에 항상 존재한다. 만약 LFN을 사용한다면 SFN의 이름의 첫 바이트가 바뀌어도 LFN은 존재하고 있다는 의미이다.
- 만약 파일명을 찾기위해 검색도구를 통해 키워드 검색 동작방법을 사용시, 긴 파일명에 유니코드(Unicode) 버전을 사용하는지 확인해야 한다. SFN은 ASCII로 저장되지만 LFN엔트리들은 유니코드로 저장된다.(다른 경우도 있다. p.s참고) LFN엔트리들이 여러 작은 조각으로 나뉘어질 수 있다.
▶ 분석 시나리오
- 두가지의 시나리오를 설명하겠다.
1. 파일명을 검색하는 것.
2. 디렉토리 엔트리의 상대적인 순서에 관한 것.
▷ 파일명 검색
- 도구에서 파일명 검색은 어떻게 이루어질까?
이름이 LFN에 저장되어 있고 SFN에 수정된 이름이 있다면 키워드로 바로 발견하는 것은 쉽지 않다. 따라서 SFN을 노리기 위해 ASCII로 이루어진 수정된 이름을 검색하거나, 긴 이름 검색을 수정해야 할 것이다.
- 긴 이름(LFN)으로 찾으려면 이름을 묶음으로 변환해 주어야 한다. 그 이후에 오탐을 줄이기 위해 가장 긴 문자열부터 검색해야 한다.
예를들어 'The Stuff.dat' 파일을 찾는다고 하자.
▷ 디렉토리 엔트리 순서
- 시스템을 조사하다보면 어떠한 경로로 그것들을 얻었는지 확인하고 싶을 수 있다. 예를들어 디렉토리 엔트리들이 알파벳 순서로 되어있다고 하자. 윈도우는 정렬된 순서로 디렉토리 엔트리들을 생성하지 않기 때문에 이것들은 이상하는 생각을 불러일으키기 충분하다. 이를 보고 여러가지의 가설을 세울 수 있다.
1. 그것들이 지금위치로 이동하고 새로운 엔트리들이 알파벳 순서로 생성되었다.
2. ZIP파일을 열어서 생성했고, 압축을 해제하는 프로그램이 알파벳 순서로 그것들을 생성했다.
3. 원격에 있는 서버에서 알파벳 순서로 되어있었는데 사용자는 알파벳 순서로 다운로드했다.
- 첫 번째 시나리오 테스트를 위해 파일들의 생성 및 마지막 수정시간을 확인할 수 있다. 복사본 파일은 생성시간이 원본의 마지막 수정시간보다 더 최근일 것이다. (이해 노) 파일을 정렬하고 드래그 앤 드롭시 완벽히 정렬로 복사되지 않는다.
- 두 번째 시나리오. 만약 ZIP에 파일들이 알파벳 순서로 더해졌었다면 해제도 마찬가지다. 또 생성된 파일들은 같은 생섯시간과 같은 수정시간을 가지고 원본도 같은 수정시간을 가진다.
- 세 번째 시나리오처럼 파일들을 다운로드 한다면 디렉토리 엔트리에 파일들이 알파벳 순서로 생성되게된다.
9.6 큰 그림
- 어떻게 하나의 파일이 생성되고 지워지는지 확인해 보자.
▶ 파일 할당의 예
- FAT 파일 시스템에서 파일의 생성을 확인하기 위해 'dir\file1.dat'이라는 파일이 생성되는 과정을 확인해보자.
(dir1 디렉토리는 이미 존재하고, 그 클러스트는 4096바이트, 파일크기는 6000바이트이다.)
1. 볼륨섹터 0에서 부트섹터를 읽고 FAT 구조체와 데이터 영역, 루트디렉토리의 위치를 확인한다.
2. dir1 디렉토리를 찾기 위해 루트디렉토리에서 각 디렉토리 엔트리를 해석하고, 이름과 속성을 이용해서 dir1을 갖는 엔트리를 찾는다. 그것은 여기서 시작클러스터 90이다.
3. dir1 시작클러스터 90의 엔트리를 읽고 비할당 엔트리를 찾는다.
4. 사용가능한 엔트리를 찾고 file1.txt 이름을 써서 할당상태를 결정한다. 또한 크기와 현재 시간을 적절한 필드에 적는다.
5. 우선 FAT 구조체 안을 검색해서 할당할 엔트리를 찾고, EOF로 설정한다. (밑에 그림에서 200위치)
6. 이후에 클러스터 200에 데이터 내용을 적는다. 이때 4096바이트를 쓰고나니 1904 바이트가 남는다는 것을 알아차린다. 그래서 두번째 클러스터가 필요하다.
7. 두 번째 클러스터를 검색하고 할당한다. (비할당 클러스터를 찾아둠)
8. 첫 클러스터를 위한 FAT엔트리 클러스터 200은 201을 포함하게 변경되고 201은 EOF를 포함하고 클러스터 201에 나머지 1904바이트를 쓴다.
▶ 파일 삭제 예제
- 이전 파일 생성 예제인 'dir1\file1.txt' 파일을 삭제해보자.
1. 볼륨섹터 0에서 부트섹터를 읽고 FAT구조체와 데이터 영역, 루트디렉토리 위치를 확인한다.
2. dir1 디렉토리를 찾기 위해 루트디렉토리에서 각 디렉토리 엔트리를 해석하고, 이름과 속성을 이요해서 dir1을 갖는 엔트리를 찾는다.
3. file1.txt 이름을 갖는 디렉토리 엔트리를 찾기위해 dir1 시작클러스터, 클러스터 90의 내용을 확인한다. 파일의 시작 클러스터 200을 확인할 수 있다.
4.파일에 클러스터 연결을 판단하기 위해 FAT구조체를 확인한다. 그 파일은 클러스터 200과 201에 할당되어있다.
5. 클러스터 200, 201의 FAT엔트리를 0으로 설정한다.
6. 첫바이트를 0xe5로 변경해서 file.txt를 디렉토리 엔트리에서 할당을 제거한다.
9.7 다른 주제
- 어느 특정 범주에도 포함하지 않아서 적용을 못하는 몇 가지를 이번에 설명한다.
- 일관성 검사동안 수행되어야 하는 것과, 파일 복구 기술에 대해 설명하자. 또한 클러스터 수에 따른 파일시스템 타입도 알아보자.
▶ 파일복구
- 파일을 삭제할 때 FAT엔트리를 0으로 설정하고 복구를 위해선 파일의 시작위치와 크기를 알아야한다.
- 알려진 클러스터로부터 데이터를 읽어 파일 데이터를 복구할 수 있다. 나머지 클러스터를 읽는데는 두 가지 옵션이 있는데 이는 파일의 크기만큼 무조건 읽는 방법과 데이터 할당 상태를 무시하거나 비할당 클러스터만을 읽는 방법이 있다.
여기서 두번째 방법은 비할당되서 단편화된 파일들을 복구하도록 한다. 그렇다보니 처음 방법보다 복구할 수 있는 확률이 높다.
- A 시나리오는 4개의 클러스터가 연속적으로 파일에 할당된 시나리오다. 여기서 두 옵션 둘다 정확히 56~59 클러스터를 복구한다.
- B 시나리오에서는 3개의 묶음(빨간색)으로 단편화된것을 볼 수있다. 그것들 사이에는 57, 60 과 같은 다른 파일들이 할당된 클러스터가 존재한다. 이때 옵션1은 56~59를 복구하고 이는 부정확하다. 옵션2는 정확하게 56,58,59,61을 복구한다. (비할당된 클러스터만 복구하기 때문)
- C 시나리오에서는 옵션 둘다 56~59를 복구하고 둘 다 부정확하다.
- 복구의 마지막은 여러개의 클러스터 디렉토리들이 단편화됐을 경우이다. 다음에 이용가능한 연속적인 클러스터가 되지 않았을 때에 해당한다. 만일 디렉토리가 복사되지 않았고, 최근에 조각모음을 하지 않았다면 더 어렵다. (복사되면 연속적인 클러스터에 할당하기 때문)
▶ 타입 결정하기
- 앞에서 FAT12, FAT16, FAT32를 구분하는 타입은 없다고 했다. 이번에는 타입을 구분하는 방법을 알아보자.
- 타입을 구분하는 방법은 파일시스템의 클러스터 수를 이용하는 것이다. 또 클러스터 수를 얻기위해서는 데이터 영역에 섹터수를 알아야 하고, 이를 클러스터당 섹터수로 나누어야 한다.
- 부트섹터는 루트디렉토리에 얼마나 많은 엔트리가 있는지 식별하는 값을 담고있고, 루트디렉토리의 섹터 개수는 다음과 같다.
((NUM_ENTRIES * 32) + (BYTE_PER_SECTOR - 1)) / (BYTE_PER_SECTOR)
- 데이터 영역에 할당된 섹터수는 (파일 시스템의 섹터수) - (클러스터2의 섹터 주소) 이다. 또한 예약된 영역, FAT 영역 루트디렉토리 크기를 뺀 것과 같다.
TOTAL_SECTORS - RESERVED_SIZE - NUM_FAT * FAT_SIZE - ROOTDIR_SIZE
- 마지막으로 한 클러스터에서 섹터수로 데이터 영역을 나누자. 나눈값을 기준으로 파일시스템의 버전을 알 수 있다.
나눈값=x일 때
4085>x -> FAT12
4085<= x < 62525 -> FAT16
62525<= x ->FAT32
- 윈도우 볼륨을 포맷할 때 FAT16, FAT32로 선택이 가능하다. 윈도우는 최종 클러스터 크기를 선택할 수 있다.
ex) FAT16 -> 4KB클러스터
FAT32 -> 2KB 클러스터
▶ 일관성 검사
- 파일시스템 조사 시 손상되거나 숨겨진 데이터가 있는지 일관성 검사를 하는 것이 좋다. 예를들어 FAT32에서 백업부트섹터와 원본을 비교하고 차이점을 확인한다.
- 손상된것으로 표시된 엔트리도 조사를 해야한다. -> 운영체제가 알기전에 하드디스크가 오류를 수정하기 때문이다.
- 마지막 클러스터의 FAT엔트리와 FAT에 할당된 섹터 끝 사이공간은 파일시스템에서 사용되지 않고 이 부분도 조사해야 한다.
- 루트 디렉토리와 그 하위 디렉토리는 반드시 조사되어야 한다. FAT 각 클러스터연결은 시작을 가리키는지 점검해야 한다.
- 볼륨레이블로 표시된 디렉토리 엔트리는 시작 클러스터를 갖지 않아야하고, 파일시스템에 볼륨레이블 엔트리는 오직 1개여야한다.
- 할당된 LFN 디렉토리 엔트리들의 체크섬을 조사해야하고, 할당된 SFN 엔트리와 비교해야 한다.
-> 충돌이거나 숨겨진 데이터를 포함할 수 있다.
- 모두 0이거나 난수 데이터인 디렉토리 엔트리는 영구삭제 후거나 전에 할당된 엔트리일 수 있다. 또한 널 엔트리 이후도 조사해야한다. 널 이후를 안보여주는 운영체제가 많기 때문이다.
p.s
SFN - ASCII or Code pages
LFN - ASCII or Unicode
'포렌식 > 파일시스템 (파일시스템 포렌식분석)' 카테고리의 다른 글
Chapter 11. NTFS의 개념 (0) | 2020.02.28 |
---|---|
Chapter 10. FAT 데이터 구조 (0) | 2020.02.26 |
FAT 개념과 분석 - 메타데이터 범주 (0) | 2020.02.19 |
FAT 개념과 분석 - 내용범주 (0) | 2020.02.18 |
Chapter 9. FAT 개념과 분석 (0) | 2020.02.17 |