[Digital Forensic] NTFS 파일 시스템 분석 (1)

 

NTFS 파일 시스템


(1) NTFS란 ?

  • Microsoft 사에서 설계한 파일 시스템 으로 윈도우 NT, 2000, XP, 2003, 2008, 7, 10 등 많은 버전에서 사용하는 파일 시스템

  • FAT는 이동형 디스크에 많이 사용되며 고정식 디스크에는 대부분 NTFS를 사용한다고 봐도 무리가 없음

  • 많은 특징들을 제공하는데, 많은 특징만큼 확장성도 뛰어남

  • 뛰어난 만큼의 복잡성을 가지고 있는 파일 시스템이기에 분석이 FAT처럼 쉽지만은 않음

  • 신뢰성, 보안, 대용량 장치를 지원하기 위해 설계

  • 특정 내용으로 데이터 구조체를 감싸는 포괄적 데이터 구조체(Wrapper)를 사용해서 확장성 제공

NTFS 명세는 MS에서 모두 공개하지 않아 부정확한 면도 없지 않아 있다.

 

NTFS는 많은 윈도우의 표준이며, 거의 모든 공개 유닉스에서도 지원할 만큼 범용적이다.

 

하지만 비 공식적 명세와 출시된 응용 프로그램들이 만나 파일 시스템을 생성하기 때문에 응용 프로그램 종속 속성과 파일 시스템의 일반적 속성을 구분하기가 힘들어졌다.

 

 

중요한 NTFS 기능은 다음과 같다.

  • b-tree 개념 (파일 클러스터 추적할 때 사용)

  • 클러스터의 대한 정보를 클러스터에 같이 저장

  • 대략 160억 바이트 용량 파일 지원

  • 접근 제어 (ACL 사용 가능)

  • 파일 압축

  • 유니코드 기반 파일 이름 지원, 긴 파일 이름 지원

  • 이동식 디스크, 고정식 디스크 모두 보안 기능 지원

 

NTFS의 레이아웃은 다음 그림과 같다.

 

[그림 1] NTFS 레이아웃

 

VBR

  • 도스 파티션의 MBR 영역과 비슷하게 부트 섹터와 부트 코드가 위치하고 있는 영역

  • 해당 영역 크기는 섹터 단위가 아닌 클러스터 크기에 따라 변동 됨

 

MFT

  • NTFS 시스템에서 가장 핵심적인 요소

 

Data

  • 여러 가지 데이터가 위치하는 영역

 

위와 같이 보면 레이아웃이 매우 간단해 보이지만 의외로 복잡하게 구성 되어 있어 분석이 까다로운 파일 시스템이다.

 

NTFS는 시스템 내에서 중요한 데이터가 파일로 취급된다.

 

다른 말로 하면 NTFS 시스템 내 관리 데이터 들이 파일로 취급 받는다.

 

이러한 이유로 관리 데이터들이 일반 파일처럼 파일 시스템 어떤 위치에도 위치할 수 있게 된다.

 

그래서 NTFS는 다른 파일 시스템들과 달리 특정 레이아웃을 갖고 있지 않다.

 

다만, NTFS 볼륨 첫 섹터에는 부트 섹터가 있고, 부트 섹터에는 부트 코드가 포함되어 있을 뿐이다.


(2) 클러스터

  • NTFS에서 파일은 속성의 집합이라고 할 수 있음

  • 일부 속성은 거주 속성으로 MFT 엔트리에 존재

  • 나머지 속성들은 비거주 속성으로 클러스터에 그 내용이 존재

 

NTFS에서 클러스터는 다른 파일 시스템과 마찬가지로 연속적인 섹터의 그룹을 의미한다.

 

클러스터 수는 2^2이어야 하며, FAT 파일 시스템과는 다르게 NTFS에서는 클러스터 주소가 0으로 시작한다.

 

클러스터 0은 파일 시스템의 첫 번째 섹터를 포함하며, 클러스터 주소를 섹터 주소로 변환하기 위해 다음과 같은 계산식을 적용한다.

 

클러스터 X 클러스터 별 섹터 수 = 섹터


(3) MFT

  • 파일 시스템의 모든 파일들과 디렉토리에 대한 정보를 포함하고 있는 것으로 NTFS의 핵심

  • 모든 파일과 디렉토리는 MFT에 꼭 하나의 엔트리를 가지고 있으며, 매우 간단

  • NTFS를 설계한 MS사에서는 MFT 엔트리를 파일 레코드(File Record)라고 부름

 

다음은 MFT 엔트리 구조이다.

 

[그림 2] MFT 엔트리 구조

 

엔트리 크기는 1KB이며, 헤더는 미리 정의된 목적을 갖는다.

 

속성 영역은 특정 목적을 갖는 작은 데이터로 이루어져 있다.

 

각 MFT 엔트리는 테이블 내 주소를 갖고, 해당 주소는 0부터 시작한다.

 

보통 엔트리 크기는 1KB이지만, 정확한 크기는 부트 섹터에서 정의한다.

 

MFT도 시스템 내에서는 하나의 파일로 취급되어 MFT를 설명하는 MFT 엔트리가 MFT 안에 포함되어 있다.

 

MFT를 설명하는 엔트리 이름은 $MFT이며, 해당 엔트리는 MFT의 디스크 위치를 설명한다.

 

MFT의 전반적인 레이아웃과 크기를 파악하려면 $MFT 엔트리를 참조해야 하며, MFT 시작 위치는 부트 섹터에서 정의한다.

 

$MFT 엔트리는 MFT 첫 번째 엔트리이므로 쉽게 $MFT 엔트리를 찾을 수 있다. 

 

MS는 MFT를 가능한 작게 시작하고, 필요할 때 크기를 확장할 수 있도록 NTFS를 설계하여 운영체제에 의해 파일 시스템이 생성될 때에는 MFT에 고정 엔트리 수의 엔트리를 생성한다.

 

볼륨 스패닝 등으로 저장 공간이 늘어날 시에는 MFT를 동적으로 늘려 파일 시스템을 크게 만들 수 있게 하였다.

 

그리고 한 번 생성된 MFT 엔트리는 지워지지 않는다.

 

엔트리 크기는 원래 부트 섹터에서 정의하지만, MS 모든 윈도우 버전들은 보통 1KB 크기를 갖는다.

 

MFT 헤더는 42바이트 크기이며, 12개 필드를 포함하고 있고, 나머지 982바이트는 비구조적으로 속성 값들을 포함하고 있다.

 

MFT 엔트리 첫 번째 필드는 시그니처인데, 보통 시그니처로는 'FILE' 문자열이 사용된다.

 

하지만, 엔트리 오류 등이 생길 시에 시그니처 필드는 'BAAD'라는 문자열을 갖도록 되어 있다.

 

또 MFT 엔트리는 엔트리 할당 상태, 타입 구분 필드 등이 있으며 파일이 하나의 엔트리만으로 설명되지 않을 경우 여러 엔트리를 사용할 수도 있다.

 

MFT 엔트리는 48bit 주소(파일 번호) 값을 가지며, 순차적으로 주소가 할당되고, 주소 시작은 0부터이다.

 

첫 번째 엔트리가 주소 0을 가지며, MFT 최대 주소는 MFT 크기가 증가할 때마다 변경된다.

 

또 MFT는 주소 외에 다른 순서 번호를 가지며, 해당 순서 번호는 16비트이고, 48bit의 주소와 조합되어 64bit의 파일 참조 번호를 생성하는데 사용된다.


(4) 메타데이터 파일

  • 볼륨의 모든 바이트가 파일로 할당되어 이를 관리하는 데이터를 저장할 파일이 필요

  • 위와 같은 다른 데이터의 관리 데이터를 저장한 파일을 메타데이터라 부름

  • MFT의 첫 16개 엔트리들로 예약되어 있으며, 사용하지 않는 엔트리들은 비할당 상태가 아닌 할당 상태

  • 오직 기본적이고 일반적인 정보만을 포함

  • 사용자에게는 보이지 않지만, 루트 디렉토리로 존재

  • 각 파일들은 '$'로 파일명이 시작되고, 첫 번째 문자는 대문자로 시작

 

다음은 MFT 메타데이터에 대한 목록이다.

엔트리 번호

파일 이름

설명

0

$MFT

MFT의 전반적인 레이아웃과 크기 설명

1

$MFTMirr

MFT 엔트리 복사본

2

$LogFile

메타데이터 트랜젝션 기록

3

$Volume

볼륨 레이블 / 식별자 / 버전 등 정보 저장

4

$AttrDef

식별자 값 / 이름 / 크기 등 속성 정보 저장

5

.

파일 시스템 루트 디렉토리 저장

6

$Bitmap

파일 시스템에 있는 각 클러스터 할당 상태 저장

7

$Boot

파일 시스템 부트 섹터와 부트 코드 저장

8

$BadClus

불량 섹터가 있는 클러스터 저장

9

$Secure

파일 보안과 접근 제어 정보 저장 

10

$Upcase

유니코드 문자의 대문자 저장

11

$Extend

파일 추가 정보 저장

12 ~ 15

이름 없음

만약을 위한 예약 파일

번호 없음

$ObjId

파일의 고유 ID 저장

번호 없음

$Quota

사용자별 할당량 정보 저장

번호 없음

$Reparse

Reparse point 정보 저장

번호 없음

$UsnJrnl

Usn 저널 정보 저장


(5) MFT 엔트리 속성

  • 속성은 많은 타입들이 있으며, 각각 속성들은 자신의 내부 구조체를 가짐

  • NTFS는 다른 파일 시스템과 달리 파일 내용에 대한 속성이 있음

  • 속성은 3개로 나누어져 있는데 한 개의 속성마다 헤더가 존재

[그림 3] MFT 엔트리 구조

 

속성 헤더는 속성 타입, 크기, 이름을 구분지으며, 해당 값들이 압축, 암호화가 되었는지를 식별하는 플래그 값도 포함하고 있다.

 

속성 내용은 형식과 크기가 정해져 있지 않다.

 

이로 인해 속성 내용의 크기가 엔트리 크기보다 커지는 경우가 발생하여 NTFS에서는 두 가지 속성을 통해 속성 내용의 저장 장소를 판단한다.

 

MFT 엔트리 속성은 대부분 거주 속성이지만, $DATA, $ATTRIBUTE_LIST와 같이 크기가 유동적인 것들은 비거주 속성이 될 수 있다.

 

  • 거주(Resident) 속성 : 속성 내용이 엔트리 크기보다 작은 경우 엔트리 내 속성 내용을 저장

  • 비거주(Non-Resident) 속성 : 속성 내용이 엔트리 크기보다 클 경우 외부에 별도 클러스터를 할당받아 해당 클러스터에 속성 내용 저장

 

두 속성의 결정은 속성 헤더에서 결정하며, 비거주 속성이 될 경우 MFT 엔트리 속성 헤더에는 할당 받은 클러스터 주소가 포함되게 된다.

 

[그림 4] 비거주 속성 

 

만약 속성이 비거주 속성으로 판명되어 클러스터를 할당 받아 속성 내용을 저장한다고 하더라도, 할당 받은 클러스터 크기를 초과하면 또 다른 클러스터를 할당 받아 저장하게 된다.

 

하지만 새롭게 할당 받은 클러스터는 연속된 클러스터일 수도 있지만, 대부분 비연속적 클러스터일 가능성이 더 높다.

 

이럴 때 NTFS에서는 클러스터 런(Cluster Runs)이라는 것을 활용하여 비연속적으로 할당된 클러스터를 효과적으로 관리한다.

 

그리고 Run이라고 하는 것을 이용하여 각 클러스터를 문서화한다.

 

이러한 run을 목록화 해둔 것을 runlist라고 하며, run의 구조는 run의 길이(클러스터 개수)와 클러스터 시작 오프셋(파일 시스템 처음 오프셋부터)으로 이루어져 있다.

 

속성에는 표준적인 유형들이 있는데 속성 타입들은 번호로 정의되어 있으며, MS에서는 해당 번호들은 식별자로 사용한다.

 

각 속성 타입은 이름을 가지고, 모두 대문자로 구성되어 있다.

 

그리고 MFT 메타데이터와 동일하게 '$'로 시작한다.

 

 

다음은 표준 속성에 대한 목록이다.

식별자

속성 이름

설명

16

$STANDARD_INFORMATION

플래그, 접근 / 수정 / 생성 시간, 소유자와 보안 ID 등 정보 저장

32

$ATTRIBUTE_LIST

다른 속성의 위치 정보 저장

48

$FILE_NAME

파일 이름(Unicode), 접근 / 수정 / 생성 시간 저장

64

$VOLUME_VERSION

볼륨 정보 저장(Windows NT만 존재)

80

$OBJECT_ID

파일 또는 디렉토리의 16비트 고유 식별자 저장(Windows 2000 이상 존재)

96

$VOLUME_NAME

볼륨 이름 저장

112

$VOLUME_INFORMATION

파일 시스템 버전과 다른 플래그들 정보 저장

128

$DATA

파일 내용 저장

144

$INDEX_ROOT

인덱스 트리의 루트 노드 저장

160

$INDEX_ALLOCATION

$INDEX_ROOT 속성에 연결되어 있는 인덱스 노드 정보 저장

176

$BITMAP

$MFT 비트맵 정보 저장

192

$SYMBOLIC_LINK

소프트 링크 정보(Windows NT만 존재)

208

$EA_INFORMATION

OS/2 응용 프로그램과의 호환성을 위해 사용(HPFS)

224

$EA

OS/2 응용 프로그램과의 호환성을 위해 사용(HPFS)

256

$LOGGED_UTILITY_STREAM

암호화된 속성에 대한 키와 정보 저장(Windows 2000 이상 존재)

 

위 표에서 목록화된 속성들이 모두 파일에 존재하는 것은 아니다.

 

대부분 기본 파일에 할당된 MFT 엔트리는 $STANDARD_INFORMATION, $FILE_NAME, $DATA 속성만 갖는다.

 

$STANDARD_INFORMATION 속성의 경우 보안, 임시 정보, 소유권 등을 나타내기 때문에 모든 파일과 디렉토리에 있어 강제적 속성이다.

 

$FILE_NAME 속성의 경우 파일 이름, 크기, 임시 정보 등을 나타내기 때문에 이 속성 또한 모든 파일과 디렉토리에 있어서 강제적 속성이다.

 

$DATA 속성은 파일 내용을 저장하는 속성으로 파일 내용이 엔트리 크기를 초과한다면 비거주 속성으로 판단되어 별도의 클러스터에 파일 내용을 저장하게 된다.

 

기본적인 $DATA 속성은 이름을 갖지 않지만, 비거주 속성으로 인해 추가적인 $DATA 속성이 생긴다면 해당 속성은 이름을 반드시 가져야 한다.

 

하지만, 해당 이름은 따로 정해진 것이 없으며, 디렉토리에 $DATA 속성에는 어떠한 내용도 저장될 수 있다.

 

모든 디렉토리는 $INDEX_ROOT 속성을 가지며, $INDEX_ROOT 속성은 해당 디렉토리 내에 위치한 파일들과 하위 디렉토리 정보를 포함한다. ($INDEX_ROOT, $INDEX_ALLOCATION 속성 이름은 일반적으로 $I30)

 

디렉토리가 커지면 $INDEX_ALLOCATION 속성과 $BITMAP 속성을 사용하게 된다.

 

또 디렉토리에도 $DATA 속성이 있을 수 있으며, 디렉토리에 있는 $DATA 속성에는 해당 디렉토리의 하위 디렉토리 목록과 파일 내용 등이 저장된다.

 

[그림 5] 기본 MFT 엔트리 속성

 

다른 여러 가지 속성들을 알아보기 전에 참고로 알아두어야 할 것이다.

 

바로 '기준 MFT 엔트리'와 '비기준 MFT 엔트리'라는 개념이다.

 

기준 MFT 엔트리는 MFT 엔트리에 속성이 65536개가 올 수 있는데 이 모든 속성의 헤더를 저장하려면 하나 이상의 MFT 엔트리가 필요하게 된다.

 

이런 경우 추가적인 MFT 엔트리가 필요한데 추가적으로 MFT 엔트리가 파일이나 디렉토리에 할당될 시 기존에 할당되어 있던 MFT 엔트리가 기준 MFT 엔트리가 된다.

 

쉽게 말하자면, 원본 MFT 엔트리가 아닌 추가적으로 할당된 MFT 엔트리가 비기준 MFT 엔트리가 되는 것이다.

 

기준 MFT 엔트리에는 하나의 $ATTRIBUTE_LIST 속성이 있고, 해당 속성은 파일 속성과 MFT 주소가 있는 목록을 포함한다.

 

그리고 비기준 MFT 엔트리에는 $FILE_NAME과 $STANDARD_INFORMATION 속성이 없다.


(6)스파스 속성(Sparse Attribute)

  • 압축 기능 중 하나이며, 파일에 0으로 채워진 클러스터를 제외하고 디스크에 기록하는 기능

  • NTFS에서도 이 기능을 속성으로 지원하는데 NTFS에서는 $DATA 속성 값을 이 속성으로 정의하여 하나의 파일을 압축

  • FAT 파일 시스템과는 다르게 제외된 0으로 채워진 클러스터를 위해 runlist에 0으로 채워진 클러스터에 대한 run을 하나 생성

 

