Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

Piki's Play

Chapter 14. Ext 2, Ext 3 개념과 분석 본문

포렌식/파일시스템 (파일시스템 포렌식분석)

Chapter 14. Ext 2, Ext 3 개념과 분석

Pikigod 2020. 3. 18. 18:13

- 많은 리눅스 운영체제 배포판은 기본 파일시스템으로 Ext2와 Ext3 파일시스템을 사용한다. Ext3는 기존의 Ext2에서 저널링 기능을 더했지만, 거의 모든 Ext2 구성은 그대로 남아있다. ExtX는 UFS(UNIX File System)를 기초로해서 만들었고, UFS의 쓸모없는 기능들을 제거하여 이해하고 분석하기 쉬워졌다. 다른 운영체제와 달리 리눅스는 많은 파일시스템을 지원하고, 각 배포판은 기본으로 사용할 파일시스템을 선택할 수 있다. 

- Ext3 파일시스템이 리눅스 기본 파일 시스템이지만, ExtX와 전혀 다른 구조를 가진 Reiser와 같은 파일시스템들을 사용하기도 한다. 이번 장에서는 ExtX가 어떻게 동작하는지 살펴보고 15장에서 데이터 구조체에 대해 다루도록 하겠다.

 

 

14.1 소개

- ExtX는 빠르고 안정적인 UFS 설계를 기초로 만들어졌다. 이 파일시스템은 중요한 데이터 구조체들의 복사본을 파일시스템을 통해 저장하고, 파일과 관련이있는 모든 데이터들을 한곳에 집중시켜 하드디스크 헤더가 데이터들을 읽을 때 너무많은 동작을 하지 않도록 하였다.

- 파일시스템 레이아웃은 선택적인 예약된 영역에서 시작되고, 나머지는 블록 그룹이라는 구역으로 나뉜다. 모든 블록 그룹들은 마지막을 제외하고는 같은 블록 수를 포함하고, 블록은 파일이름, 메타데이터, 파일내용을 저장하는데 사용된다. 블록 그룹은 앞서 설명한 영화관의 좌석이랑 비슷하다. 구역으로 나누고, 각 구역은 같은 수의 좌석을 갖는다.

- 파일시스템 시작부분에 있는 슈퍼 블록 데이터 구조체는 ExtX의 기본적인 레이아웃 정보를 저장한다. 파일내용을 연속적인 섹터 그룹인 '블록'에 저장한다. 각 파일과 디렉토리의 메타데이터를 inode라는 데이터 구조체에 저장하며, 그것은 고정된 크기를 갖고 inode 테이블에 위치한다. 각 블록 그룹에는 한 개의 inode 테이블이 있다. 파일의 부모 디렉토리 블록에 위치한 디렉토리 엔트리 구조체는 파일이름을 저장한다. 디렉토리 엔트리 구조체는 파일 이름과 파일 inode 엔트리 포인터를 포함하는 간단한 구조체이다. 

 

디렉토리 엔트리, inode, 블록들의 관계는 아래에서 확인하자.

<ExtX 디렉토리엔트리, inode, 데이터 블록의 관계>

 

- ExtX에는 3가지 범주로 구성된 선택적인 기능들이 있는데 운영체제가 지원하지 않는 파일시스템을 마주했을 때 동작하는 개념이다.

 

⊙ 첫 번째 호환기능(Compatible Features)은 OS가 이러한 기능들을 지원하지 않아도 파일시스템을 여전히 마운트 할 수 있다. 이 예로는 할당방법, 파일시스템, 저널존재, 확장된 속성이 있다.

⊙ 두 번째 비호환(Incompatible Features)이며, 운영체제가 이러한 기능들 중 하나를 마주하면 파일시스템을 마운트하지 않는다. 예로는 압축이있다.

⊙ 마지막으로 읽기전용 호환기능(Read Only Compatible Features)이다. 운영체제가 지원하지 않는 기능 중 하나를 마주했을 때 파일시스템은 오직 읽기 전용으로 마운트되어야 한다. 이러한 예로는 대용량 파일지원과 정렬되지 않은 목록 대신 디렉토리를 정렬하는 B-Trees를 사용하는 것이 있다. 

 

- ExtX에는 리눅스 주 배포판에서 아직 구현되지 않은 많은 실험적 요소들과 기능들이 있다. 따라서 다양한 기능을 사용하는 시스템이 있을 수 있고 아닐 수 있다. 

- 커널에 어떤 변경들이 있었는지를 조사하는 것은 응용프로그램 분석영역이므로, 이 책의 범위를 벗어난다.

- 이 장의 나머지는 Ext2 및 Ext3과 관련이 있는 5가지 범주 데이터 모델을 조사한다. 각 절은 범주의 기본 속성들을 기술하고 ExtX의 세부사항들을 설명한다. 기능들은 항상 변경되었고 이 글을 읽는 시점에는 이미 사용하지 않을 수 있다.

 

 


14.2 파일 시스템 범주

-> 파일시스템 범주는 파일시스템의 일반적인 데이터가 어디에 위치하는지 나타낸다. 이 절에서는 데이터의 이 범주가 어디에 위치하는지 알아보고, 그 데이터 분석방법을 알아보도록 한다.

 

 

 개요

- ExtX에는 파일시스템 범주의 데이터를 저장하는 2개의 구조체인 슈퍼블록(Super Block), 그룹 기술자(Descriptor)가 있다. 슈퍼블록은 파일시스템 시작부분에 위치하고 기본 크기와 설정정보를 포함한다. 이것은 NTFS, FAT 파일시스템의 부트섹터 데이터 구조체와 유사하다.

- 앞서 언급처럼 파일시스템을 블록 그룹들로 구성하고, 각 그룹에는 자신의 레이아웃을 설명하는 그룹 기술자 데이터 구조체가 있다. 그룹기술자들은 슈퍼블록 다음에 있는 그룹 기술자 테이블에 위치하고, 이 파일시스템은 슈퍼블록과 그룹기술자의 손상을 대비한 복사본을 제공한다.

 

 슈퍼블록

- ExtX 슈퍼블록은 파일시스템 시작으로부터 1024바이트에 위치하고 크기가 1024 바이트이지만 실제로 사용하는 바이트 수는 적다. 이 데이터 구조체는 단지 설정 값들만 포함하고 있으며 부트코드는 포함하지 않는다. 슈퍼블록의 복사본은 보통 각 그룹의 첫 블록에 저장된다.

슈퍼블록에는 각 블록크기, 전체 블록수, 블록 그룹당 블록 개수, 첫 블록 그룹보다 전에 예약된 블록의 수와 같은 기본정보가 있다. 또한 inode 전체 개수와 블록 그룹당 inode 개수를 포함한다. 슈퍼블록의 부가 데이터로는 볼륨이름, 마지막 수정시간, 마지막 마운트 시간, 파일시스템이 마지막으로 마운트된 경로 같은 정보가 있다. 파일시스템이 깨끗한 상태인지, 무결성 검사가 실행될 필요가 있는지 식별하는 값 또한 포함한다. 슈퍼블록은 비사용중인 inode와 볼륨들의 전체 개수에 대한 데이터를 기록한다. 이것들은 새로운 inode와 블록들을 할당할 때 사용된다. 

- 파일시스템 레이아웃을 결정하기 위해서 파일시스템 크기를 계산하는데 필요한 블록크기블록개수를 알아야한다. 이러한 값들이 볼륨 크기보다 작다면 파일시스템에 '볼륨슬랙' 공간이 있을 수 있다. 첫 번째 블록 그룹은 예약된 영역 다음 블록에 위치한다. 

 

※ 아래 그림은 레이아웃을 결정하는데 사용되는 값들을 보여준다. 아래에서 마지막 그룹은 앞에 4개의 블록그룹과 블록 수가 동일하지 않다.

<5개의 블록그룹을 갖는 Ext 레이아웃>

 