기본적으로 run은 시작 클러스터 위치와 크기를 포함하지만, 0으로 채워진 클러스터를 위해 생성된 run은 데이터로 크기만 가질 뿐 시작 위치는 포함하지 않는다.

 

0으로 채워진 클러스터를 위한 run이라는 것을 표시하기 위한 플래그 값도 포함하며, 이러한 run은 'sparse run'이라고 한다.

 

[그림 6] Sparse run

 

 

RunList는 스파스 속성 클러스터의 RunList이다.

클러스터 번호

정보

종류

1

시작 위치 : 100, 길이 : 5

Run

2

시작 위치 : x, 길이 : 2

Sparse Run

3

시작 위치 : 160, 길이 : 5

Run

 

속성의 압축

  • NTFS에서 지원하는 속성 압축은 파일 시스템 수준의 압축으로 $DATA 속성이 비거주 속성일 때만 압축 가능

  • 속성이 압축되었는지 판단하는 것은 속성 헤더

  • $STANDARD_INFORMATION, $FILE_NAME 속성 플래그는 해당 파일이 압축된 속성을 포함하였는지 판단하도록 정보 제공

  • 속성 내용이 압축되기 전에 속성 내용은 유닛이라는 같은 크기의 단위로 나뉘게 됨 (압축 유닛 크기는 속성 헤더에서 결정)

 

압축 유닛이 생성될 때 발생할 수 있는 경우가 3가지 정도 있는데 이는 다음과 같다.

 

  • Sparse run이 압축 유닛 크기로 만들어지는 경우, 모든 클러스터는 0을 포함하게 되고 디스크 공간에 할당되지 않음

  • 압축될 때 압축 결과는 저장을 위한 같은 수의 클러스터가 필요한데, 이 경우 압축 유닛은 압축되지 않고 하나의 run이 원본 데이터로 만들어짐

  • 압축될 때 압축 결과는 적은 양의 클러스터를 사용하며, 이 경우 압축 결과를 디스크에 run으로 압축 후에 저장하고, sparse run은 전체 run 길이와 압축 유닛에 클러스터 수를 같도록 하기 위해 압축된 run 뒤에 위치하게 됨

 

속성의 암호화

  • NTFS는 속성을 압축하는 기능 뿐만 아니라 암호화하는 기능도 있음

  • OS별로 보았을 때 윈도우를 제외한 OS는 여러 가지의 속성을 암호화할 수 있고 윈도우는 $DATA의 속성만을 암호화

  • 암호화 시 속성 헤더를 제외한 속성 내용만 암호화

  • $LOGGED_UTILITY_STREAM 속성이 암호화 된 파일을 복호화하기 위해서 사용하는 복호화 키를 포함

  • NTFS에서는 암호화 알고리즘으로 3DES 알고리즘을 사용

  • 3DES 알고리즘은 대칭 알고리즘인 DES를 연속으로 3번 적용한 알고리즘

 

복호화할 때 사용되는 난수 키는 암호화 된 각 MFT 엔트리를 위해 생성되며, NTFS에서는 'FEK(File Encryption Key)'라고 한다.

 

만약 MFT 엔트리에 여러 개의 $DATA가 있다면, 그것들은 모두 같은 FEK로 암호화 되는 것을 뜻한다.

 

FEK는 $LOGGED_UTILITY_STREAM 속성에 암호화 된 상태로 저장되는데, 해당 속성은 DDF(Data Decryption Fields)와 DRF(Data Recovery Filelds)의 목록을 포함한다.

 

DDF는 해당 파일에 접근하려는 모든 사용자를 위해 생성되는 것이며, 포함하는 데이터로는 사용자 SID, 암호화 정보, 사용자 공개 키로 암호화 된 FEK를 포함한다.

 

DRF는 데이터 복구를 위해 생성되는 것이며, 데이터 복구 공개 키로 암호화 된 FEK를 포함한다.

 

[그림 7] 암호화 과정

 

사용자 공개 키는 레지스트리 저장되며, 해당 키는 로그인 패스워드를 키로 하는 대칭 알고리즘으로 암호화되어 있다.

 

암호화가 되었다면 해당 내용을 사용자에게 보여주기 위해서는 복호화가 이루어져야 한다.

 

복호화 과정은 암호화된 FEK가 포함되어 있는 $LOGGED_UTILITY_STREAM을 참조하고, 참조하여 얻은 FEK를 사용자 공개 키로 복호화하여, 복호화된 FEK를 $DATA 속성 내용 복호화하는 것이다.

 

[그림 8] 복호화 과정

 

대부분 보안 도구들이 이러한 암호화를 풀기 위해 무작위 대입 공격 등을 시도하는 기능들이 들어있다.

 

하지만 성공률은 시간에 따라 달라 오래 걸릴 수 있고 짧게 걸릴 수도 있어 무조건적인 신뢰는 하지 않는 것이 좋다.

 

일부 디렉토리들과 파일들이 암호화 되어 있다면 암호화 되지 않은 파일 내용이 복사본이 불특정 비할당 영역 어딘가에 존재할 수도 있다.

 

이는 NTFS 설계 상의 취약점이며, 이러한 문제로 인해 평문 파일 내용이 저장된 EFS0, TMP 임시 파일이란 것이 생성되고, 이 파일은 MFT 엔트리가 재할당되지 않았다면 충분히 복구가 가능하다.

 

또 Swap 공간이나 페이지 파일 또한 암호화 되지 않은 평문 내용의 복사본을 포함하기도 한다.

 

하지만 이런 수고를 할 필요 없이 관리자나 도메인 컨트롤러, 해당 사용자 계정을 알고 있다면 바로 접근하고자 하는 암호화 파일에 접근하여 내용 확인이 가능하다.

 


# Reference

 

http://www.yes24.com/Product/Goods/8511539

Digital Forensic - FAT 파일 시스템 분석 (2)

 

FAT 파일 시스템


(9) 데이터 구조

 

부트 섹터

  • 파일 시스템 첫 섹터에 존재하며 FAT 파일 시스템 종류에 따라 조금씩 다름

  • 하지만 첫 36byte는 동일

 

다음은 부트 섹터의 36byte 오프셋 구조이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 2

부트 코드 점프 명령

19 ~ 20

파일 시스템 섹터 개수

3 ~ 10

OEM 이름 (ASCII)

21 ~ 21

장치 타입

11 ~ 12

섹터 별 바이트(512, 1024, 2048, 4096)

22 ~ 23

FAT 영역 섹터 수

13 ~ 13

클러스터 별 섹터 수

24 ~ 25

저장 장치 트랙별 섹터 수

14 ~ 15

예약 영역의 섹터 크기

26 ~ 27

저장 장치 헤드 수

16 ~ 16

FAT 영역 개수

28 ~ 31

파티션 시작 전 섹터 수

17 ~ 18

루트 디렉토리가 포함하는 최대 파일 개수

32 ~ 35

파일 시스템 섹터 수

 

1) 부트 코드 점프 명령

  • 해당 부분은 부팅 파일 시스템이 아니면 설정되지 않아도 되는 부분

 

2) 섹터 별 바이트

  • 주로 512, 1024, 2048, 4096 바이트로 할당

 

3) 클러스터 별 섹터 수

  • 클러스터 당 섹터 수는 2제곱의 숫자만이 할당

 

4) FAT 영역 개수

  • 보통 2로 할당되지만 일부 작은 저장 장치에서는 1로 할당 되기도 함

 

5) 루트 디렉토리 최대 파일 개수

  • FAT 12 : 224

  • FAT 16 : 512

  • FAT 32 : 0

 

6) 파일 시스템 섹터 수

  • 2바이트로 표현되는 값보다 섹터 수가 많다면 0으로 설정 됨

 

7) 장치 타입

  • 디스크 유형에 따라 다른 값이 할당되는 부분

  • 고정식 디스크 경우 '0xF8', 이동식 디스크 경우 '0xF0'이 할당

 

8) FAT 영역 섹터 수

  • FAT 12 / 16의 FAT 영역 섹터 수를 나타내는 부분

  • FAT 32의 경우는 0이 할당

 

9) 파일 시스템 섹터 수

  • 위 2바이트로 표현되는 부분과 동일하나 차이점이 있다면 4바이트로 표현된다는 것

  • 2바이트로 표현이 안될 시 2바이트 부분은 0으로 설정되고 이 부분에 섹터 수가 설정 됨

  • 두 부분 중 한 부분은 무조건 0이 되어야 함

 

위에서 설명한 부트 섹터 영역 다음부터는 FAT 12 / 16과 FAT 32가 다르다.

 

 

다음 표는 FAT 12 / 16의 부트 섹터 구조를 정리한 것이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 35

부트 섹터

43 ~ 53

볼륨 레이블

36 ~ 36

BIOS INT13h 드라이브 번호

54 ~ 61

파일 시스템 타입 레이블

37 ~ 37

사용 x

62 ~ 509

사용 x

38 ~ 38

확장 부트 시그니처

510 ~ 511

시그니처 (0xAA55)

39 ~ 42

볼륨 시리얼 번호

   

 

1) 확장 부트 시그니처

  • 고정 값으로 0x29를 가짐

 

2) 볼륨 레이블

  • 파일 시스템 생성 날짜 등을 확인할 수 있는 값

 

다음 표는 FAT 32의 부트 섹터 구조를 정리한 것이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 35

부트 섹터

64 ~ 64

BIOS INT13h 드라이브 번호

36 ~ 39

FAT 영역 섹터 수

65 ~ 65

사용 x

40 ~ 41

FAT 구조체 저장 결정 비트

66 ~ 66

확장 부트 시그니처

42 ~ 43

주 / 부 버전 번호

67 ~ 70

볼륨 시리얼 번호

44 ~ 47

루트 디렉토리 클러스터 위치

71 ~ 81

볼륨 레이블

48 ~ 49

FSINFO 구조체 섹터 위치

82 ~ 89

파일 시스템 타입 레이블

50 ~ 51

부트 섹터 복사본 섹터 위치

90 ~ 509

사용 x

52 ~ 63

예약 영역

510 ~ 511

시그니처 (0xAA55)

 

1) FAT 구조체 저장 결정 비트

  • 만약 7번째 비트 자리가 1이라면 여러 FAT 구조체들 중 하나만 활성화된 것을 의미

  • 활성화 FAT 구조체 번호는 비트 0 ~ 3자리를 이용해 나타냄

 

2) 확장 부트 시그니처

  • 고정 값으로 0x29를 가짐

3) 볼륨 레이블

  • 파일 시스템 생성 날짜 등을 확인할 수 있는 값

 

공통적으로 시그니처 값 전에 사용하지 않는 영역이 있는데 이 부분은 특별한 목적이 없기 때문에 사용되지 않는다고 표현하였지만, 일반적으로는 부트 코드와 오류 메시지를 저장한다.

 

 

FSINFO 구조체

  • FAT 32에만 존재하는 구조체

  • 운영체제가 새로운 클러스터를 어디에 할당하는지 설명하는 역할을 담당

 

다음은 FSINFO 구조체 오프셋 구조이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 35

시그니처 (0x41615252)

492 ~ 495

다음 할당 클러스터 번호

4 ~ 483

사용 x

496 ~ 507

사용 x

484 ~ 487

시그니처 (0x61417272)

508 ~ 511

시그니처 (0xAA550000)

488 ~ 491

비할당 클러스터 수

   

 

 

FAT 영역

  • 클러스터 할당 상태 파악

  • 어떠한 파일이나 디렉토리에 할당된 클러스터의 다음 클러스터 주소 파악

 

FAT은 보통 FAT 파일 시스템에서는 두 개가 존재하며, 정확한 번호는 부트 섹터에서 할당 한다.

 

첫 번째 FAT은 예약 영역 섹터 다음부터 시작하며, 부트 섹터에서 전체 크기를 할당 한다.

 

두 번째 FAT은 만약 존재한다면 첫 번째 FAT 마지막 섹터 다음부터 시작하며, 구성은 같은 크기의 엔트리들로 구성된다.

 

 

알아두어야 할 점은 엔트리에 Header와 Footer는 존재하지 않는다는 것이다.

 

각 엔트리 크기는 FAT 종류마다 다른데, 해당 종류 숫자 bit 크기를 갖는다. (예 FAT 12는 12bit)

 

엔트리 주소는 0부터 시작하며, 같은 주소의 클러스터와 맵핑된다.

 

클러스터가 할당되지 않은 엔트리는 다음 클러스터 항목에 0값을 가지고, 클러스터가 할당되면 0값이 아닌 파일이나 디렉토리에 할당된 클러스터의 다음 클러스터 주소를 갖게 된다.

 

마지막 클러스터 주소를 가지게 되면 엔트리에는 마지막 클러스터라는 어떠한 값을 가지게 되는데, 그 값은 FAT 종류마다 다르다.

 

  • FAT 12 : 0xFF8

  • FAT 16 : 0xFFF8

  • FAT 32 : 0x0FFF FFF8 

 

만약 위 값들 보다 작은 값을 가진다면 클러스터가 손상되었다는 의미이며, 할당되어서는 안 된다.

 

클러스터의 시작 주소는 2부터여서 FAT 영역에도 당연히 0과 1의 주소를 갖는 엔트리는 꼭 필요하지 않다.

 

보통 0의 주소를 갖는 엔트리는 미디어 유형 복사본을 저장하는 엔트리이고, 1의 주소를 갖는 엔트리는 파일 시스템의 불량 상태를 저장하는 엔트리로 사용된다.

 

부트 섹터에도 미디어 유형 종류를 저장하는 항목이 있지만, 윈도우는 부트 섹터 항목은 사용하지 않고 FAT 영역의 엔트리 0을 사용한다.

 

 

디렉토리 엔트리

  • 디렉토리 이름과 여러 데이터를 대신 설명해 주는 메타 데이터가 포함 되어 있음

  • 이런 엔트리들은 파일과 디렉토리 모두에 할당되며 엔트리 위치는 할당된 파일이나 디렉토리의 부모 디렉토리 클러스터에 위치

  • 엔트리에 저장되는 이름의 최대 길이는 확장자를 제외하고 8글자이며, 확장자는 최대 3글자

 

다음은 디렉토리 엔트리 오프셋 구조에 대한 정리이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 0

파일 이름 첫 문자 할당 상태

18 ~ 19

접근 날짜

1 ~ 10

파일 이름 2번째 ~ 11번째 문자 (ASCII)

20 ~ 21

첫 번째 클러스터 주소의 상위 2바이트

11 ~ 11

파일 속성

22 ~ 23

수정 시간

12 ~ 12

예약 영역

24 ~ 25

수정 날짜

13 ~ 13

생성 시간

26 ~ 27

첫 번째 클러스터 주소의 하위 2바이트

14 ~ 15

생성 시간

28 ~ 31

파일 크기

16 ~ 17

생성 날짜

   

 

1) 파일 이름 첫 문자 할당 상태

  • 해당 필드는 디렉토리나 파일 이름 첫 번째 문자가 설정되는 부분

  • 해당 디렉토리 엔트리가 비할당 상태일 시 문자 대신 '0xE5' 또는 '0x00'이 설정 됨

  • 파일명이 8글자 이하일 경우 사용되지 않는 바이트는 'space(0x20)'으로 채워짐

 

2) 파일 속성

  • 00000001 : 읽기 전용

  • 00000010 : 숨김 파일

  • 00000100 : 시스템 파일

  • 00001000 : 볼륨 레이블

  • 00001111 : 긴 파일 이름

  • 00010000 : 디렉토리

  • 00100000 : 아카이브

 

3) 첫 번째 클러스터 주소 상위 2바이트

  • FAT 12 / 16의 경우 이 값은 0으로 설정 됨

 

4) 파일 크기

  • 해당 필드는 파일 크기를 나타내는 필드

  • 디렉토리일 때 0으로 설정 됨

 

디렉토리 엔트리 필드를 보면 타임스탬프 필드들이 여럿 보인다.

 

해당 필드들의 값들을 일반적으로 사용하는 날짜 형식으로 변환하는 과정은 다음과 같다.

 

1) 날짜 변환

  • 타임스탬프 값 중 날짜 값은 다음과 같은 규칙을 가짐

년 (0 ~ 127 유효)

월 (0 ~ 127 유효)

일 (1 ~ 31 유효)

15 14 13 12 11 10 9

8 7 6 5

4 3 2 1 0

 

먼저 hex 값을 2진수로 변환한다.

 

0x3116(예시, 생성 날짜) > 0011000100010110

 

 

다음으로 위 규칙대로 2진수를 끊어 10진수로 변환한다.

  • 0011000 > 30

  • 1000 > 10

  • 10110 > 26

 

년도의 경우 1980년도를 기준으로 하기 때문에 1980 ~ 2107년도까지 표현이 가능하다.

 

계산된 년도 값에 1980을 더해주면 계산이 완료된다.

 

변환 값 : 2010. 10. 26

 

 

2) 시간 변환

  • 날짜와 마찬가지로 시간도 규칙이 있음

시 (0 ~ 127 유효)

분 (0 ~ 59 유효)

초 (0 ~ 29 유효)

15 14 13 12 11

10 9 8 7 6 5

4 3 2 1 0

 

먼저 날짜 계산 과정과 마찬가지로 hex 값을 2진수로 변환한다.

 

0x5C7A (생성 시간) > 0101110001111010

 

 

다음으로 위 규칙대로 2진수를 끊어 10진수로 변환한다.

  • 01011 > 13

  • 100011 > 43

  • 11010 > 32

 