- 슈퍼블록은 파일시스템에서 어떤 기능들이 활성화 되어있는지 정의한다. 앞서 설명한 3가지 기능, 호환, 비호환성, 읽기전용을 기억해보자. 각 기능의 세부사항은 각 절에서 언급하는데, 여기서는 'Sparse 슈퍼블록'이라는 읽기 전용 기능에 대해 설명하겠다.

- Sparse 슈퍼블록 기능을 사용할 때 일부 블록 그룹들은 슈퍼블록과 그룹기술자 테이블의 복사본을 포함한다. 어떤 파일 시스템은 그룹 1, 3, 5, 7, 9에 복사본이 존재하고, 다음 복사본은 그룹 25와 27까지 존재하지 않는다. ExtX 파일시스템이 리눅스에 생성될 때 Sparse 슈퍼블록 기능은 기본적으로 활성화 되어있다. 이 기능은 그룹마다 슈퍼블록에 예약된 영역이 있다고 추측하지 말아야 한다는 것을 제외하고는 조사에 영향을 미치지 않는다.

슈퍼블록의 볼륨레이블은 파일시스템을 구분하기위해 사용된다. 예를들어 유닉스에서 파일시스템을 조회하는 기본적인 방법은 /dev/hda5와 같은 장치이름을 사용하는 것이다. 다른 방법은 장치 이름대신 레이블을 참조하도록 하는것이다.

예를 들어 리눅스 /etc/fstab은 마운트할 파일시스템을 목록화하고, 만약 그 볼륨레이블이 rootfs이라면 /dev/hda4 장치를 'LABEL=rootfs'로 참고한다.

- 데이터 구조체의 레이아웃과 슈퍼블록 예제는 다음 장에서 확인하겠다. 파일시스템에서 fsstat을 실행한 결과는 이 절 뒷부분에서 확인할 수 있다. 

 

블록 그룹 기술자 테이블

- 슈퍼블록 다음 블록은 파일시스템의 모든 블록 그룹의 그룹 기술자 데이터 구조체인 그룹 기술자 테이블이다. 테이블 복사본은 Sparse 슈퍼블록 기능이 활성화돼 있지 않다면 각 블록그룹에 존재한다.

- 블록 그룹들을 파일 내용 이외에 슈퍼블록, inode 테이블, inode 비트맵, 블록 비트맵 같은 관리데이터를 포함한다. 그룹 기술자는 데이터를 찾을 수 있는 '위치'를 설명한다. 블록 그룹의 레이아웃은 아래와 같다.

<예제 블록 그룹 레이아웃>

 

- 블록 비트맵은 그룹의 블록할당 상태를 관리하고, 시작 블록주소는 그룹 기술자에서 주어진다, 그것의 바이트 크기는 그룹에 블록 개수를 8로 나눠 계산한다.(?! 왜 8이야) 리눅스가 파일시스템을 생성할 때, 블록의 비트수와 같은 그룹 당 블록 수를 정의한다. 그래서 블록 비트맵은 정확히 한 블록이 요구된다.

- inode 비트맵은 그룹의 inode 할당상태를 관리하고, 시작 블록 주소는 그룹 기술자에서 주어진다. 그것의 바이트 크기는 그룹별 inode수를 8로 나누어 계산할 수 있다. 일반적으로 그룹별 블록들은 inode보다 적지만 사용자는 파일시스템을 생성할 때 이런한 값들을 선택할 수 있다. 마지막으로 inode 테이블의 시작 블록 주소는 그룹 기술자에서 주어지고, 크기는 그룹당 inode 수를 128바이트인 각 inode 크기로 나눠서 계산한다. 

- 또한 그룹 기술자는 비사용 블록들의 수와 블록그룹에 inode수를 포함한다. 슈퍼블록은 비사용 블록의 전체 개수와 모든 그룹들에 inode 개수를 포함한다. 그룹 기술자 데이터 구조체는 15장에서 설명한다.

 

부트코드 