시간은 따로 더해주는 값이 없어 이대로 계산이 끝난다.

 

변환 값 : 오후 13시 43분 32초

 

 

현재 이러한 계산을 자동적으로 수행해 주는 도구가 많이 있으며, 대표적으로 DCode 도구가 이러한 도구들에 속한다.

 

 

LFN 엔트리

  • 디렉토리 엔트리에 포함되는 엔트리

  • 긴 파일명을 사용하는 디렉토리나 파일에 디렉토리 엔트리가 할당되면 LFN 엔트리에 파일명이 저장 됨

  • LFN 엔트리는 일반 엔트리보다 우선시 되어 짧은 이름을 저장하는 기본 엔트리 전에 목록화되며, 순서는 역순

 

다음 표는 LFN 엔트리 바이트 오프셋이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 0

일반 헤더

13 ~ 13

체크섬

1 ~ 10

파일 이름 문자

14 ~ 25

파일 이름 문자 6 ~ 11 (유니코드)

11 ~ 11

파일 속성

26 ~ 27

예약 영역

12 ~ 12

예약 영역

28 ~ 31

파일 이름 문자 12 ~ 13 (유니코드)

 

1) 순서 번호 또는 할당 상태

  • 순서 번호는 0x40과 OR 연산되어 할당 상태일 경우 설정 됨

  • 비할당 상태이면 0xE5로 설정 됨

 

파일 이름의 경우 사용되지 않는 바이트 필드들은 0xFF로 채워지며 파일 이름의 끝은 NULL (0x00)로 채워진다.

 


(10) 포렌식 측면에서의 관점

 

슬랙 공간

  • 파일 크기가 클러스터에 맞지 않아 발생하는 빈 공간

  • 파일에 할당된 클러스터가 파일보다 크더라도 클러스터 전체가 할당되며 파일이 사용하고 남은 클러스터 공간이 슬랙 공간이 되는 것

  • 일부 슬랙 공간은 한번 할당되고 다시 할당되지 않아 이전에 할당되어 쓰여진 데이터들이 남아 있을 수 있음

 

슬랙 공간 중 'RAM 슬랙 공간'이라고 부르는 공간이 있는데 이 공간은 운영체제가 파일 내용을 무엇으로 채우는지 결정하도록 한다.

 

그러나 대부분 0으로 채우게 된다.

 

RAM 슬랙 공간 말고 또 다른 공간이 있는데 이 공간은 클러스터의 비사용 섹터가 있는 공간이다.

 

앞에서 말했던 한번 할당되고 다시 할당되지 않은 슬랙 공간이 이 슬랙 공간을 말하는 것이다.

 

 

모든 파일 시스템은 슬랙 공간이 존재할 수 밖에 없다.

 

섹터 단위로 할당을 하기 때문에 슬랙 공간이 발생한다.

 

파일 시스템에서는 슬랙 공간이 할당된 데이터로 간주되기 때문에 만약 분석 시 파일 시스템에서 슬랙 공간을 분석하기 위해 비할당 데이터를 추출한다면 도구로부터 슬랙 공간을 추출받지 못한다.

 

[그림 1] 슬랙 공간

 

FAT 파일 시스템은 데이터 구조체가 다른 파일 시스템들에 비해 수가 적고 그 구조가 단순하다.

 

FAT의 부트 섹터와 FAT 엔트리는 파일 시스템 분석 도구가 자동으로 분석할 때 참조하는 아주 중요한 영역들로 필수적인 영역들이며, 디렉토리 엔트리는 응용 프로그램 도움 없이 삭제 된 파일을 복구하는데 참조되는 중요한 영역이다.

 

파일을 복구하길 원한다면 이 3가지 영역을 분석해야 하며 숨겨진 데이터가 있는지 확인하고 싶다면 각 비할당 영역이나 슬랙 공간을 분석해야 한다.

 

예를 들어, 부트 섹터 영역에는 시그니처 필드 앞 부분에 사용되지 않는 공간들이 존재한다.

 

이 부분은 부팅 파일 시스템일 경우 부트 코드를 저장하는 영역으로 사용하지만 부티 파일 시스템이 아닌 일반 저장 용도로 사용되는 파일 시스템이라면 빈 공간으로 남게 된다.

 

이렇듯 각 영역의 구조들을 살펴보면 사용되지 않는 공간들이 조금씩은 존재한다.

 

악의적 사용자는 이러한 공간들을 이용해 자신의 데이터를 숨기려고 할 것이며, 이러한 비할당 영역 말고도 슬랙 공간도 분석을 진행해야 한다.

 

FAT에서는 대표적으로 볼륨 슬랙이 존재한다.

 

파일 시스템과 볼륨 마지막 사이를 말하는 것이며, 이와 같은 볼륨 슬랙에도 악의적 데이터가 숨겨져 있을 가능성이 농후하다.

 

볼륨 슬랙을 찾기 위해서는 파일 시스템 섹터 수와 볼륨 전체 섹터 수를 비교해 얼마만큼의 슬랙 공간이 존재하는지 파악하는 방법이 있다.

 

볼륨 슬랙 공간을 파악하기 전에, 볼륨 슬랙 공간이 존재하는지, 사람에 의해 생성되었는지 확인하고 싶다면 주 부트섹터와 백업본 부트 섹터의 섹터 수를 저장하는 필드 값을 비교해 보면 된다.

 

 

FAT 영역은 시스템을 자동 분석할 때 중요하게 사용되는 영역이고, 그 안에 있는 디렉토리 엔트리는 응용 프로그램 수준의 기술 없이 삭제된 파일을 복구할 때 중요한 역할을 하는 엔트리이므로 필수적으로 알아두어야 할 부분이다.

 

대부분의 하드 디스크 등의 저장 장치들은 NTFS를 파일 시스템으로 많이 사용하지만 USB와 같은 이동형 저장 장치에서는 아직도 FAT을 사용하기 때문에 이동형 저장 장치를 분석하고 파일을 복구하려면 FAT에 대해 상세하게 알아두어야 할 필요가 있다.


# Reference

 

http://www.yes24.com/Product/Goods/8511539

[Digital Forensic] FAT 파일 시스템 분석 (1)

 

FAT 파일 시스템


(1) FAT (File Allocation System)

  • 흔히 SD 카드에서 많이 사용하는 파일 시스템

  • 파일 시스템 중 가장 간단한 구조를 가짐

  • 종류에는 FAT12, FAT16, FAT32가 있음

  • 모든 윈도우와 대부분 유닉스 기반 운영체제들에서 모두 지원

  • 보통 우리가 사용하는 디지털 카메라의 플래시 카드, USB 드라이브에서 볼 수 있음

 

FAT 파일 시스템은 간단 구조이기 때문에 여러 가지 기능들이 추가되어 정확하게 참조 모델로 구분하기 애매한 구조이다.

 

FAT 파일 시스템에는 중요한 두 가지의 구조체(디렉토리 엔트리, FAT)가 존재한다.

 

디렉토리 엔트리는 각 파일과 디렉토리를 데이터 구조체에 할당할 때 사용되는 구조체를 말한다.

 

 

디렉토리 엔트리에는 다음의 데이터가 포함된다.

  • 파일명

  • 크기

  • 파일 내용 시작 주소

  • 다른 메타 데이터

 

하나의 파일이나 하나의 디렉토리를 하나 이상의 클러스터에 할당했다면 FAT 구조체를 통하여 나머지 클러스터를 찾을 수 있다.

 

FAT 구조체에는 파일 다음 클러스터와 클러스터 할당 상태를 식별하기 위한 데이터가 포함된다.

 

위에서 FAT 파일 시스템 종류를 나열해 보았는데 종류들의 차이는 FAT 구조체 엔트리 크기에서 차이가 난다.

 

 

다음 그림은 디렉토리 엔트리 구조체와 FAT 구조체의 관계를 나타낸 것이다.

 

[그림 1] 디렉토리 엔트리와 클러스터, FAT 관계

 

FAT 파일 시스템의 물리적 레이아웃은 다음과 같다.

 

[그림 2] FAT 파일 시스템의 물리적 레이아웃

 

1-1. 예약 영역

  • 파일 시스템 참조 모델 데이터를 포함하는 영역

  • FAT12, FAT 16 파일 시스템 경우 해당 영역의 크기는 보통 1개의 섹터 크기지만 어떤 경우에는 부트 섹터에서 해당 영역 크기를 정의하기도 함

 

1-2. FAT 영역

  • 주 FAT 구조체와 부(백업) FAT 구조체를 포함하는 영역

  • 예약된 영역 바로 다음 섹터부터 시작

  • 해당 영역 크기는 FAT 구조체 수와 크기에 따라 달라짐

 

1-3. 데이터 영역

  • 파일과 디렉토리 내용을 저장하는 클러스터를 포함하는 영역


(2) 부트 섹터

  • 예약 영역 중에서도 볼륨 1번째 섹터에 위치

  • FAT 파일 시스템 물리적 레이아웃에서 예약 영역에 위치 (MS사에서는 BPB라 부름)

  • 파일 시스템을 설명하는 데이터를 포함하지만, FAT 종류(FAT 12 / 16 / 32)를 설명하는 데이터는 포함하지 않음

  • 부트 섹터 데이터를 참조하여 파일 시스템 종류를 결정 

 

FAT32 파일 시스템 부트 섹터에는 부트 섹터 백업본의 섹터 주소, 주/부 버전 번호와 같은 추가 데이터들이 포함되어 있다.

 

FAT32 파일 시스템은 섹터 0(부트 섹터)에 존재하는 원본이 손상되었을 때 부트 섹터 백업본을 사용 가능하다.

 

MS 문서에서는 원본 부트 섹터가 손상되었는지 자동 검사를 위해 '부트 섹터 백업본이 섹터 6(7번째 섹터)에 있어야 한다'고 설명한다.

 

또 FAT32 파일 시스템은 다음에 할당 가능한 클러스터 위치, 전체 크기에 대한 정보를 포함하는 FSINFO 구조체를 갖고 있다.

 

FSINFO 구조체에 포함되어 있는 데이터들은 운영체제를 안내하기 위해 존재하며, 안내만 하는 역할을 하므로 데이터 정확성을 보증하지 않는다.

 

 

필수 부트 섹터 데이터

  • FAT 파일 시스템 물리적 레이아웃 중 데이터 영역이 있는데 이 데이터 영역은 FAT 12/ 16과 FAT32는 차이를 가짐

  • FAT 12 / 16 파일 시스템 경우 데이터 영역 시작 주소는 루트 디렉토리 주소 다음으로 예약되어 있음

  • 하지만 FAT 32 파일 시스템 경우 루트 디렉토리는 데이터 영역 어디든지 위치 가능

  • FAT 파일 시스템 루트 디렉토리는 대부분 데이터 영역 시작 주소에 위치 

 

FAT 32 파일 시스템은 루트 디렉토리의 위치와 크기를 데이터 영역 시작에 불량 섹터가 있을 경우 루트 디렉토리가 적절하게 대처할 수 있도록 필요한 만큼 조절할 수 있도록 하였다.

 

반면 FAT 12/ 16 파일 시스템 루트 디렉토리는 부트 섹터에 정의된 위치와 크기로 설정된다.

 

FAT 32 파일 시스템 루트 디렉토리 시작 주소는 부트 섹터 처음에만 제공하고, 크기는 FAT 구조체에서 결정한다.

 

 

부가 부트 섹터 데이터

  • 필수 부트 섹터가 가지고 있는 데이터 외에 많은 추가 정보들을 포함

  • 해당 데이터들은 파일 시스템을 구동하기 위한 데이터들이 아닌 편의를 위한 데이터이므로 정확성은 보증되지 않음

  • 예로 OEM Name이 부가 부트 섹터 데이터에 포함 되며, OEM Name은 필수 데이터가 아니므로 사용자가 임의로 변경 가능

 

부트 코드

  • 파티션 테이블 처리와 운영체제 위치를 파악하는 명령어

  • FAT 파일 시스템의 부트 코드는 부트 코드를 완전하게 분리하는 유닉스 파일 시스템과는 다른 형태를 띄고 있음

  • 부트 섹터 첫 3Byte는 CPU에게 부트 코드의 나머지 설정 데이터로 이동하라는 기계어 코드(점프 명령어)

 

FAT 종류마다 부트 섹터로 예약되어 있는 바이트 단위 오프셋은 다음과 같다.

  • FAT 12 / 16 : 62 ~ 509

  • FAT 32 : 90 ~ 509

 

위 오프셋들은 부트 코드를 포함하고 있는 곳이기 때문에 일반적으로 다른 곳에 사용되지 않으며, 위 오프셋 다음에 오는 섹터들은 추가 부트 코드를 위해 사용될 수 있다.

 

또 FAT 파일 시스템은 부팅을 하지 않아도 부트 코드를 가지며, 해당 부트 코드는 해당 시스템을 부팅하기 위해 다른 디스크가 필요하다는 메시지를 출력하는 역할을 한다.

 

출력된 후 디스크 MBR 부트 코드에서 FAT 부트 코드를 호출한다.

 

호출 후 부트 코드는 적절한 OS 파일들을 위치시키고 적재하여 실행시킨다.


(3) 클러스터

  • 연속적인 섹터의 그룹

  • 섹터의 개수는 2의 제곱(1, 2, 4, 8, ...)이어야 함

  • 주소를 가지며, 0이나 1이 아닌 2라는 주소부터 시작 (1번째 클러스터는 클러스터 2가 됨)

 

첫 번째 클러스터 찾기

  • FAT 파일 시스템은 첫 번째 클러스터인 클러스터 2부터 시작하지 않아 위치를 쉽게 찾지는 못 함

  • FAT 파일 시스템은 모든 논리적 볼륨 주소가 논리적 파일 시스템 주소로 맵핑 되지 않음

  • 따라서 FAT 파일 시스템 예약 영역과 FAT 영역은 클러스터 주소를 사용하지 않음

 

첫 번째 클러스터를 찾는 방법은 FAT 12/16과 FAT 32가 서로 다르다.

 

FAT 12/16 파일 시스템의 경우 파일 시스템이 생성될 때 데이터 영역 첫 번째 섹터에 루트 디렉토리가 부트 섹터에서 정의된 고정 크기를 갖고 할당된다.

 

그래서 FAT 12/16 파일 시스템의 클러스터 2는 루트 디렉토리 다음 섹터를 포함하게 된다.

 

 

FAT 12/16 파일 시스템 클러스터 2 위치는 다음과 같다.

 

[그림 3] FAT 12 /16

 

이와 다르게 FAT 32 파일 시스템 경우 루트 디렉토리 유동성 때문에 데이터 영역 첫 번째 섹터를 클러스터 2가 포함된다.

 

즉 데이터 영역 첫 번째 섹터가 클러스터 2이다.

 

[그림 4] FAT 32

 

클러스터와 섹터 주소 변환

  • 클러스터와 섹터 주소 간에 변환을 위해서는 클러스터 2의 주소를 알아야 함

  • 또 클러스터 당 몇 개의 섹터를 포함하고 있는지도 파악 필요

 

다음은 클러스터 X (계산하고자 하는 클러스터)의 섹터 주소를 계산하는 기본 계산식이다.

 

(X - 2) x (클러스터 당 섹터 수) + (클러스터 2의 섹터 수)

 

역으로 섹터 S (계산하고자 하는 섹터) 가 포함되어 있는 클러스터를 계산하는 계산식은 다음과 같다.

 

((S 클러스터 2의 섹터 수) / (클러스터 당 섹터 수)) + 2

 

 

클러스터 할당 상태

  • FAT 구조체를 통해 알 수 있음

  • 보통 두 개의 FAT 구조체 복사본이 있는데 하나는 파일 시스템 예약 영역 이후에 존재

  • FAT 구조체는 파일 시스템 클러스터마다 하나의 테이블 엔트리를 가짐

  • 테이블 엔트리에는 각 클러스터 번호들이 데이터로 포함되어 있음  

 

테이블 엔트리에 포함되어 있는 번호들의 최대값은 다음과 같다.

  • FAT 12 : 12bit

  • FAT 16 : 16bit

  • FAT 32 : 32bit (하지만 28bit만 사용)

 

만약 테이블 엔트리에 포함되어 있는 값이 0이라면 해당 엔트리가 할당된 클러스터는 파일에 아직 할당되지 않은 것을 의미한다.

 

FAT 종류마다 테이블 엔트리가 갖고 있는 값 중 할당되지 않은 상태를 표시하는 값들이 있으며, 다음과 같다.

  • FAT 12 / 16 : 0xFF7

  • FAT 32 : 0xFFF FFF7

 

만약 어떠한 테이블 엔트리가 위 값을 가지고 있다면 해당 테이블 엔트리의 클러스터는 파일에 할당되지 않음을 의미한다.


(4) 디렉토리 엔트리

  • 파일과 디렉토리마다 할당되는 데이터 구조체를 말함

  • 크기는 32byte

 

디렉토리 엔트리는 다음과 같은 데이터를 포함한다.

  • 파일 이름

  • 파일 속성

  • 파일 크기

  • 클러스터 시작 주소

  • 날짜

  • 시간

 

디렉토리 엔트리는 위에서 보듯이 파일 이름을 포함하기 때문에 파일 이름 참조 모델의 역할도 수행한다.

 