- ExtX 파일시스템이 운영체제에 커널을 포함한다면, 부트코드를 포함한다. 부팅되지 않은 모든 파일시스템들은 부트코드가 없다. 부트코드는 슈퍼블록 이전에 위치하고 크기는 1024바이트이다. 부트코드는 디스크 섹터 0, MBR에 있는 코드로부터 제어가 넘겨진 다음에 실행된다. ExtX 부트코드는 전형적으로 어떤 블록들이 커널에 할당되었는지 알 수 있으며, 이후 커널을 메모리에 적재할 것이다. 

- 많은 리눅스 시스템들은 파일시스템에 부트코드가 있지 않다. 대신 MBR에 부트로더가 있고, 그것은 커널이 어떤 블록에 있는지 알고있다. 이 경우 MBR에 코드는 커널을 적재하고, 파일시스템에 부트코드는 추가적으로 필요하지 않을 것이다.

 

 예제이미지

- TSK fsstat 실행결과를 보자. 다음장에서 수동으로 분석하겠다.

-> 위 결과는 inode, 블록의 총 개수, 블록크기 같은 슈퍼블록에 일반적인 데이터를 보여준다. 또한 각 블록 그룹의 레이아웃 세부사항을 볼 수 있고, 그룹 0에서 이것들을 볼 수 있다. 그룹 0에서 블록과 inode 범위, 비트맵과 inode 테이블 위치를 확인 할 수 있다. 기능 플래그들과 일시적인 정보들 또한 볼 수 있다.

 

 

분석 기술

- 파일시스템 범주의 분석은 파일시스템 레이아웃을 결정하도록 핵심데이터 구조체들을 처리하는 것이다. ExtX에서 첫 단계는 슈퍼블록을 찾는 것이다. 이 위치는 파일시스템 시작에서 1024바이트 오프셋에 항상 위치한다. 슈퍼블록을 찾은 후 바로 그것을 처리한다. 파일시스템의 크기는 블록개수와 블록크기를 사용해서 계산한다.

- 슈퍼블록의 다음 블록에는 그룹기술자 테이블이 있다. 이것을 각 그룹을 위한 엔트리를 포함하고 있으며, 블록과 inode 할당상태를 결정하는 데이터 구조체의 위치를 확인하는데 사용된다. 또한 이것의 복사본들은 슈퍼블록이 있는 각 그룹에서 확인할 수 있다. 슈퍼블록과 그룹기술자를 사용해 파일과 디렉토리들이 사용하는 모든 데이터 구조체 위치를 찾을 수 있다.

 

 

▶ 분석 고려사항

- 이 범주는 파일시스템의 레이아웃을 설명하는 필수 정보를 포함하지만, 사건의 증거가 있는 값들은 포함하지 않는다. 슈퍼블록에는 사용하지 않는 공간이 많고, 이곳에 데이터를 숨길 수 있다. 

16장 "UFS"장을 읽고나면 ExtX 슈퍼블록이 UFS 슈퍼블록보다 훨씬 명료해서 숨겨진 데이터 값들을 더 쉽게 탐지할 수 있다는 것을 알 수 있다. 슈퍼블록 전 1024바이트는 부트코드를 위한 공간이지만 모든 파일시스템에서 필요한 것은 아니므로 숨겨진 데이터가 있을 수 있다. 또한 볼륨과 크기를 비교해서 사용하지 않는 여분의 공간을 알아낼 수 있다.

- 그룹 기술자 테이블은 할당된 데이터를 효율적으로 사용하도록 하는 엔트리를 갖지만 테이블 마지막에 사용하지 않는 공간이 있을 수 있다. 그리고 백업본에도 숨겨진 데이터가 있는지 확인해야 한다. 