디렉토리 엔트리 위치는 데이터 영역 어디든지 가능하며, 그 이유는 디렉토리에 할당된 클러스터가 해당 디렉토리 엔트리를 포함하기 때문이다.

 

디렉토리 엔트리는 클러스터처럼 고유 주소를 사용하지 않고 할당된 파일이나 디렉토리의 전체 이름을 사용한다. (표준 방법)

 

디렉토리 엔트리에는 위처럼 파일 속성이 포함되며, 파일 속성에는 7가지 항목이 있지만 모두 OS에서 필요로 하는 것은 아니다.

 

 

다음은 파일 속성 중 필수 속성이다.

  • 디렉토리 속성 : 서브 디렉토리를 위한 디렉토리 엔트리인지 구분하는 속성

  • 긴 파일명 속성 : 다른 레이아웃을 갖는 엔트리 유형인지 구분하는 속성

  • 볼륨 레이블 속성 : 하나의 디렉토리에만 설정되는 속성

 

다음은 나머지 4개의 부가 속성이다.

  • 읽기 전용 속성 : 파일 쓰기를 방지하는 속성

  • 숨김 속성 : 파일과 디렉토리 목록을 보여줄 때 사용자에게 해당 속성이 설정된 파일이나 디렉토리를 보여주지 않는 속성

  • 시스템 속성 : 시스템 파일로 구분하는 속성

  • 아카이브 속성 : 일반적인 파일 속성

 

디렉토리 엔트리에는 시간 정보도 포함되는데 세부적으로 나누어 보면 수정 시간(Modify), 접근 시간(Access), 생성 시간(Create)로 나누어진다.

 

디렉토리 엔트리의 할당 상태는 첫 바이트를 통해 알 수 있으며, 할당된 엔트리는 자신이 할당된 파일이나 디렉토리 이름을 사용하는데 할당 상태인 경우 자신이 할당된 파일명이나 디렉토리 명의 첫 글자가 첫 바이트가 된다.

 

하지만 할당되지 않은 상태라면 디렉토리 엔트리 첫 바이트는 '0xE5'로 설정된다.

 

 

클러스터 연결

  • 디렉토리 엔트리는 클러스터 시작 주소를 포함

  • FAT 구조체는 파일에 할당된 클러스터를 찾는데 사용

  • 클러스터 할당 상태는 FAT 엔트리 값이 0이 아니면 할당 상태이고 0이면 비할당 상태인 것으로 판단 가능

  • FAT 엔트리는 다음 클러스터 주소, 파일 끝(EOF), 불량 섹터가 있는 클러스터를 보여주는 값을 포함

 

다음은 디렉토리 엔트리와 FAT 엔트리가 클러스터를 찾을 때 어떻게 연관되는지를 보여준다.

 

[그림 5] 디렉토리 엔트리와 FAT 엔트리 관계

 

디렉토리

  • OS는 새로운 디렉토리가 생성되면 클러스터를 할당하고 0으로 초기화

  • 디렉토리 크기 필드를 사용하지 않는 경우 항상 0으로 설정

  • 디렉토리 크기 결정 방법은 '클러스터 연결' 원리와 동일

  • 생성 이후에는 생성 시간, 접근 시간, 수정 시간을 업데이트하지 않음 (디렉토리 생성 날짜 무결성을 검증하는데 사용하기도 함)

  • 이유는 디렉토리 생성 날짜와 시간은 디렉토리 내용의 '.' 와 '..' 의 생성 날짜와 시간이 동일하기 때문

 

만약 서로 값이 다르다면 이는 악의적 사용자에 의해 변경되었거나 시스템의 어떠한 응용 프로그램에서 수정했을 가능성이 있다.

 

 

디렉토리 엔트리 주소

 

디렉토리 엔트리 주소를 찾기 위해서는 파일명이나 디렉토리 명의 전체 이름을 사용하는 방법이 있지만, 이 방법에는 다음과 같은 두 개의 문제점이 존재한다.

 

1) 파일이 지워졌을 때의 충돌성

  • 1-1.txt 파일과 2-1.txt 파일이 있다고 가정

  • 파일이 지워지면 해당 디렉토리 엔트리는 첫 바이트가 0xE5로 설정되어 파일명이나 디렉토리명의 첫 글자가 지워짐

  • 이럴 경우 두 txt 파일은 -1.txt, -1.txt 파일명이 되어 이름이 충돌하게 됨

 

2) 디렉토리 엔트리 재할당

  • 디렉토리가 삭제된다고 하여 디렉토리 내용도 모두 데이터 영역에서 삭제되는 것은 아님

  • 삭제된 디렉토리 엔트리 자리에 새로운 디렉토리가 생기고 해당 디렉토리의 디렉토리 엔트리가 할당되면 디렉토리 내용들은 모두 고아 상태가 됨 (이러한 파일들을 고아 파일이라고 함)

 

고아 상태(클러스터 11의 상태)가 된 파일들을 일반 커맨드 명령어로는 접근할 수 없고 데이터 영역의 섹터를 전체적으로 분석해야만 찾을 수 있다.

 

다음은 고아 파일에 대한 내용이다.

 

[그림 6] 고아 파일

 

시간 값 할당

  • 디렉토리 엔트리에 포함되는 시간 값들은 부가적 데이터

  • 잘못된 값을 가지고 있을 수도 있음 

 

1) 생성 시간

  • 새로운 파일을 생성하면 새로운 디렉토리 엔트리를 할당하는데 이때 설정 됨

  • 다른 디렉토리나 다른 디스크로 파일을 이동시키면 이동시킨 디렉토리나 디스크로 옮겨진 원본 파일의 새로운 엔트리가 할당

  • 새롭헤 할당된 엔트리를 기존 원본 엔트리가 덮어 씌움 (생성 시간 변하지 않음)

  • 예외 경우가 있으며, 커맨드 명령어로 다른 디렉토리나 디스크로 이동시킬 시 생성 시간은 이동 시간으로 다시 할당

  • 복사의 경우 새로운 파일로 간주하여 새로운 엔트리가 생성되고 새롭게 생성 시간이 할당 됨

 

2) 수정 시간

  • 윈도우가 파일에 내용을 써 넣을 때 설정 됨

  • 속성이나 파일명은 수정 시간 업데이트에 영향을 주지 않음

  • 파일의 이동 및 복사할 시에 새롭게 할당된 엔트리는 원본 엔트리의 수정 시간을 할당 받음

  • 윈도우 경우 응용 프로그램이 파일에 접근하여 내용을 수정한 후 저장하지 않아도 수정 시간을 새롭게 할당

 

3) 접근 시간

  • 파일을 열 때나 클릭할 때 설정 됨

  • 파일을 열 때 할당 됨

  • 파일의 속성 창 버튼을 클릭하면 할당

  • 파일을 다른 볼륨으로 이동시킬 시 윈도우는 해당 파일의 내용을 참조하기 위해 파일에 접근하고 이때 접근 시간 또한 다시 할당


(5) FAT 파일 이름 관리

  • FAT은 파일명의 길이가 8보다 크거나, 이름에 특별한 문자가 있으면 디렉토리에 LFN(Long File Name) 타입을 추가

  • LFN 타입을 갖고 있는 디렉토리(파일)은 SFN(Short File Name)이라는 디렉토리 엔트리를 또 갖게 됨

  • LFN 엔트리는 시간, 크기, 시작 클러스터 정보를 포함하지 않아 SFN이 대신하여 해당 정보들을 포함하기 때문에 추가되는 것

  • LFN과 SFN 속성 항목은 같은 위치에 존재, LFN 엔트리의 경우 특별한 속성 값을 사용함

  • 해당 속성 항목을 제외한 나머지 바이트들은 UTF-16으로 인코딩된 13개의 유니코드 문자들을 저장하는데 사용

  • 만약 파일명의 길이가 13글자 이상이면 추가적으로 LFN 엔트리를 사용

  • LFN 엔트리는 SFN 엔트리와의 관계를 나타내는 체크섬을 포함

 

LFN 엔트리는 파일명만 포함하며 디렉토리 엔트리에 파일 할당이 비할당 상태로 전환되는 것은 LFN 엔트리가 비할당 상태로 전환되는 것을 뜻한다.

 

그리고 이때 디렉토리 엔트리 첫 번째 바이트가 '0xE5'로 설정된다.

 

LFN 엔트리들은 순서가 반대이기 때문에 파일명 첫 번째 부분이 SFN 엔트리와 가깝다.


(6) 파일 생성 및 삭제

 

파일 생성 과정

  • 디렉토리(dir)는 생성되어 있으며 클러스터 크기는 4096byte

  • 파일 크기는 5000byte라고 가정한 과정

 

1) 볼륨 섹터 0에서 부트 섹터를 참조하고, FAT 구조체와 데이터 영역, 루트 디렉토리 위치를 파악한다.

 

[그림 7] 1번 과정

 

2) 디렉토리를 찾기 위해 루트 디렉토리에서 각 디렉토리 엔트리를 해석하고, 찾으려고 하는 디렉토리 이름 및 속성을 이용하여 찾으려고 하는 디렉토리의 엔트리를 찾는다.

 

[그림 8] 2번 과정

 

루트 디렉토리에는 '.' 이 존재하지 않으나, 이미지에는 루트 디렉토리를 나타내기 위한 방편으로 추가하였다.

 

 

3) dir 시작 클러스터(10)의 내용을 읽고, 사용 가능한 디렉토리 엔트리를 찾아 파일 명을 입력한 후 할당 상태로 전환시킨다.

 

또 파일의 크기와 시간 값도 입력한 후 파일 내용을 위한 클러스터를 할당하기 위해 FAT 영역의 FAT 구조체를 이용한다.

 

FAT 구조체에는 파일명, EOF, 다음 클러스터 주소 데이터, 타입 등이 포함된다.

 

FAT 구조체로 클러스터를 할당한 후 클러스터 10의 File.txt 디렉토리 엔트리에 시작 클러스터를 입력하고, 할당된 클러스터에 파일 내용을 입력한다.

 

[그림 9] 3번 과정

 

4) 하지만 클러스터 크기보다 파일 크기가 더 커 또 하나의 클러스터를 할당한다.

 

클러스터를 할당하기 위해 FAT 영역의 FAT 구조체를 이용한다.

 

적당한 구조체를 통해 또 하나의 클러스터를 할당한다.

 

[그림 10] 4번 과정

 

5) 시작 클러스터의 FAT 구조체에서 EOF 데이터를 지우고 다음 클러스터 주소를 입력한다.

 

그 후 나머지 파일 내용을 새롭게 할당된 클러스터에 입력한다.

 

[그림 11] 5번 과정

 

추가 내용으로는 위 [그림 11]에는 나와 있지 않지만, 클러스터 101의 FAT 구조체는 EOF로 설정 되어 있다.

 

 

파일 삭제 과정

 

1) 파일 생성 과정 전체 과정처럼 파일의 클러스터 연결 확인까지 진행한다.

 

2) 클러스터 연결 확인을 수행했다면 해당 파일과 연관되어 할당되어 있는 클러스터의 FAT 구조체 엔트리 모두를 0으로 설정한다.

 

3) 그 후 디렉토리 엔트리의 첫 바이트를 '0xE5'로 변경하여 해당 파일을 디렉토리 엔트리에서 할당 해제시킨다.

 

 

위 과정을 거치면 다음 사진과 같다.

 

[그림 12] 삭제 상태

 

위 [그림 12]의 상태가 되면 커맨드 명령어나 탐색기로는 해당 파일에 접근이 불가능하다.


(7) 파일 복구

  • 파일 삭제 과정을 보면 FAT 엔트리가 0이 되고 디렉토리 엔트리가 비할당 상태로 바뀌면서 디렉토리 엔트리의 첫 바이트가 '0xE5'로 설정 됨

  • 파일을 복구하기 위해서는 파일의 시작 위치(시작 클러스터)와 크기를 알아야 함

  • 하지만 시작 클러스터만 알 수 있을 뿐 나머지 연계되는 클러스터는 정확하게 알지 못 함 

 

파일 시스템의 파일 클러스터들 배치는 다음과 같이 매우 다양하다.

 

연속적인 클러스터 할당의 경우

 

[그림 13] 연속 할당 클러스터

 

위 [그림 13]의 경우 파일 복구가 매우 쉽다.

 

시작 클러스터인 45를 시작으로 파일의 크기만큼인 클러스터 48까지만 복구해주면 되기 때문이다.

 

 

할당 클러스터 사이의 다른 클러스터

 

[그림 14] 클러스터 단편화

 

위 [그림 14]의 경우 파일 내용 클러스터 사이에 전혀 다른 파일의 할당 클러스터가 위치 하고 있어 시작 클러스터인 45부터 파일의 크기만큼 복구를 시도하면 47이라는 전혀 다른 파일의 할당 클러스터가 섞여 완전한 복구가 되지 않는다.

 

 

할당 클러스터 사이의 비할당 클러스터

 

[그림 15] 클러스터 단편화 (2)

 

위 [그림 15]의 경우도 두 번째 경우와 마찬가지로 복구 시도 시 비 할당 클러스터 때문에 완전한 복구가 되지 않는다.

 

이런 문제점 해결을 위해 파일을 지우기 전 디스크 파일 조각 모음을 통해 클러스터를 한 곳으로 모아야 한다.

 

파일 조각 모음을 할 경우 클러스터가 좀 더 연속적으로 배치되기 때문이다.

 

지워진 후 파일 조각 모음은 의미가 없으며 해당 클러스터들은 다시 할당될 수 있기 때문에 불필요하다.


(8) FAT 파일 시스템 종류 결정

  • FAT 파일 시스템은 여러 종류가 있지만 정작 파일 시스템은 그 종류를 결정하는 기능이 없음

  • FAT 파일 시스템은 데이터 영역의 클러스터 개수에 따라 종류 결정 가능

  • 클러스터 개수를 알기 위해서는 데이터 영역의 섹터 개수를 알아야 함

  • FAT 12 / 16 파일 시스템의 경우 루트 디렉토리는 FAT 영역 다음 데이터 영역 첫 번쩨 섹터에 위치하며, 이 영역 다음 클러스터 2가 시작

  • FAT 32 파일 시스템 경우 루트 디렉토리가 유동적이어서 클러스터 2가 데이터 영역 첫 번째에 위치

  • 이러한 루트 디렉토리 엔트리 개수는 부트 섹터에서 알 수 있으며 FAT 32 경우에는 0

 

다음은 루트 디렉토리 섹터 개수(루트 디렉토리 크기)를 계산하는 계산식이다.

 

((루트 디렉토리 엔트리 개수 x 32) + (섹터 별 바이트1)) / (섹터 별 바이트)

 

 

클러스터에 할당된 섹터 수(데이터 영역)는 파일 시스템 전체 섹터에서 예약 영역 크기, FAT 영역 크기, 루트 디렉토리 크기를 빼면 된다.

 

파일 시스템 전체 섹터 수 - 예약 영역 크기 - (FAT 구조체 개수 * FAT 구조체 크기) - 루트 디렉토리 크기

 

 

위 계산식의 계산으로 인해 데이터 영역의 크기가 나오고 이 값을 클러스터 별 섹터 수로 나누면 클러스터 개수가 나온다.

 

데이터 영역 크기 / 클러스터 별 섹터 수

 

 

각 FAT 종류는 데이터 영역 클러스터 개수가 다음과 같이 다르다.

  • FAT 12 : 4,085보다 작을 때

  • FAT 16 : 4,085보다 크거나 같을 때

  • FAT 32 : 62,525와 크거나 같을 때


# Reference

 

http://www.yes24.com/Product/Goods/8511539

[Digital Forensic] RAID & Disk Spanning

 

RAID & Disk Spanning


(1) RAID(Redundant Arrays of Inexpensive Disks)

  • 성능 향상을 위해 디스크 하나 대신 여러 개를 사용하는 중복 디스크 개념

  • 하드웨어 컨트롤러나 소프트웨어 드라이버가 여러 디스크들을 하나로 병합

  • 컴퓨터는 그 볼륨을 단일 디스크로 인식

 

예전에는 RAID가 고성능 서버 컴퓨터에서만 사용되었지만, 요즘은 일반 Desktop 컴퓨터에도 쓰이고 있다. 

 

RAID 기술에는 여러 레벨이 있고 각 레벨마다 신뢰성과 성능 향상 등의 정도가 다르다.

 

총 7가지 레벨이 있으며 그 레벨들에 대하여 알아보자.


(2) RAID 레벨

2-1. RAID 레벨 0

  • RAID Level 0은 스트라이핑 모드 (Striping Mode)라고도 함

  • 2개 이상의 디스크를 사용, 두 디스크에 데이터를 볼륨 묶음으로 교차하여 나열해 놓은 방식

  • 해당 레벨은 읽기/쓰기 성능에 향상을 제공하지만, 데이터가 나누어져 나열되어 있는 경우이기 때문에 하나의 디스크만 고장 나도 데이터를 복구할 수 없음

 

[그림 1] RAID Level 0

 

2-2. RAID 레벨 1

  • RAID Level 1은 미러링 모드 (Mirroring Mode)라고도 함

  • 동일한 디스크가 두 개 있는 것

  • 한쪽 디스크에 데이터를 입력할 때 다른 한쪽 디스크에도 동일한 데이터가 입력됨

  • 신뢰성에서는 선호되는 구조지만, 한 번 입력 시 두 번의 디스크 입력 퍼포먼스로 인해 성능 저하와 디스크 구성 비용이 2배로 들어 일반적으로 사용하지 않는 구조

 