- 슈퍼블록을 찾을 수없거나 손상되었다면, 백업본을 찾아야한다. 백업본을 찾는 한가지 방법은 데이터 구조체 56, 57바이트에 있는 시그니처 0xef53 값을 검색하는 것이다. 또 한 블록당 얼마나 많은 비트수가 있는지, 그리고 예상된 블록크기를 이용해서 블록 그룹의 경계를 결정할 수 있다. 블록크기를 8로나누고 1을 더하면 해당 섹터에서 복사본을 확인할 수 있다. 예를들어 파일시스템이 1024바이트 블록크기를 갖는다면 각 블록 그룹은 8192 블록을 갖고, 슈퍼블록 복사본은 블록 8192에 있어야 한다. (말이 좀 어려운데 경계에 복사본이 있는걸로 봐도 되는건가?) 데이터 구조체의 복사본은 원본이 수정되었는지 탐지하는데 사용될 수 있다.

 

 

▶ 분석 시나리오

- 파티션 테이블이 없는 시나리오를 생각해보자. 4장 "볼륨분석"에서 파티션 테이블이 손상되었을 때 qpart 도구를 통해 파일시스템을 찾았었다. 여기에서는 qpart 도구가 수행한 과정과 유사한 분석을 한다.

- 리눅스시스템에서 디스크를 조사시 ExtX 파일 시스템을 조사해야 한다고 생각한다. 하지만 리눅스 시스템들이 같은 디스크에서 여러가지 파일시스템과 파티션을 사용할 수 있다는 것을 기억하자. 첫번째 파일시스템이 작은 경우는 부트코드와 커널만을 사용해야 하기 때문에 흔하지 않다.

- ExtX 슈퍼블록은 바이트 56-57에 0xef53 시그니처를 갖는다. 이 값을 검색해서 파일시스템 시작 위치를 알 수 있다. 시그니처가 잛아서 오탐이 많을 수 있다. 오탐 발생여부를 확인하기 위해 슈퍼블록에 있어야 하는 다른 값들을 점검한다.(ex 블록크기) 실제로 ExtX 슈퍼블록을 찾을 때 각 그룹에는 복사본이 존재하기 때문에 동일한 간격으로 일치하는 검색 결과가 나오는 것을 볼 수 있다. 기본 생성 절차 사용한 블록그룹들은 전형적으로 블록크기에 기반을 둔다. 슈퍼블록 사이의 거리는 8192, 16384 또는 32768이다. 또 Sparse 슈퍼 블록을 사용하더라도, 모든 블록 그룹에 복사본이 존재하지는 않을 수 있다. 

- 16진수 값을 검색할 수 있는 도구를 이용해 시그니처를 검색할 수 있다. grep 같은 도구는 단지 ASCII 값을 지원하기 때문에 이러한 경우는 검색할 수 없다. 예를들어 TSK sigfind를 사용할 수 있다. 헥스 시그니처가 디스크에서는 리틀엔디안 순서로 저장되기 때문에 사용하는 도구에 따라 적절히 설정할 필요가 있고, 시그니처 값을 입력할 때 그 순서를 바꿔야 하는 경우도 있다. 예제 이미지를 대상으로 sigfind 한 결과는 아래에 있다. 

 

# sigfind -o 56 -l ef53 disk - 8.dd

Block Size : 512 Offset : 56

Block : 298661 (-)

Block : 315677(+17016)

Block : 353313(+37636)

Block : 377550(+24237)

-> sigfind 도구는 시그니처가 일치한 섹터와 이전 일치 지점으로부터의 거리를 같이 출력한다. 이 거리는 2의 제곱이 아니고, 일정한 간격이 아니다. 그래서 나중에 이 결과는 분석에 방해가 된다. 그러나 또 이후에 결과에서 흥미로운 데이터를 볼 수 있다.

 

[REMOVED]

Block : 2056322 (+274327)

Block : 2072706 (+16384)

Block : 2105474 (+32768)

Block : 2138242 (+32768)

Block : 2171010 (+32768)

Block : 2203778 (+32768)