[그림 2] RAID Level 1

 

2-3. RAID 레벨 2

  • RAID Level 0의 장점과 신뢰성을 향상시킨 구조

  • 패리티 코드를 사용, 디스크 고장 시 데이터를 복구할 수 없는 문제점을 해결

  • 패리티 코드 계산 시에 해밍 코드가 사용되며 패리티 디스크 개수는 (저장 디스크 개수 -1)

 

[그림 3] RAID Level 2

 

2-4. RAID 레벨 3

  • RAID Level 2를 개선시킨 구조

  • 패리티 코드를 포함하는 많은 디스크를 단 하나의 디스크를 사용하여 동일한 효과를 볼 수 있도록 함

  • 패리티 코드 계산은 XOR 연산을 통해 계산

 

[그림 4] RAID Level 3

 

2-5. RAID 레벨 4

  • 구조는 Level 3와 별반 다를 것 없음

  • 차이는 패리티 코드 계산에 있으며, Level 3 경우 바이트 단위로 패리티 코드를 계산

  • 그러나 Level 4는 미리 정해진 블록 단위로 패리티 코드 계산

 

[그림 5] RAID Level 4

 

2-6. RAID 레벨 5

  • Level 4의 단점을 개선한 구조

  • 각 데이터들의 변화가 많을 경우 패리티 비트 또한 변화해야 하기 때문에 빈번한 접근으로 인해 디스크에 부하 발생

  • 이를 방지하기 위해 패리티 비트 디스크를 따로 만드는 것이 아닌 데이터 디스크 내에 패리티 비트를 저장하는 방식 사용

 

[그림 6] RAID Level 5

 

2-7. RAID 레벨 6

  • 신뢰성에 기반을 둔 구조

  • Level 5의 경우 두 개의 디스크에서 동시에 오류 발생 시, 복구하지 못하는 단점이 있는데 이를 해당 레벨에서 패리티 디스크를 하나 더 추가하여 해결

  • 디스크 하나가 더 추가되었다보니 구현 시 추가 비용이 발생

  • 데이터 (A ~ E) Q가 레벨 6에서 추가된 패리티 코드

 

[그림 7] RAID Level 6

 

지금까지 알아 본 RAID 구조들은 표준 구조들이며 현재는 시스템 별로 다른 구조를 혼용하여 사용하고 있다.

 

RAID 볼륨을 생성하는 방법으로는 하드웨어 방식과 소프트웨어 방식으로 나뉘며, 두 가지를 알아보도록 하자.


(3) RAID 구성 방식

3-1. 하드웨어 방식

  • 해당 방식은 하드웨어 장비로 RAID를 구성하는 방식으로 두 가지 방식으로 나눌 수 있음

 

1) 독립된 컨트롤러 방식

  • 해당 방식은 독자적인 프로세서와 메모리, 입출력 장치 등을 갖고 있어 CPU 없이도 입출력이 가능하여 최적화된 성능 발휘 가능

  • 하지만 별도로 메인보드에 장착되는 이유로 인해 가격이 비쌈

  • 볼륨 부팅 등의 경우에서 일어나는 악의적 행위들에 대해 안정적이며, 독립적이어서 시스템이 고장 나도 영향을 받지 않음

 

2) 일반적인 디스크에 삽입하는 컨트롤러

  • 하나의 칩(Chip)에 모든 기능이 구현되어 있는 형태

  • 다른 하드웨어와 통합하여 사용할 수 있고, 기존 I/O 컨트롤러 등과도 교체가 가능

  • 가격은 비교적 독립된 컨트롤러 방식에서 사용하는 장치보다 저렴

  • 이 방식은 독립된 컨트롤러 방식과 얻어지는 성과물은 대부분 같지만, 기존 하드웨어에 장착되어 있는 방식이기 때문에 다른 시스템으로 이전하여 사용하기 어려움

 

[그림 8] 하드웨어 RAID 방식 기본 구조

 

 

3-2. 소프트웨어 방식

  • RAID 기능이 소프트웨어적으로 구현된 방식

  • 이 방식으로 RAID를 구현할 경우 사용자는 볼륨만을 확인 가능

  • 각 디스크에 직접 접근하기 위해 유닉스 수준의 저수준 장치를 이용해야만 함

  • RAID 기능을 지원하는 OS는 MS Windows NT, 2000, XP, Apple Mac OS X, Linux, Sun Solaris, HP-UX, IBM AIX 정도가 있음

  • CPU를 사용하기 때문에 하드웨어 RAID에 비해 많은 제약이 있고 성능이 효율적이지 못함

  • 하드웨어 방식과 마찬가지로 두 가지로 나뉨

 

1) 순수 소프트웨어 방식

  • 하드웨어 없이 소프트웨어로만 구현하는 방식으로 구현 비용 저렴

  • 그러나 RAID 기능이 OS에 로드되기 전인 부팅 시에 일어나는 악의적 행위나 여러 가지 에러에 대해 안전하지 못함

  • CPU를 사용하므로 해당 시스템 성능에 영향을 주며 시스템 에러나 고장으로 인해 얻어지는 결과물에 대한 무결성 보장 못함

 

2) 하이브리드 방식

  • 순수 소프트웨어 방식의 RAID 기능이 OS에 로드되기 전 안전하지 못한 점 해결을 위해 하드웨어와 혼합하여 구현한 방식

  • 실제 구현은 소프트웨어 방식이며, 도움을 주는 하드웨어는 메인보드에 설정된 RAID BIOS

  • 해당 방식은 결국 소프트웨어 방식이기 때문에 RAID 기능이 OS에 로드된 후 에러나 악의적 행위에 대한 안전 보장 못함

  • 다른 시스템으로의 이전이 쉽지 않음

  • 무결성 또한 보장 못함

 

[그림 10] 소프트웨어 방식 기본 구조


(4) RAID 포렌식

  • RAID 볼륨을 분석할 때에는 어떻게 이미징 해야 하는지 선택해야 함

  • 각각 디스크를 이미징할 지, 아니면 각 방식에 의해 생성된 볼륨을 이미징할 지 선택

 

4-1. 하드웨어 방식

  • 해당 방식에서 사용하는 컨트롤러 경우 비교적 저렴하지만, 저렴하지 않은 것들도 있어 만약 디스크를 개별적으로 이미징한 경우 컨트롤러 구입이나 자신이 사용하는 RAID 볼륨을 생성하여 분석 필요

  • 하지만 만약 분석해야 할 시스템에 고가의 컨트롤러를 사용하고 자신이 갖고 있지 않은 컨트롤러라면 해당 컨트롤러를 구입해서 사용해야함 (쉽지 않은 일)

  • 그렇기에 개별적 디스크를 이미징하는 것은 이런 경우 좋지 못함 (그렇다고 디스크 이미징을 안 하면 안 됨)

 

RAID 볼륨을 만들지 않고 디스크 자체를 제한적인 방법들(Strings Search)로 분석을 시도해야 한다.

 

다양한 방법이 있겠지만 쉬운 방법으로는 해당 컨트롤러 드라이버를 갖추고 있는 Live CD(Linux)들로 부팅하여 수집하는 것이 있다.

 

 

4-2. 소프트웨어 방식

  • 해당 방식 컨트롤러 경우 소프트웨어이기 때문에 디스크를 이미징 하여도 되고 RAID 볼륨을 이미징 하여도 크게 문제 없음

  • 두 방식 모두 볼륨 이미징 방식을 포함하게 되는데 볼륨을 이미징할 때는 비할당 영역도 세심하게 살피고 주의해야 함


(5) 디스크 스패닝

  • RAID와 비슷한 개념으로 여러 디스크를 하나의 큰 디스크로 운영체제가 인식하게끔 하는 기술

  • 하지만 RAID와 같이 성능 향상이나 중복성 등은 지원하지 않고, 오직 디스크 크기만을 늘려 줌

  • 이러한 점 때문에 통합되어 있는 디스크에 또 다른 디스크 추가나 파일 시스템 크기를 동적으로 늘릴 수 있음

 

많은 운영체제에서 디스크 스패닝 기술을 지원하고 있지만 이 글에서는 리눅스와 윈도우만 다룬다.

 

5-1. 리눅스 디스크 스패닝

  • 두 가지로 된 디스크 스패닝 기술이 있으며 MD, LVM으로 나눌 수 있음

 

리눅스는 부팅할 때 디스크 스패닝 볼륨을 마운트하지 않더라도 슈퍼블록 값은 업데이트 한다.

 

이를 이용해 커널이 디스크를 제거 했는지와 디스크 순서를 체크한다.

 

1) MD

  • 리눅스에는 'MD 드라이버'라고 불리는 드라이버가 있는데 이 드라이버는 도스 기반 파티션을 사용

  • 파티션이 할당된 순서대로 목록을 정리한 'etc/raidtab' 이라는 파일이 존재하는데 볼륨은 이 파일 없이 마운트 가능

  • 해당 파일 설정 값 중에 persistent-superblock이라는 항목 값이 0일 경우 설정 데이터들이 /etc/raidtab 파일 안에만 존재

  • 값이 1일 경우 설정 데이터들이 MD 장치를 생성할 수 있도록 디스크나 파티션 끝에 포함 됨 

 

이는 '자동 감지' 기능을 뜻하며 자동 감지 기능이 동작하기 위해서는 설정 데이터가 위치한 파티션 타입이 'Linux raid partition with autodetect using persistent superblock(0xfd)'이어야 한다.

 

부팅하는 동안 MD 장치가 생성된 것을 확인하려면 Messages 로그를 보면 된다.

 

MD 장치가 생성되도록 superblock이 설정되어 있다면 디스크나 파티션은 1024Byte로 나눠진 여러 구역의 구조를 갖는다.

 

각 구역에는 다음과 같은 정보가 포함되어 있다.

구역

정보

첫 번째 구역

디스크 스패닝 또는 RAID 버전, 디스크 수, 생성 시간, 식별자

두 번째 구역

마지막 업데이트 시간, 카운터, 볼륨 상태, 동작 중인 디스크와 오류난 디스크 수

나머지 구역

주/부 장치 번호, 볼륨 내 각 장치 역할, 디스크 상태

 

2) LVM 

  • Logical Volume Manager의 약자로, MD의 개선된 기술로 볼륨 그룹이라는 것을 사용

  • LVM을 사용하려면 파티션은 'Linux Logical Volume Manager Partition(0x8e)'이어야 함

  • 각 시스템에는 1개 또는 그 이상 볼륨 그룹이 있으며, 각 볼륨 그룹은 /dev/ 디렉토리에 하위 디렉토리를 가짐

  • 물리적 확장 세트를 볼륨 그룹을 이용하여 논리적 볼륨을 생성하는데 이는 물리적 확장 세트들을 연속적으로 연결하거나 스트라이핑을 사용하여 생성

  • 이렇게 생성된 볼륨은 /dev/ 볼륨 그룹 하위 디렉토리 내 장치 파일이 주어지며, 논리적 볼륨 설정 데이터는 로컬 시스템과 볼륨 두 곳에 저장 됨

  • 설정 파일 같은 경우는 '/etc/lvmtab, /etc/lvmtab.d'에 저장 됨 (설정 파일들은 바이너리 파일이며, vgimport, vgscan, vgchange 등의 유틸리티로 업데이트 됨)

 

[그림 11] LVM

 

위 [그림 11]에서 디스크 0과 1은 물리적 세트이고, 볼륨 그룹을 통해 생성된 디스크는 논리적 세트이다.

 

 

5-2. 윈도우 디스크 스패닝

  • 윈도우는 NT 버전 이후로 디스크 스패닝을 지원해 왔으며 사용하는 기술은 LDM

  • LDM은 기본 파티션, 디스크 스패닝, RAID 레벨 0, 1, 5와 유사하고 간단한 볼륨들을 지원

  • 기본 디스크들은 LDM이 사용되지 않으며 LDM이 사용되기 위해서는 디스크에 추가적 데이터 구조체가 포함 되어야 함

 

[그림 12] LDM(동적 디스크) 기본 구조

 

위 [그림 12]를 보면 LDM 파티션 영역 뒤에 LDM 데이터베이스라는 것이 있는데 이 영역은 동적 파티션을 정의하고 논리적 볼륨을 생성한 규칙을 만드는 곳이다.

 

이 영역은 다음과 같은 엔트리를 갖는다.

  • 디스크 엔트리 : 도스나 GPT 디스크가 있는 각 동적 디스크를 위해 존재

  • 파티션 엔트리 : 동적 디스크 파티션 방법을 설명

  • 컴포넌트 엔트리 : 파티션들의 결합 방법을 설명

  • 볼륨 설명 엔트리 : 파티션 컴포넌트 유형을 적용한 결과인 논리적 볼륨을 포현


(6) 디스크 스패닝 포렌식

  • 리눅스 MD 볼륨을 분석하기 위한 최선의 선택은 단일 드라이브 또는 파티션으로 볼륨을 수집하고 표준 분석 도구를 사용하는 것

  • 슈퍼블록이 설정되어 있다면 쉽겠지만, 그렇지 않다면 대상 시스템에서 /etc/raidtab 파일 생성 필요

  • 그 후 raidstart 명령어로 MD 장치 생성 후, dd 종류 도구로 MD 장치를 이미징 할 수 있음

  • 수집 후에 MD 장치를 정지시키기 위해 raidstop 명령어 사용 필요

 

리눅스 LVM 볼륨 분석은 MD 장치보다 분석을 더 자동화할 수 있다.

 

시스템으로부터 디스크를 분리하여 신뢰할만한 리눅스 시스템에 디스크를 결합하여 분석할 수 있고, LVM을 지원하는 Live CD(Linux)를 대상 시스템에 부팅 시켜 분석이 가능하다.

 

vgscan 명령어를 사용하면 '/etc/lvmtab, /etc/lvmtab.d' 파일이 자동 생성되는데, 자동 생성되면 vgchange -a y 명령어를 실행하여 볼륨을 활성화 시킨 후에 dd 종류 도구로 이미징 시도가 가능하다.

 

윈도우 LDM 경우 분석이 어렵고, 읽기 전용으로 볼륨을 재생성하는 것 또한 쉽지 않다.

 

Live CD(Linux)를 사용하여 LDM을 분석할 수 있는데 이는 조금 수정이 필요하다.

 

기본적으로 리눅스는 LDM을 지원하지 않아 커널 재컴파일을 해야 하며, 재컴파일된 커널은 데이터베이스를 읽고, 각 동적 디스크에 물리적 파티션을 위해 하드 디스크 장치를 생성하게 된다.

 

위와 같은 장치와 방법을 통해 이미징을 시도하면 된다.


# Reference

 

http://www.yes24.com/Product/Goods/8511539

[Digital Forensic] 볼륨과 파티션

 

볼륨과 파티션

 

파일 시스템이 위치하는 볼륨과 파티션 구조를 모르고서는 파일 시스템을 정확히 분석해낼 수 없다.

 

대부분 파티션과 볼륨을 혼용하여 사용하는데 정확히 구분하면 이는 잘못된 사용이다.


(1) 볼륨

  • 운영체제나 응용 프로그램이 데이터를 저장해 사용하도록 주소가 지정된 섹터들의 집합

  • 섹터들이 연속적이지 않다라는 뜻을 가짐

 

볼륨은 다음과 같이 두 가지 개념을 가진다.

  • 여러 개의 저장 볼륨에서 한 개의 저장 볼륨으로 조합하는 것 (더 작은 볼륨들로 나뉘거나 더 큰 볼륨으로 합쳐질 수 있음)

  • 저장 볼륨들을 독립적인 파티션들로 분할하는 것

 

 

Windows와 Unix의 볼륨 사용 차이

  • Windows 경우 C, D와 같은 드라이브 문자가 있으나, Unix의 경우 이러한 문자들이 없음

  • Unix는 / 로 시작하는 루트 디렉토리가 존재하며, 하위에 다른 디렉토리나 볼륨 위치

 

볼륨 분석은 조사관이 수행한다기 보다는 도구에 의해 일반적으로 진행된다.

 

분석 기술은 의외로 간단하며, 분석 도구들의 분석 방법을 살펴보면 대부분 파티션 테이블의 위치를 확인하고 그 값을 읽어 그 정보를 출력하여 준다.

 

테이블에는 파티션 시작, 마지막 섹터 값, 파티션 유형 등의 정보가 들어 있으며 이 정보를 토대로 파티션 시스템(이미지)에서 각 볼륨들을 파악한다.

 

 

그리고 일관성 검사라는 것이 있는데 이 검사는 파티션을 제외한 영역에 증거가 존재하는지 조사하는 기능이다.

 

조사관은 파티션 테이블을 확인하여 파티션의 시작과 마지막 섹터를 확인하고 각 파티션들을 목록화하여 파티션 사이에 할당되지 않은 섹터가 있는지 확인하여 그곳에 증거가 없는지 분석하여야 한다.

 

[그림 1] DOS 파티션 내부

 

위 그림은 DOS 파티션 내부 파일 시스템 파티션을 보기 쉽게 그림으로 표현한 것이다.

 

이러한 정보들로 파티션 내부의 파일 시스템 파티션을 추출할 수 있으며 도구로는 dd를 사용할 수 있다.

 

dd의 사용 방법은 다음과 같다.

 

dd if=<DOS 파티션 이미지> of=<추출 결과 저장 파일명> bs=<한번에 읽어 들일 블록 크기>  skip=<건너 뛸 길이> count=<길이>

 

위와 같이 파티션 내부 파일 시스템 파티션을 추출해도 되지만 요즘 도구들은 파티션과 파일 시스템 분석을 모두 하여 데이터까지 조사관에게 보여줘 특별한 경우가 아니라면 위와 같이 일일이 파일 시스템을 이미지에서 분리해내지 않아도 된다.

 

대표적으로는 AccessData의 FTK와 Guidance의 EnCase가 있다.


(2) 파티션

  • 볼륨 색터들의 연속적인 것

  • 일반적으로 파티션은 파티션 테이블이라는 것을 가짐

  • 흔히 파티션을 구성할 때, 볼륨의 레이아웃을 구성하는 것을 말하는 데 레이아웃을 구성하기 위해서는 파티션 테이블 값이 절대적으로 필요

  • 파티션 테이블이 잘못된 값을 갖는다면 볼륨 레이아웃은 정상적으로 작동하지 않음

  • 파티션 테이블에도 부가적인 필드들이 존재하며, 필드들의 값은 볼륨 레이아웃 구성과 관련이 없어 값이 잘못되도 상관 없음

 

2-1. 도스 파티션

  • 우리가 흔히 사용하는 컴퓨터 파티션 형식

  • 자주 사용하고 흔히 접하는 도스 파티션은 정확한 명세가 제공되지 않음

  • Microsoft는 이런 파티션 시스템을 MBR(Master Boot Record) 디스크라고 부름

  • 도스 파티션은 도스, 윈도우, 리눅스 IA32 기반 FreeBSD와 OpenBSD 시스템에서 사용

  • 흔한 시스템이지만 의외로 복잡한 구성을 가짐ㅁ

  • 도스 파티션을 사용하는 Disk는 512Byte 섹터 내의 MBR을 갖고 있음

 

MBR에는 다음과 같은 정보가 있다.

 

1) 부트코드

 

2) 파티션 테이블

  • 파티션 시작 CHS 주소

  • 파티션 마지막 CHS 주소

  • 파티션 시작 LBA 주소

  • 파티션 섹터 수

  • 파티션 타입

  • 플래그

3) 시그니처

 

CHS(Cylinder, Head, Sector)는 8GB 이하 디스크에서만 사용이 가능하며, LBA는 TB(TeraByte) 크기의 디스크까지 사용 가능하다.

 

파티션 타입은 파일 시스템을 나타내는 것으로, Ext, NTFS, HFS+ 등이 있다.

 

운영체제들은 운영체제별로 파티션 타입이 다르며 리눅스는 파티션을 마운트할 때에 파티션 타입을 참조하지 않아 NTFS 파티션 타입이어도 리눅스 파티션 타입인 FAT으로 파티션을 마운트한다.

 

이와 달리 윈도우 경우 파티션 타입을 참조하여 NTFS 타입이 아니면 마운트하지 못한다.

 

 

위와 같은 방법으로 파티션을 숨길 수 있는 방법이 있다.

 

간단히 설명하자면, 파티션 타입에 1비트를 변조하여 윈도우에서 파티션을 인식하지 못하게 하는 것이다.

 

플래그는 파티션 부팅 여부를 나타내는 항목이며, 컴퓨터가 부팅할 때 운영체제가 어떤 파티션에 위치하고 있는지 구분할 때 사용된다.

 

MBR은 4개의 파티션만 표현할 수 있으며 4개의 엔트리를 이용하여 파티션들이 할당된 디스크 구조를 표현할 수 있다.

 

하지만 사용자에 따라 4개 이상의 파티션이 필요할 때가 있으며, 이러한 경우를 위해 확장 파티션 개념이 생겼다.

 

[그림 2] 기본 확장 파티션 구조

 

확장 파티션 개념은 3개의 파티션은 기본적인 파티션으로 두고 나머지 1개의 파티션을 확장 파티션으로 만들고 그 안에 또 다른 파티션들을 만드는 것이다.

 

예를 들어 12GB의 디스크에 6개 파티션을 구성하려고 하면 확장 파티션 개념으로 해야 할 것이다.

 

[그림 3] 예문 확장 파티션

 

부 파티션 앞에 있는 MBR들은 위 [그림 3]과 같은 방법으로 모두 부 파티션과 부 확장 파티션을 갖게 된다.

 

부 파티션 1, 2를 만들고 부 확장 파티션 1을 만들게 되며 대부분의 OS에서는 세 번째 파티션을 무시하게 되어 '부 확장 파티션1'이 인식이 되지 않는다. (크기를 잘못 인식하는 경우도 발생)

 

확장 파티션에는 파티션 테이블 엔트리에서 사용되는 특별한 타입들이 있는데 위와 같이 복잡한 구조가 된 것은 확장 파티션 타입이 여러 가지 종류가 있으며 파티션 사이를 구분하기 어렵기 때문이다.

 

 

부트 코드

  • MBR 섹터 내에 1~446 바이트에 존재하며, 나머지는 파티션 테이블 엔트리

  • MBR 파티션 테이블을 처리한 후 부팅 플래그가 있는 파티션을 찾고 부팅 가능한 파티션의 첫 번째 섹터를 찾은 후 운영체제 코드를 실행시킴

  • 이 영역에 바이러스 침투 시, OS 부팅 시 바이러스도 함께 OS 부팅 시 매번 실행되는 것

  • 부트코드를 수정하면 OS 멀티 부팅이 가능

 

MBR

  • 512 Byte 크기의 구조체를 사용

  • 첫 446Byte는 어셈블리 부트 코드를 위해 예약이 되어 있음

 

MBR은 다음 표와 같은 내용들을 담고 있다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 445

부트 코드

478 ~ 493

파티션 테이블 엔트리 3

446 ~ 461

파티션 테이블 엔트리 1

494 ~ 509

파티션 테이블 엔트리 4

462 ~ 477

파티션 테이블 엔트리 2

510 ~ 511

시그니처 (0xAA55)

 

MBR은 기본적으로 4개의 파티션을 파티션 테이블 엔트리(16Byte)로 표현할 수 있어 파티션 테이블 엔트리가 4개이다.

 

 

각 파티션 레이아웃을 구성하는 파티션 테이블 엔트리의 구조는 다음과 같다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 0

부팅 플래그

5 ~ 7

파티션 끝 CHS 주소

1 ~ 3

파티션 시작 CHS 주소

8 ~ 11

파티션 시작 LBA 주소

4 ~ 4

파티션 타입

12 ~ 15

섹터 크기

 

부팅 플래그는 반드시 필요한 것은 아니다.

 

하나의 운영체제가 설치되어 있는 시스템(부팅 플래그 default : 0x80)이라면 부팅 플래그가 필요해지며, 여러 운영체제를 멀티 부팅하는 시스템이라면 사용자가 OS 부팅을 선택하기 때문에 이러한 경우에는 부팅 플래그가 필요 없다.

 

위 표에서 CHS 항목 두 가지가 있는데 이 항목들은 최신 시스템에서는 필수적이지 않다.

 

파티션 타입은 파일 시스템 타입을 구분짓기 위해 필요한 항목이다.

 

주요 파티션 타입 목록은 다음 표와 같다.

타입

설명

타입

설명

0x00

Empty

0x83

Linux

0x01

FAT12, CHS

0x84

Hibernation Mode

0x04

FAT16, 16 ~ 32MB, CHS

0x85

Linux Extended

0x05

Microsoft Extended, CHS

0x86

NTFS Volume Set

0x06

FAT 32MB ~ 2GB, CHS

0x87

NTFS Volume Set

0x07

NTFS

0xA0

Hibernation Mode

0x0B

FAT32, CHS

0xA1

Hibernation Mode

0x0C

FAT32, LBA

0xA5

FreeBSD

0x0E

FAT16, 32MB ~ 2GB, LBA

0xA6

OpenBSD

0x0F

Microsoft Extended, LBA

0xA8

Mac OS X

0x11

Hidden FAT12, CHS

0xA9

NetBSD

0x14

Hidden FAT16, 16 ~ 32MB, CHS

0xAB

Mac OS X Boot

0x16

Hidden FAT16, 32MB ~ 2GB, CHS

0xB7

BSDI

0x1B

Hidden FAT32, CHS

0xB8

BSDI Swap

0x1C

Hidden FAT16, 16 ~ 32MB, LBA

0xEE

EFI GPT Disk

0x42

Microsoft MBR, Dynamic Disk

0xEF

EFI System Partition

0x82

Solaris x86

0xFB

VMware File System

0x82

Linux Swap

0xFC

VMware Swap

 

확장 파티션 MBR 또한 위 MBR의 구조와 다를 바가 없으나 시작 섹터의 주소가 디스크 특정 지점의 상대적 주소이기 때문에 파티션 테이블 엔트리가 조금 다르다.

 

  • 부 파일 시스템 엔트리 시작 주소는 현태 파티션 테이블 주소에서 상대적 주소

  • 부 확장 파티션 엔트리 시작 주소는 주 확장 파티션에서 상대적

 

요즘은 디스크 레이아웃을 분석해 주는 도구들이 많이 개발되어 있어 조사관들이 사건 조사하기 편하게 해주기는 하지만 도스 파티션 경우 흔하게 접할 수 있는 파티션 시스템이므로 도스 파티션애 대해서는 필히 알고 있어야 한다.

 

 

2-2. 애플 파티션

  • 도스 파티션보다 적게 사용되지만 사용자가 증가하고 있는 추세이며 여러 장비들에 애플 파티션이 적용

  • 매킨토시 시스템에는 파티션 맵이라고 하는 이미지가 있는데 이것은 매킨토시 시스템이 파일들을 전송하기 위해 사용하는 디스크 이미지

  • 파티션 맵 이미지 디스크는 윈도우 zip 파일, 유닉스 tar 파일과 유사한 형태

  • 파티션 맵은 데이터 영역 위치, 부트 코드 위치 등의 데이터를 가짐

 

[그림 4] 애플 디스크 기본 구조

 

[그림 4]에서 보는 것처럼 파티션 맵은 첫 번째 엔트리가 자신의 엔트리이고 나머지 엔트리가 파티션 엔트리이다.

 

파티션 맵에서 파티션 맵 엔트리는 파티션 맵의 최대 크기를 나타낸다.

 

파티션 맵은 MBR과 동일하게 512Byte 크기이며, 여러 구조체로 구성되고 두 번째 섹터에서 시작한다.

 

또 모든 파티션을 배치할 때까지 구조체를 계속 할당한다.

 

파티션 데이터 구조체들은 연속적인 섹터들 내에 구성되며, 각 맵 엔트리는 전체 파티션 수를 나타낸다.

 

 

다음은 애플 파티션 맵 엔트리 오프셋 구조이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 1

시그니처 (0x504D)

92 ~ 95

부트 코드 시작 섹터

2 ~ 3

예약 영역

96 ~ 99

부트 코드 크기

4 ~ 7

파티션 총 개수

100 ~ 103

부트 적재 코드 주소

8 ~ 11

파티션 시작 섹터

104 ~ 107

예약 영역

12 ~ 15

파티션 크기

108 ~ 111

부트 코드 엔트리 지점

16 ~ 47

파티션 이름

112 ~ 115

예약 영역

48 ~ 49

파티션 타입 (ASCII)

116 ~ 119

부트 코드 체크섬

80 ~ 83

데이터 영역의 파티션 시작

102 ~ 135

프로세서 타입

84 ~ 87

데이터 영역 크기

136 ~ 511

예약 영역

88 ~ 91

파티션 상태

   

 

위 표의 데이터 구조체 항목들 중 파티션 상태 영역이 있는데 이 필드는 다음 표의 목록들 중 하나의 값을 가진다.

타입

설명

0x00000001

앤트리 유효 (A/UX만 해당)

0x00000002

엔트리 할당 (A/UX만 해당)

0x00000004

엔트리 사용 중 (A/UX만 해당)

0x00000008

엔트리가 부트 정보를 포함 (A/UX만 해당)

0x00000010

파티션 읽기 가능 (A/UX만 해당)

0x00000020

파티션 쓰기 가능 (매킨토시, A/UX만 해당)

0x00000040

부트 코드 위치가 독립적 (A/UX만 해당)

0x00000100

파티션이 연결-호환 드라이버를 포함 (매킨토시만 해당)

0x00000200

파티션이 실제 드라이버를 포함 (매킨토시만 해당)

0x00000400

파티션이 연결 드라이버를 포함 (매킨토시만 해당)

0x40000000

시작될 때 자동으로 마운트 (매킨토시만 해당)

0x80000000

시작 파티션 (매킨토시만 해당)

 

조사할 때 파티션 맵은 두 번째 섹터에서 시작하므로 애플 디스크의 파티션들을 구분하려면 두 번째 섹터에서 파티션 맵의 데이터 구조체들을 통해 정보를 수집해야 한다.

 

애플 디스크의 파티션들을 분석할 경우 고려해야 할 사항으로는 파티션 맵의 구조체 데이터들 중 사용되지 않는 필드들이 있어 적은 양의 데이터가 사용되지 않는 필드에 숨겨질 수 있다.

 

또 파티션 데이터 구조체와 파티션 맵 끝 사이 섹터에 데이터가 숨겨질 수도 있다.

 

 

2-3. BSD 파티션

  • 컴퓨터 포렌식 조사 대상에는 BSD 시스템들이 많이 속함 (리눅스도 마찬가지)

  • IA32 기반 하드웨어(x86/i386)를 사용하며 자체 분할 시스템을 사용

  • IA32 기반 하드웨어를 사용하기 때문에 MS 제품들과 같은 디스크에 공존할 수 있도록 설계됨

  • 도스 파티션보다 간단하기 때문에 이해하는 데 매우 쉬움

  • 단점으로 애플 파티션 맵보다는 약간의 한계점을 가짐

  • 도스 파티션과 공존할 수 있기 때문에 도스 파티션에서 생성한 볼륨에 위치할 수 있음

  • 즉 '주 도스 파티션'이 될 수 있음

 

[그림 5] 도스 파티션과 BSD 파티션 공존

 

BSD 파티션의 핵심은 디스크 레이블(Disk Label)이다.

 

최소 크기는 276Byte이며 BSD 파티션 두 번째 섹터에 위치한다.

 

일부 IA32가 아닌 시스템들은 첫 번째 섹터에 위치하기도 한다.

 

디스크 레이블의 구조체들은 디스크 하드웨어 명세서를 포함하고, 8개 또는 16개의 BSD 파티션 테이블을 포함한다.

 

애플 파티션 맵과 다르게 BSD 파티션 테이블은 크기가 고정적이다.

 

BSD 파티션 테이블의 엔트리 항목들은 다음과 같다.

  • BSD 파티션 시작 섹터 주소 : 도스 파티션이나 디스크 레이블에서의 상대적 주소가 아닌 디스크 시작 주소에서의 상대적 주소

  • BSD 파티션 크기

  • 파티션 타입 : BSD 파티션에 있는 파일 시스템 타입을 구분할 때 쓰이는 항목

  • UFS 파일 시스템 조각 크기

  • 블록당 UFS 파일 시스템 조각의 수

  • UFS 실린더 그룹 당 실린더 개수 

 

마지막 3개 항목은 UFS 파일 시스템을 포함할 때만 사용된다.

 

BSD 파티션은 구조체 하나를 읽어서 전체 파티션 구조를 파악한다.

 

 

2-4. FreeBSD

  • 하나의 디스크에서 도스 파티션과 BSD 파티션 둘 다 사용할 수 있도록 되어 있음

  • FreeBSD에서 도스 파티션은 '슬라이스'라는 용어로 불리며, BSD 파티션은 '파티션'으로 불림

  • 디스크 레이블 구조체는 FreeBSD 도스 파티션에 있으며, 그 구조체는 도스 파티션 내 존재하는 BSD 파티션 레이아웃을 구성하는데 쓰임

  • FreeBSD는 각 파티션과 슬라이스에 특별한 장치 이름을 부여하는데 슬라이스의 경우 디스크 기본 이름에 's'와 번호를 부여

  • 파티션의 경우 슬라이스 이름에 알파벳으로 순서를 매김

 

파티션의 경우 이름을 줄일 수도 있는데 다음 그림과 같다.

 

[그림 6] 슬라이스 파티션 이름 할당

 

BSD 파티션은 이름에 따라 특별한 의미를 갖게 되는데 'a' 라는 이름을 할당 받은 파티션의 경우 보통 부트 코드가 위치하고 있는 파티션이 된다.

 

'b' 이름을 할당 받은 파티션은 보통 스왑 공간을 나타내며, 'c' 이름을 할당 받은 파티션은 보통 전체 슬라이스를 나타내고, 'd' 이름을 할당 받은 파티션은 보통 어떠한 파티션도 될 수 있는 파티션을 나타낸다.

 

하지만 이 이름 부여 원칙은 절대적이 아니며 수정이 가능하다.

 

 

2-5. OpenBSD (NetBSD)

  • 원래 OpenBSD 코드와 NetBSD 코드는 함께 있었지만 지금은 따로 분리 됨 (같은 구조라고 보면 됨)

  • OpenBSD에서는 도스 파티션이 단지 OpenBSD 파티션의 시작 부분을 확인시켜 주기 위해서만 사용되기 때문에 OpenBSD 커널이 적재되어 실행되면 도스 파티션은 무시

  • 이름 할당 방법은 FreeBSD와 동일하지만, 슬라이스 개념은 없음

  • BSD 시스템 부트 코드는 첫 번째 섹터에 위치 (항상 이런 것은 아님)

 