-> 마지막 4개 엔트리는 같은 간격을 두고 있다. 이전 일치점부터 16384 섹터 떨어진 엔트리이다. 이 거리는 블록 그룹 사이라고 볼 수 있다. 그래서 초기 가설로 첫 슈퍼블록은 섹터 2056322에 있고 백업본은 섹터 2072706, 2105474에 존재한다고 정의할 수 있다. 거기에는 아마도 블록 당 16384 섹터가 있고, Sparse 슈퍼블록 기능은 사용중이지만 모든 그룹들은 슈퍼블록을 갖지 않는다. 

 

- 이런 가설을 테스트하기 위해 섹터 2056322에서 1024 바이트를 추출한다. 거기에 슈퍼블록 데이터 구조체를 적용해 다양한 값들을 조사한다. 블록크기는 1024바이트이고 Sparse 슈퍼블록은 활성화 되어있다. 파일 시스템에는 총 104422블록과 그룹별 8192블록이 있다. 그래서 슈퍼블록의 복사본은 16384 섹터 떨어져 있다.(블록별 2섹터)

- 마지막 테스트는 섹터 2056322에 슈퍼블록이 파일시스템의 첫 번째 부분인지, 복사본인지 결정하는 것이다. 슈퍼블록은 어떤 블록 그룹의 일부분인지 식별하는 필드를 갖고, 원본의 경우 0 값을 갖는다. 섹터 2072706에 슈퍼블록이 1의 값을 갖는다. 그래서 그 파일시스템은 섹터 2056320에서 섹터 2265164까지라는 것을 예상할 수 있다.(???)

- 복사본은 자주 업데이트 하지 않기 때문에 슈퍼블록이 어떤 블록 그룹에 있는지를 보여주는 값이 두 복사본이 같지 않다.

- 이전 예제는 업데이트가 많지 않은 /boot 파티션이었기 때문에 매우 명료했다. 다음에 일치하는 부분들은 명료하지 않고 일치점은 이전 파일 시스템의 마지막 이후 두 섹터이다.

 

Block : 2265167 (+61389)

Block : 2265733 (+566)

Block : 2265985 (+252)

Block : 2266183 (+198)

Block : 2266357 (+174)

Block : 2266457 (+100)

-> 이전 파티션의 마지막 섹터 2265167 위치를 기초로해서 이것은 새로운 파일시스템의 시작이라고 생각할 수 있다. 한편 그 다음에 일치하는 부분은 복사본이 아니고, 그것들 사이 간격이 20섹터인 엔트리가 200개 이상 있는 것을 볼 수 있다. 그래서 이러한 일치 부분을 무시하고 수백개의 엔트리를 건너뛰어 다음으로 이동하자.

 

[REMOVED]

Block : 2278273 (+2800)

Block : 2281551 (+3278)

Block : 2282617 (+1066)

Block : 2314319 (+31702)

Block : 2347087 (+32768)

Block : 2379855 (+32768)

Block : 2412623 (+32768)

-> 지금 다음 복사본으로 예상되는 일치점을 보고있다. 섹터 2314319의 내용을 조사할 때 그것은 1024바이트 블록크기와 그룹 당 8192 블록을 갖는 Ext3 이라는 것을 확인할 수 있다. 그래서 블록그룹 0은 이전 49152 섹터에서 시작해서 섹터 2265167이고, 이전 파일시스템 끝 바로 다음에 온다. 

 

- 슈퍼블록 시그니처가 수 백 군데에서 일치하는 경우는 파일시스템 시작 부분에 위치하는 파일시스템 저널 파일 내 주 슈퍼블록 복사본 때문이다. Ext3는 슈퍼블록 내 모든 업데이트들을 기록하는데, 검색에서 나온 200개의 슈퍼블록들은 저널 내 저장된 복사본들이다. 아래 그림에서 볼 수 있다. 

 

<슈퍼블록 시그니처가 발견되는 위치>

 

-> 이 시나리오에서 ExtX위치를 찾기 위해 슈퍼블록에 시그니처 값을 이용했다. 저널 복사본들이 방해를 했지만 이것은 주 디스크 장애를 대비해서 더 많은 복사본이 있다는 것을 의미한다.

 

 


p.s 코로나 제발