BSD 파티션에서 디스크 구조 정보를 가지고 있는 디스크 레이블의 구조는 다음 표와 같다.

범위(Byte)

설명

범위Byte)

설명

0 ~ 3

시그니처(0x82564557)

112 ~ 131

예약 영역

4 ~ 5

드라이브 타입

132 ~ 137

체크섬

6 ~ 7

드라이브 하위 타입

138 ~ 139

파티션 번호

8 ~ 23

드라이브 타입 이름

140 ~ 143

부트 영역 크기

24 ~ 39

팩 식별자 이름

144 ~ 147

파일 시스템 부트 슈퍼 블록 최대 크기

40 ~ 43

섹터 크기(Byte)

148 ~ 163

BSD 파티션 1

44 ~ 47

트랙 섹터 개수

164 ~ 179

BSD 파티션 2

48 ~ 51

실린더 트랙 개수

180 ~ 195

BSD 파티션 3

52 ~ 55

유닛 실린더 개수

196 ~ 211

BSD 파티션 4

56 ~ 59

실린더 섹터 개수

212 ~ 227

BSD 파티션 5

60 ~ 63

유닛 섹터 개수

228 ~ 243

BSD 파티션 6

64 ~ 65

트랙 Sparse 섹터 개수

244 ~ 259

BSD 파티션 7

66 ~ 67

실린더 Sparse 섹터 개수

260 ~ 275

BSD 파티션 8

68 ~ 71

유닛 보조 실린거 개수

276 ~ 291

BSD 파티션 9

72 ~ 73

디스크 회전 속도

292 ~ 307

BSD 파티션 10

74 ~ 75

하드웨어 섹터 교대 배치

308 ~ 323

BSD 파티션 11

76 ~ 77

트랙 스큐

324 ~ 339

BSD 파티션 12

78 ~ 79

실린더 스큐

340 ~ 355

BSD 파티션 13

80 ~ 83

헤드 전환 시간(ms)

356 ~ 371

BSD 파티션 14

84 ~ 87

트랙에서 트랙 검색 시간(ms)

372 ~ 387

BSD 파티션 15

88 ~ 91

플래그

388 ~ 403

BSD 파티션 16

92 ~ 111

드라이브 관련 정보

404 ~ 511

사용 X

 

BSD 파티션 레이아웃 오프셋 구조는 다음과 같다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 3

BSD 파티션 섹터 크기

12 ~ 12

파일 시스템 타입

4 ~ 7

BSD 파티션 시작 섹터

13 ~ 13

블록별 파일 시스템 조각 개수

8 ~ 11

파일 시스템 조각 크기

14 ~ 15

그룹별 파일 시스템 실린더 개수

 

파일 시스템 타입은 BSD 파티션이 위치한 파일 시스템의 타입값을 가지며 목록은 다음과 같다.

타입값

설명

타입값

설명

0

비사용 슬록

8

MS-DOS File System(FAT)

1

Swap 공간

9

4.4 BSD Log-Structured File System(4.4 LFS)

2

Version 6

10

사용 중이지만 알려지지 않았으며, 지원되지 않음

3

Version 7

11

OS/2 HPFS

4

System V

12

CD-ROM(ISO9660)

5

4.1 BSD

13

Bootstrap

6

8번째 출시

14

Vinum 드라이브

7

4.2 BSD Fast File Systems(FFS)

   

 

FreeBSD와 OpenBSD 파일 시스템은 4.2BSD FFS(타입값:7)이며, 적어도 해당 시스템에서 Swap 파티션은 하나 이상 있어야 한다.

 

 

2-6. 솔라리스 파티션

  • 솔라리스 운영체제는 대용량 서버와 데스크탑용으로 나누어져 있지만 대부분 대용량 서버에서 많이 사용하는 운영체제

  • 그렇기 때문에 침해사고 조사 시 솔라리스 운영체제를 많이 볼 수 있어 파티션에 대한 이해 필요

  • 솔라리스 모든 버전들은 BSD 디스크 레이블과 비슷한 구조 사용

  • Sparc 솔라리스와 i386 솔라리스로 나뉘며, 두 종류의 파티션 데이터 구조 역시 다름

 

솔라리스에서는 각 파티션을 지칭하는 용어로 '슬라이스'를 사용한다.

 

솔라리스 설치 시에 디스크에 디스크 레이블을 솔라리스가 생성하게 되며, 정확히 설치되는 위치는 하드웨어 플랫폼에 따라 다르며, 생성되는 디스크 레이블에는 파티션 최대 개수 정보가 들어 있다.

 

디스크 레이블은 Sparc 시스템의 경우 최대 개수 8개, i386 시스템의 경우 16개이며, 각 파티션은 다음과 같은 항목들을 가진다.

 

  • 파티션 시작 위치

  • 파티션 크기

  • 플래그 세트

  • 플래그 세트 크기

  • 파티션 타입

 

플래그의 경우 파티션이 읽기 전용인지 스왑(Swap) 공간처럼 마운트가 불가능한지 판단하게 해 주는 항목이다.

 

파티션 타입 항목은 다른 시스템 파티션과 다르게 파티션 파일 시스템 타입을 설명하는 항목이 아닌 파티션 마운트 지점을 설명하는 항목이다.

 

솔라리스 파티션의 경우 이름 할당 방법이 다른 시스템 파티션들과는 조금 다르다.

 

 

다음과 같은 규칙을 적용하여 이름을 할당한다.

 

[그림 7] 솔라리스 시스템 별 파티션 이름 할당 규칙

 

 

Sparc 시스템

  • Sparc 시스템 디스크 레이블 구조체는 디스크 1번째 섹터에 생성

  • 2번째 섹터부터 16번째 섹터까지는 부트 코드가 위치하는 부트 블록

  • 부트 블록 바로 다음 섹터부터는 파일 시스템 등을 저장하는 파티션 영역

다음은 기본적인 Sparc 시스템의 디스크 레이아웃이다.

 

 

[그림 8] sparc 시스템 디스크 레이아웃

 

Sparc 디스크 레이블은 파티션 모든 정보를 직접적으로 담고 있지는 않으며 두 개의 구조체에 파티션 정보를 나누어 저장한다.

 

sparc VTOC(Volume Table Of Contents)라는 구조체와 파티션 디스크 맵이라는 구조체로 나뉘어 저장된다.

 

먼저 디스크 테이블의 항목들로부터 살펴 보면 다음 표와 같다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 127

ASCII 테이블

438 ~ 439

트랙 섹터 개수

128 ~ 261

Sparc VTOC

440 ~ 443

예약 영역

262 ~ 263

Sectors to skip, Writing

444 ~ 451

파티션 1 디스크 맵

264 ~ 265

Sectors to skip, Writing

452 ~ 459

파티션 2 디스크 맵

266 ~ 419

예약 영역

460 ~ 467

파티션 3 디스크 맵

420 ~ 421

디스크 스피드

468 ~ 475

파티션 4 디스크 맵

422 ~ 423

물리적 실린더 개수

476 ~ 483

파티션 5 디스크 맵

424 ~ 425

실린더별 대체 개수

484 ~ 491

파티션 6 디스크 맵

426 ~ 429

예약 영역

492 ~ 499

파티션 7 디스크 맵

430 ~ 431

인터리브

500 ~ 507

파티션 8 디스크 맵

432 ~ 433

데이터 실린더 개수

508 ~ 509

시그니처 (0xDABE)

434 ~ 437

헤드 개수

510 ~ 511

체크섬

 

파티션 정보를 저장하는 VTOC 구조체는 다음 표와 같다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 3

버전(0x01)

40 ~ 41

파티션 7 플래그

4 ~ 11

볼륨 이름

42 ~ 43

파티션 8 타입

12 ~ 13

파티션 개수

44 ~ 45

파티션 8 플래그

14 ~ 15

파티션 1 타입

46 ~ 47

부트 정보

16 ~ 17

파티션 1 플래그

58 ~ 59

예약 영역

18 ~ 19

파티션 2 타입

60 ~ 63

시그니처(0x600DDEEE)

20 ~ 21

파티션 2 플래그

64 ~ 101

예약 영역

22 ~ 23

파티션 3 타입

102 ~ 105

파티션 1 타임스탬프

24 ~ 25

파티션 3 플래그

106 ~ 109

파티션 2 타임스탬프

26 ~ 27

파티션 4 타입

110 ~ 113

파티션 3 타임스탬프

28 ~ 29

파티션 4 플래그

114 ~ 117

파티션 4 타임스탬프

30 ~ 31

파티션 5 타입

118 ~ 121

파티션 5 타임스탬프

32 ~ 33

파티션 5 플래그

122 ~ 125

파티션 6 타임스탬프

34 ~ 35

파티션 6 타입

126 ~ 129

파티션 7 타임스탬프

36 ~ 37

파티션 6 플래그

130 ~ 133

파티션 8 타임스탬프

38 ~ 39

파티션 7 타입

   

 

뭔가 많아 보이지만, 결국 담고 있는 정보는 파티션 개수와 파티션 타입, 플래그, 부트 정보, 시그니처, 파티션 타임스탬프이다.

 

파티션 타입에는 다음과 같은 값들이 저장된다.

설명

설명

0

비할당

6

/stand 파티션

1

/boot 파티션

7

/var 파티션

2

/파티션

8

/home 파티션

3

Swap

9

대체 섹터 파티션

4

/usr

10

Cahcefs 파티션

5

전체 디스크

   

 

또 파티션 플래그 값에는 두 가지 값이 있는데 값과 설명은 다음과 같다.

  • 1 : 파티션이 마운트 되지 않음을 뜻함

  • 128 : 읽기 전용 파티션을 뜻함

 

이번에는 디스크 맵 구조체 구조이다.

범위((Byte)

설명

0 ~ 3

시작 실린더

4 ~ 7

크기

 

위와 같이 디스크 맵 구조체는 간단한 구조이다.

 

하지만 위 구조로 봐서는 시작 위치를 정확히 알 수 없기 때문에 섹터로 변환하는 작업이 필요하다.

 

실린더 주소는 디스크 내 각 플래터 주소 트랙들의 집합이다.

 

실린더를 섹터로 변환하는 계산식은 다음과 같다.

 

트랙 당 섹터 수 x 헤드 수 x 실린더 = 실린더 당 섹터 수

 

트랙당 섹터 수(438 ~ 439)와 헤드 개수(434 ~ 437)는 VTOC 구조체와 디스크 맵을 포함하고 있는 디스크 레이블에서 확인할 수 있다.

 

 

i386 시스템

  • 해당 시스템을 디스크으 셀치할 때는 하나 이상 도스 파티션이 생성되어야 함

  • 일반적으로 도스 파티션 타입 부트 파티션 1개와, 파일 시스템을 사용하는 도스 파티션 타입의 파티션이 생성되어야 함

  • 부트 파티션은 당연히 시스템 시작에 필요한 부트 코드를 포함하고 있어야 함

 

해당 시스템 디스크 레이블은 도스 파티션 타입 파일 시스템 2번째 섹터에 위치하며, 디스크 레이블이 위치한 파티션의 i386 파티션들을 설명한다.

 

i386 파티션은 반드시 도스 파티션 시작 이후에 시작해야 하며, i386 시스템은 리틀 엔디안 방식을 사용한다.

 

i386 시스템의 디스크 레이블은 512바이트 크기이며, 모든 파티션 정보가 Sparc 시스템과 달리 디스크 레이블 한 곳에 모여있고 CHS 주소를 사용하여 정보를 저장한다.

 

다음은 i386 시스템의 디스크 레이블 구조체의 구조이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 11

부트 정보

156 ~ 167

파티션 8

12 ~ 15

시그니처(0x600DDEEE)

168 ~ 179

파티션 9

16 ~ 19

버전

180 ~ 191

파티션 10

20 ~ 27

볼륨 이름

192 ~ 203

파티션 11

28 ~ 29

섹터 크기

204 ~ 215

파티션 12

30 ~ 31

파티션 개수

216 ~ 227

파티션 13

32 ~ 71

예약 영역

228 ~ 239

파티션 14

72 ~ 83

파티션 1

240 ~ 251

파티션 15

84 ~ 95

파티션 2

252 ~ 263

파티션 16

96 ~ 107

파티션 3

264 ~ 327

타임스탬프 (사용 x)

108 ~ 119

파티션 4

328 ~ 455

볼륨 레이블

120 ~ 131

파티션 5

456 ~ 507

하드웨어 세부사항

132 ~ 143

파티션 6

508 ~ 509

시그니처(0xDABE)

144 ~ 155

파티션 7

510 ~ 511

체크섬

 

[그림 9] i386 시스템 기본 디스크 구조

 

위 표를 보면 디스크 레이블에는 16개의 파티션 엔트리가 있는데 이 파티션 엔트리들의 구조는 다음 표와 같다.

범위(Byte)

설명

0 ~ 1

파티션 타입

2 ~ 3

플래그

4 ~ 7

시작 섹터

8 ~ 11

섹터 크기

 

i386 시스템에서의 파티션 타입과 플래그의 값들은 Sparc 시스템과 동일하다.

 

i386 시스템의 파티션을 확인하기 위해서는 디스크 레이블의 VTOC 부분을 참고해야 하며 해당 파티션 레이아웃은 파티션 엔트리를 참고하면 된다.

 

 

GPT 파티션

  • 대부분 고성능 서버에서 쓰임

  • IA64 시스템들은 IA32 시스템처럼 BIOS가 있지 않아 EFI(Extensible Firmware Interface) 시스템을 사용

 

GPT 파티션을 사용하는 디스크 기본 구조는 다음과 같다.

 

[그림 10] GPT 디스크 기본 구조

 

1)보호용 MBR

  • 하나의 엔트리 만을 가진 파티션 테이블을 포함한 도스 파티션이 위치해 있으며 해당 엔트리는 EFI GPT 디스크를 위한 것

  • 해당 파티션은 과거 컴퓨터 디스크를 재구성하기 위해 존재

 

2) GPT 헤더

  • 위 그림처럼 두 번째 섹터에 위치

  • GPT 디스크가 생성될 때 고정된 파티션 테이블 위치와 크기를 정의하는 항목 등이 포함

 

3) 파티션 테이블

  • 여러 개의 엔트리가 있으며 해당 엔트리들은 파티션 영역의 파티션들의 타입 등을 정의하는 항목들을 포함

  • 윈도우의 경우 GPT 헤더 다음 위치하는 파티션 테이블에 포함되는 엔트리 갯수를 128개로 제한함

 

4) 파티션 영역

  • GPT 디스크 중에서 가장 큰 공간이며, 파티션 할당에 필요한 섹터들을 포함

  • 파티션과 파티션 영역을 혼동하여서는 안 됨

  • 이 영역은 GPT 헤더에 의해 정의

 

5) 백업 영역

  • 해당 영역은 파티션에 문제가 발생하였을 경우를 대비하여 GPT 헤더와 파티션 테이블을 복사한 복사본이 존재

 

GPT 헤더의 오프셋 구조는 다음과 같다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 7

시그니처(EFI PART)

48 ~ 55

파티션 영역 마지막 LBA

8 ~ 11

버전

56 ~ 71

디스크 GUID

12 ~ 15

GPT 헤더 크기(Byte)

72 ~ 79

파티션 테이블 시작 LBA

16 ~ 19

GPT 헤더 체크섬(CRC32)

80 ~ 83

파티션 테이블 엔트리 개수

20 ~ 23

예약 영역

84 ~ 87

파티션 테이블 각 엔트리 크기

24 ~ 31

현재 GPT 헤더의 LBA

88 ~ 91

파티션 테이블 체크섬(CRC32)

32 ~ 39

다른 GPT 헤더의 LBA

92 ~ 섹터 끝

예약 영역

40 ~ 47

파티션 영역 시작 LBA

   

 

GPT 파티션은 위 표의 오프셋 구조들을 이용하여 디스크 전체 레이아웃을 정의한다.

 

다음 표는 GPT 헤더에서 정의한 파티션 테이블의 각 엔트리들이 오프셋 구조이다.

범위(Byte)

설명

범위(Byte)

설명

0 ~ 15

파티샨 타입 GUID

40 ~ 47

파티션 LBA 마지막

16 ~ 31

고유 파티션 GUID

48 ~ 55

파티션 속성

32 ~ 39

파티션 LBA 시작

56 ~ 127

파티션 이름 (유니코드)

 

GUID는 128bit로 파티션 내용을 구분하는 데 사용된다.

 

인텔과 MS에서 정의한 GUID 값이 있는데 그 값들은 다음 표와 같다.

GUID

설명

00000000-0000-0000-000000000000

비할당된 엔트리

C12A7328-F81F-11D2-BA4B-00A0C93EC93B

EFI 시스템 파티션

024DEE41-33E7-11D3-9D69-0008C781F39F

도스 파티션 테이블 내부에 있는 파티션

 

GUID

설명

E3C9E316-0B5C-817D-F92DF00215AE

마이크로소프트 예약 파티션(MRP)

EBD0A0A2-B9E5-4433-87C0-68B6B72699C7

주 파티션(기본 디스크)

5808C8AA-7E8F-42E0-85D2-E1E90434CFB3

LDM 메타데이터 파티션(동적 디스크)

AF9B60A0-1431-4F62-BC68-3311714A69AD

LDM 데이터 파티션(동적 디스크)

 

위 표가 인텔에서 정의한 GUID이고, 아래 표가 MS에서 정의한 GUID이다.

 

MS에서 정의한 파티션 중 예약 파티션은 임시 파일을 보관하기 위한 파티션이고 주 파티션은 우리가 알고 있는 하나의 파일 시스템을 사용하는 파티션이다.

 

해당 파티션을 지원한느 분석 도구는 아직까지 많지 않다.

 

하만 앞으로 64bit 시스템이 주를 이루어 사용하는 날이 얼마 남지 않아 해당 시스템에 대한 분석 도구의 지원이 절실할 때이다.

 

해당 시스템을 가지는 디스크를 분석할 때에는 다른 파티션들과 같이 비할당 영역의 데이터를 찾아 반드시 분석해야 한다.


# Reference 

 

http://www.yes24.com/Product/Goods/8511539

[Digital Forensic] 하드디스크와 데이터 수집

 

하드디스크와 데이터 수집


(1) 하드 디스크 구조

 

비휘발성의 보조 기억 장치라고 설명할 수 있는 하드 디스크의 일반적 구조는 다음과 같다.

 

1-1. Platter (플래터)

  • 위 그림에 원판으로 된 부분이며, 데이터가 기록되는 부분

  • 금속 재질로, 데이터를 기록하기 위해 산화철 등의 자성체로 양면 코딩

  • 하드 디스크에는 한 개 또는 그 이상의 플래터들이 부착 가능

  • 많이 부착되면 될수록 용량은 커지지만 안정성에 대한 문제 증가

 

1-2. Spindle (스핀들)

  • 플래터의 회전을 담당하는 부분

  • 초기에는 볼 베어링이 사용되었지만, 최근에는 동압 유체 베어링이 많이 사용

  • 동압 유체 베어링은 완전한 원형 회전을 하게 하여 트랙 밀도를 높임

 

1-3. Actuator (액추에이터)

  • Actuator Head가 데이터를 읽을 수 있도록 Actuator Arm을 움직이도록 하는 부분

  • 구동을 위해 네오디뮴 자석을 사용하고, 누설 자속을 줄이기 위해 스테핑 모터를 사용 > 데이터 손실로 인해 헤드 파킹이 필요

  • 요즘은 음성 코일 방식을 사용 > 전원이 차단되어도 스핀들 모터의 관성에 의해 헤드가 제자리로 돌아가 헤드파킹이 필요 없어짐

 

1-4. Head (헤드)

  • 데이터를 읽고 쓰는 부분으로 플래터와의 간격이 마이크로미터 단위로 떨어져 데이터를 읽고 씀

  • 만약 플래터와 맞부딪힌 상태에서 스핀들 모터가 구동되어 헤드가 플래터에 닿는 경우 데이터 손상

  • 헤더 기록 방식에는 수직 기록 방식과 수평 기록 방식이 있음

 

수직 기록 방식 : 데이터를 수직으로 기록하여 수평 기록 방식에 비해 플래터 당 기록 밀도를 훨씬 높일 수 있고, 자성의 손실이 거의 없어 데이터 수명 또한 긺

 

수평 기록 방식 : 데이터를 수평으로 기록하여 자기장을 입히는 기록 도체를 수평으로 눕혀놓고 그 기록 도체에 자기장을 입혀 데이터를 기록하는 방식


(2) 하드 디스크 저장 방식

 

[그림 1] 플래터 구조

 

2-1. CHS 방식

  • 실린더(Cylinder), 헤드(Head), 섹터(Sector) 세 가지 요소를 이용한 방식

  • 물리적 주소 할당 방식

  • 실린더, 헤드, 섹터에 번호를 할당해 그 주소를 이용해 데이터를 찾아 읽고 쓰는 방식

  • 과거에 사용되었으며 용량이 커지는 현대 하드 디스크에 맞지 않는 한계를 보임

  • 요즘에는 쓰이지 않으며, CHS가 지원하는 용량의 임베디드(embeded) 하드 디스크들은 아직 이 방식 사용

 

2-2. LBA 방식

  • CHS 한계로 인해 고안된 방식

  • 모든 섹터에 논리적 고유 번호를 할당하는 방식

 

2-3. ZBR (Zone Bit Recording)

  • 요즘 사용하는 방식으로, 외부 트랙 길이가 내부 트랙 길이보다 길다는 점에서 착안하여 길이가 긴 트랙일수록 섹터를 많이 할당하도록 만드는 방식

  • CHS와 LBA 경우에는 트랙의 섹터 수가 모두 동일

  • ZBR은 트랙 길이마다 섹터 수가 다르기 때문에 데이터를 읽고 쓸 때 트랙에 섹터 수를 정확히 알고 있어야 함


(3) 하드 디스크 숨김 영역

  • 사용자 임의적 설정을 통해 숨김 영역을 설정할 수 있고 하드 디스크 제조 공정에서 숨김 영역이 생성 되어 설정 된 상태로 판매 되어 일반 사용자가 사용할 수도 있음

  • 악성코드나 하드 디스크에 대한 지식이 있는 사용자는 숨김 영역에 중요 데이터를 숨길 수 있음

  • 분석 대상 시스템에서 조사관이 흔적을 찾을 때 분석 영역 중 고려해야 하는 영역 중 하나

  • 하드 디스크 덤프 파일을 획득할 시에 하드 디스크 덤프 도구가 숨김 영역까지 덤프하는지 알아보고 사용해야 함

  • 숨김 영역을 덤프하지 못한다면 중요 데이터를 놓칠 수 있기 때문

 

3-1. HPA (Host Protected Area)

  • 데이터를 저장할 수 있는 영역이지만, 일반 사용자가 볼 수 없는 영역

  • 숨겨진 영역이며, 설정은 ATA 명령으로 가능

  • ATA-4에서 추가되었으며, 사용자가 하드 디스크를 포맷하거나 삭제했을 때도 데이터를 보존할 수 있는 영역

  • 하드 디스크 끝에 위치하며, 하드 디스크 재설정에 의해서만 접근 가능

 

HPA는 다음과 같은 두 명령어 결과값 차이를 보고 존재 유무 파악이 가능하다.

 

1) READ_NATIVE_MAX_ADDRESS

  • 물리적 주소 최대값을 반환하여 주는 명령어 (항상 이런 결과는 아님)

 

2) IDENTIFY_DEVICE

  • 사용자 영역(HPA 영역 앞 부분) 끝을 반환하여 주는 명령어

 

[그림 2] HPA 생성, 삭제 도식화

 

HPA 영역 설정은 SET_MAX_ADDRESS 명령어를 통해 이루어지며, 이 명령어 기능은 사용자가 접근할 수 있는 최대 주소를 설정한다.

 

HPA 영역 제거는 READ_NATIVE_MAC_ADDRESS 결과를 SET_MAC_ADDRESS 입력 값으로 이용하면 된다.

 

HPA 제거할 때에는 완전 제거와 임시 제거가 있으며, 완전 제거는 말 그대로 완전 제거되는 것이고, 임시 제거는 SET_MAC_ADDRESS 명령어 설정을 휘발성 비트 설정으로 하여 하드 디스크가 재설정되거나 전원이 재공급된 이후에 HPA 영역이 다시 복구되게끔 한다.

 

 

3-2. DCO (Device Configuration Overlay)

  • ATA-6에서 추가된 기능이며 HPA와 동일한 기능을 하는 영역

  • 컴퓨터에서 어떠한 기능을 제공하는지 IDENTIFY_DEVICE 명령어를 통해 확인하는데 DCO 기능은 자신의 기능을 IDENTIFY_DEVICE 명령어 결과값에 추가하지 않아 기능이 존재하지 않는 것처럼 보임

  • 지원 기능 목록 말고도 디스크 크기도 보여주는데 여기서 DCO 영역이 제외된 크기가 보여짐

  • HPA 영역도 있을 시에 HPA 영역도 제외

 

명령어 중에 DEVICE_CONFIGURATION_IDENTIFY 명령어의 기능은 디스크 크기와 실제 명령어 목록을 반환하여 준다. 

 

위 명령어와 IDENTIFY_DEVICE 명령어를 비교하여 DCO 탐지가 가능하다.

 

또 READ_NATIVE_MAX_ADDRESS 결과와 DEVICE_CONFIGURATION_IDENTIFY 결과를 비교하여 DCO 영역을 찾아 낼 수 있다.

 

DCO 영역 생성은 DEVICE_CONFIGURATION_SET 명령어로 하며, 삭제는 DEVICE_CONFIGURATION_RESET 명령어로 할 수 있다.

 

만약 HPA 영역까지 존재한다면 디스크 논리적 구조와 각 명령어들이 출력하는 결과물들이 있는 곳은 다음과 같다.

 

[그림 3] DCO 설정 도식화

 

포렌식 관점에서 보았을 때 이런 영역들은 상당히 성가시다.

 

혹여 유효 데이터가 해당 영역에 위치하고 있는데 해당 영역까지 디스크를 복사하지 않거나 분석하지 않으면 그 유효한 데이터를 얻지 못할 수도 있기 때문이다.

 

그래서 대부분 디스크 복제 도구나 장비들은 해당 영역이 있는지 파악한 후에 영역이 존재하면 해당 영역까지 복제를 시도한다.


(4) 데이터 수집

  • 하드 디스크에서 데이터를 분석하기 위한 단계 중 이 데이터 수집 단계가 필수적

 

4-1. 컨트롤러의 직접 접근

  • 하드 디스크 컨트롤러는 하드 디스크와 연결되어 있고 리본 케이블로 하드 디스크에 명령을 내림

  • 소프트웨어는 하드 디스크 컨트롤러를 통해 디스크 데이터에 접근할 수 있으며, 이때 소프트웨어는 하드 디스크 컨트롤러의 주소 지정, 데이터를 읽고 쓰기 위한 명령어 등 세부적 사항을 모두 알고 있어야 함

  • 속도면에서는 좋지만 소프트웨어 개발 시 부담이 많이 가는 접근법

 

4-2. 컨트롤러의 BIOS 접근

  • BIOS를 통해 디스크 데이터에 접근하게 되면 컨트롤러 직접 접근법에서 알아야 했던 하드 디스크의 모든 세부 사항을 소프트웨어가 인식하고 있지 않아도 됨

  • 소프트웨어는 BIOS 하드 디스크 서비스들을 사용하기 위해 섹터 주소와 섹터 크기 같은 데이터를 CPU 레지스터 내부로 적재하고, 소프트웨어 인터럽트 명령어 0x13(INT13h)을 실행하면 됨

INT13h : 데이터를 읽고 쓰고 하기 위한 질의들을 포함하는 명령어

 

 

원래 INT13h의 경우 CHS 방식에서 사용하던 명령어여서 8.1GB까지만 읽고 쓸 수 있어 LBA 방식에는 맞지 않아 '확장 INT13h'라는 것이 새로 추가되었다.

 

지금까지의 설명을 보면 소프트웨어 입장에서 BIOS를 통한 접근법이 좋아 보이지만, 조사관 입장에서는 시스템과 도구에 따라 다르게 보일 수 있다. 

 

이유는 다음과 같다.

 

접근법의 차이

  • 결론부터 말하면 BIOS 접근법은 시스템과 도구에 따라 정확한 결과를 얻지 못할 수 있다.

 

BIOS에서 확장 INT13h를 사용하지 않고 기존 CHS 방식 INT13h를 사용한다면 위와 같은 현상이 발생한다.

 

소프트웨어가 BIOS를 통해 디스크 크기가 몇이냐고 명령을 내렸다면 대상은 10GB 디스크일 때 INT13h를 사용하는 BIOS일 경우 8.1GB로 인식하기 때문에 결과값을 8.1GB로 돌려줄 것이다.

 

만약 이 명령이 모든 디스크 데이터를 복사하라는 명령이었다면 10GB에서 8.1GB 크기 데이터만 복사해 올 것이다.

 

이렇게 되면 2GB 데이터를 수집하지 못하는 것이다.

 

직접 접근법의 경우 BIOS 상관 없이 LBA 형식 확장 INT13h를 사용해 디스크 크기를 정확하게 알아낼 수 있다.

 

[그림 4] BIOS 접근법과 직접 접근법

 

위 그림과 같은 문제로 자신이 사용하는 도구가 어떤 접근법을 가지고 데이터를 수집하는지 파악해 놓고 있어야 하며, 만약 BIOS를 사용한다면 어떤 INT13h 명령어를 사용하는지 알아야 한다.

 

 

4-3. 동적 수집

  • 분석 대상 시스템 운영체제가 동작한는 상태에서 데이터를 수집하는 것

  • 이 방법은 매우 신뢰성이 떨어짐

  • 악의적인 공격자나 루트킷 등에 의해 운영체제가 변조되었을 가능성이 있기 때문에 변조된 운영체제를 통해 수집된 데이터 또한 엉뚱한 데이터나 증거가 남아 있지 않을 수도 있기 때문 

 

4-4. 정적 수집

  • 이동 장치로 부팅하여 분석 대상 시스템의 데이터를 수집하는 것을 말함

  • 즉, 분석 대상 시스템 운영체제 도움 없이 시스템 데이터를 수집하는 것

  • 신뢰성이 높은 이동 저장장치를 이용하여 부팅한 후 대상 시스템에서 데이터를 수집함

  • 악의적인 공격자나 루트킷 등이 하드웨어를 변조했을 가능성도 있지만 운영체제 변조 가능성보다는 낮음

 

분석 대상 시스템의 디스크 섹터 중 불량 섹터가 존재하여 도구가 불량 섹터를 읽는 도중 오류가 발생하면 데이터 수집에 차질이 생길 수 있다.

 

모든 수집 도구는 이러한 상황을 대처할 줄 알아야 하며 일반적 방법으로는 불량 섹터를 0으로 덮어 버리는 것이다.

 

이렇게 함으로써 오류 발생 요인 제거와 불량 섹터 위치를 정확하게 판별할 수 있게 된다.

 

[그림 5] 오류 처리

 

데이터 수집 시에는 유의 사항이 있으며, 바로 HPA 영역과 DCO 영역이다.

 

이 부분들을 탐지하지 못한다면 중요한 데이터를 얻지 못할 수도 있다.

 

그래서 HPA영역을 탐지하는데 도움을 주는 도구들이 존재하며, HPA 영역을 탐지할 수 있는 수집 도구는 다음과 같다.

  • BXDR

  • diskstat

  • DRIVEID

  • hpa

 

DCO 영역을 탐지하는 도구로는 Image MASSter Solo 2가 있다.

 

데이터 수집 시에 저장하는 영역은 디스크와 파일로 나뉠 수 있다.

 

하지만 디스크에 저장하는 방식에 문제점이 있어 요즘은 대부분 CD-ROM이나 이동 저장장치에 분석 대상 디스크를 파일로 저장한다.


(4) 데이터 쓰기 방지 장치

  • 무결성은 증거 투명성을 보장하는 것으로 데이터 수집 시에 중요하게 여겨야 할 부분 중 하나

  • 만약 디스크 데이터를 수집하거나 복제할 때 그 과정에서 원본 내용이 변경되면 무결성은 보장 받지 못함

  • 그렇기 때문에 디지털 데이터를 수집할 때에는 쓰기 방지 장치라는 것을 사용함

  • 디스크 데이터를 수집하거나 복제하는 데 사용하는 장비나 도구가 원본 디스크 데이터에 접근해 어떤 행위를 하던 도중 오류나 다른 원인으로 인해 원본 데이터를 손상시키는 일을 방지하기 위해 사용하는 장치

 

쓰기 방지 장치에는 하드웨어/소프트웨어 종류가 있으며, 이 두 종류 모두 원본 디스크 데이터와 디스크 데이터에 접근하는 장치 사이에 위치하여 입/출력을 제어한다.

 

하드웨어 쓰기 방지 장치의 경우는 [그림 5]에서 수집 도구와 디스크 사이에 쓰기 방지 장치가 위치한다고 생각하면 된다. (BIOS는 X)

 

하드웨어 쓰기 방지 장치는 대부분 연결 포트 인터페이스(SATA, IDE, Firewire, USB 등)를 지원하고, 장치 연결 후 동작 하기 전 먼저 숨김 영역인 HPA나 DCO를 제거하기 위해 제거에 관한 명령어들을 원본 디스크 데이터쪽으로 전송한다.

 

이러한 이유로 주로 소프트웨어 쓰기 방지 장치보다는 하드웨어 쓰기 방지 장치를 사용한다.

 

또 소프트웨어 쓰기 방지 장치는 [그림 5]에서 수집 도구와 BIOS 사이에 위치하여 BIOS 인터럽트 테이블에 INT13h 엔트리의 주소를 쓰기 방지 장치 주소로 수정해 운영체제에서 INT13h를 호출했을 때 쓰기 방지 장치가 호출되게 끔하여 작동한다.

 

대표적 쓰기 방지 장치는 다음과 같다.

 

1) 하드웨어 쓰기 방지 장치

  • ICS Drive Lock

  • Tableau Write Blockers 

  • Wiebe Tech Write Blockers

 

2) 소프트웨어 쓰기 방지 장치

  • SAFE Block XP

  • MacForensicLab Write Controller


# Reference

 

http://www.yes24.com/Product/Goods/8511539

+ Recent posts