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

UFS1, UFS2 개념과 분석 - 내용 범주 본문

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

UFS1, UFS2 개념과 분석 - 내용 범주

Pikigod 2020. 4. 3. 21:41

16.3 내용 범주

-> 내용범주는 파일과 디렉토리를 포함한다. 이 절은 UFS 파일과 디렉토리 내용을 어디에 저장하는지와 그것을 어떻게 분석하는지 설명하겠다.

 

 

 개요

- UFS는 파일과 디렉토리를 저장하기 위해 조각과 블록을 이용한다. 조각(fragment)은 연속적인 섹터의 그룹이고, 블록(block)은 연속적인 조각의 그룹이다. 모든 조각들은 주소가 있고, 0으로 시작한다. 또한 블록주소는 조각의 첫 주소로 지정된다. 첫 블록과 조각은 파일시스템의 첫 번째 섹터이다. 블록의 최소크기는 4096바이트이고 블록의 조각 개수는 8개가 최대이다. 

 

아래 그림은 블록과 조각의 관계를 보여준다.

<UFS 블록과 조각들이 파일에 할당된 예>

-> 조각 64와 71일 포함하는 블록 64는 파일에 할당되었고, 조각 74와 75는 다른 파일에 할당되었다. 블록 72의 다른 조각들은 다른 파일에 할당될 수 있다.

 

- 데이터 유닛으로 두가지 유형(블록, 조각)을 갖도록 하는 이유는 마지막 블록에 버려지는 영역이 없도록하고 연속적인 데이터에 할당을 위해서이다. UFS는 버려지는 공간의 양을 최소화한다. 

- UFS에서 한 파일이 한 블록 크기라면 그것은 블록 전체에 할당하지만 크기가 더 커서 한 블록으로 부족하면 필요한 만큼 조각을 할당한다.

 

8192바이트 블록과 1024바이트 조각을 갖는 예제 파일시스템에 크기가 20000바이트인 파일은 2개의 블록과 4개의 조각들이 필요하다. 아래 그림과 같이 할당될 수 있다.

<크기가 20000바이트인 파일이 할당된 예>

 

- 블록이나 조각의 할당상태는 블록 비트맵, 조각 비트맵 둘 중 하나를 사용해서 결정한다. 블록비트맵과 조각 비트맵은 거의 비슷한 정보를 가지지만 블록 비트맵이 대용량 파일에서 연속적인 블록들을 더 빠르게 찾아준다. UFS 비트맵들은 설정이 일반 비트맵들과 반대이다. 비트가 1이면 비할당 상태이고, 비트가 0이면 할당상태이다. 

- 그 비트맵들은 실린더 그룹의 그룹 기술자 내부에 저장이 되어있다. 그래서 어떤 그룹에 위치하는지 알아야 해당 블록의 비트맵을 얻을 수 있다. -> 이 작업은 실린더 당 조각의 수로 조각 주소를 나누면 된다.

- 특정 블록의 블록주소를 얻기 위해서 특정블록에서 해당 그룹의 시작 블록주소를 빼야한다. 

 

TSK dsstat 도구는 UFS 조각의 할당 상태를 보여주고, 그 일부분인 실린더 그룹을 얻을 수 있다. UFS예제 이미지 분석 결과는 아래와 같다.

 

#dsstat 0-f openbsd openbsd.dd 288

Fragment : 288

Allocated

Group : 0

 

 

▶ 할당 알고리즘

- 블록이나 조각을 할당할 때 가장 먼저 고려해야할 사항은 실린더 그룹이다. 운영체제는 실린더 그룹 내에 이용가능한 블록 개수가 있는지 확인하고 사용한다. 만약 기존 파일에 블록을 더하는데 기존 그룹에 여유 블록이 없다면 다른 그룹의 블록을 이용한다. 많은 운영체제들은 단일 그룹에 할당할 파일이나 디렉토리 블록 수를 제한한다. 대체로 전체 블록의 25~33%정도이고 그 값에 도달하면 다른 그룹을 선택한다. 솔라리스에서는 파일을 위해 그룹당 12개의 블록을 할당하고, 나머지는 다른 블록에서 할당한다. 

- 운영체제는 실린더 그룹을 선택 후 데이터량에 따라 블록을 할당한다. 만약 파일의 크기를 알 수 없거나 천천히 증가한다면 '다음 적용' 전략을 이용해 블록을 증가시킨다.

- 크기를 알고 있다면 그 데이터 16개의 블록을 데이터 묶음으로 만든다. 이때 '첫 번째 적용'을 이용해 블록들을 각 묶음에 할당한다. 그래서 한 블록이 8192 바이트라면 각 데이터 묶음은 128KB이다. 이 값들은 슈퍼블록에서 설정된다. 

- 운영체제는 파일의 마지막 데이터를 블록 대신 조각으로 할당한다. 그래서 데이터를 위한 연속적인 조각이 있는지 찾는데 이 연속된 조각은 블록 단위로 나뉘고, 파이릿스템의 할당 정보에서는 주어진 길이의 조각들이 어디에서 확인될 수 있는지 목록을 제공한다. 마지막 조각을 할당할때 '첫 번째 적용' 전략을 사용한다.

- 이미 할당된 조각이 있고 파일의 크기가 늘어나면 운영체제는 조각들을 확장하고자 한다. 이것이 불가능하다면 새로운 집합이나 블록을 할당한다. 

- 실험결과 BSD와 솔라리스 시스템들은 조각의 비할당 섹터들을 모두 영구삭제한다. 

 

 

▶ 분석기술 

- 내용범주의 데이터 분석은 블록이나 조각에 위치를 확인해서 그 내용들을 보고, 또 그것들의 할당상태를 구분하는 것이다. 데이터 위치를 확인하기 위해서는 그 블록이나 조각의 주소가 필요하다. 블록과 조각의 크기는 슈퍼블록에서 지정하고, 이러한 정보는 특정 위치까지 주소를 계산할 수 있도록 한다. 블록주소는 블록의 첫 조각의 주소에 해당한다.

- 조각의 할당상태를 판단하기 위해서 조각이 위치하는 실린더 그룹을 먼저 결정해야한다. 슈퍼블록에 있는 그룹 기술자 오프셋 값과 그룹의 기준 주소 값을 더해서 그룹기술자의 위치를 확인할 수 있다. 그 그룹 기술자는 조각 비트맵을 포함한다.

 

 

▶ 분석 고려사항

- UFS 설계와 할당 전략은 수사관들에게 이점과 단점을 제공한다. 우선 블록들의 위치가 inode에 집중되어 파일복구가 쉽다는 이점이 있다. 삭제된 파일이 활동이 적은 그룹에 있었다면 더 오래 데이터가 존재할 수 있다. 또한 연속적인 블록들이 할당이 되기 때문에 단편화가 감소해 데이터 수집을 돕는다. 

- UFS의 단점 중 하나는 마지막 조각이다. 파일의 마지막 조각은 실린더 그룹의 다른 부분에 존재하고 이는 데이터 수집을 어렵게 만든다. 

- UFS는 오직 할당된 조각만 영구삭제해서, 한 블록의 일부분들은 몇개의 조각이 재할당된 후에도 일부 조각은 여전히 유지된다. 

- 실린더 그룹의 25% 이상을 차지하는 파일들은 다른 그룹에 할당이 되기 때문에 복구가 어려울 수 있다. 

 


16.4 메타데이터 범주

-> 메타데이터 범주는 파일이나 디렉토리를 설명하는 데이터가 포함된다. 이 절에서는 UFS가 데이터를 어디에 저장하는지, 그것들을 어떻게 분석해야 하는지 설명하겠다.

 

 

▶ 개요

- ExtX와 마찬가지로 UFS는 파일과 디렉토리의 메타데이터를 저장하기 위해 inode 데이터 구조체를 사용한다. UFS2는 파일에 대한 추가적인 설명 데이터를 저장하기 위해 확장된 속성을 갖는다.

 

▷ inode

- UFS inode는 ExtX와 동일한 기본 개념을 갖는다. 실린더 그룹에 inode 테이블이 존재하고, 위치는 슈퍼블록에서 지정한다. UFS1의 inode는 파일시스템이 생성될 때 초기화된다. UFS2 inode는 필요할 때 초기화되는 동적 inode이고, inode 테이블 공간은 파일의 내용을 위해 사용될 수도 있다. 한 개의 inode는 파일과 디렉토리에 할당되고, 블록주소, 파일크기, 한시적 정보들을 포함한다.

- UFS inode는 직접블록 포인터 12개, 간접블록 포인터 하나, 이중 간접 블록 포인터 하나, 삼중 간접 블록 포인터 하나를 갖는다. 각 블록포인터의 주소는 마지막 포인터를 제외하고는 한개 또는 그 이상의 조각들이 있을 수 있는 블록을 위한 것이다. 파일크기는 얼마나 많은 조각들이 사용되는지 판단하는데 사용된다. 블록 포인터들은 UFS1에서 32비트이고, UFS2에서 64비트이다.

- UFS는 Sparse 파일들을 지원한다. 파일의 일부분의 내용을 정의하지 않거나, 그 블록이 모두 0이면, 운영체제는 블록을 할당하지 않는다. 대신 블록 포인터를 0으로 저장하고, 파일의 해당 부분을 읽을 때 0을 출력한다.

- inode에는 마지막 수정, 접근, 변경시간 값들이 있지만, 지워진 값은 없다. UFS2 inode에 생성시간을 더했다. 1970년 1월 1일을 기준으로 지나간 초를 나눈 단위로 저장한다. UFS1에서 32비트이고 UFS2에서 64비트이다.

- inode 0 과 1은 예약되어있어 파일을 위해 사용되지 않는다. inode 2는 루트 디렉토리를 위해 예약되어있다. inode할당상태는 그룹 기술자에 위치한 inode 비트맵을 이용해 확인할 수 있다. inode 주소를 슈퍼블록에서 제공하는 그룹 당 inode 개수로 나누면 inode가 어떤 그룹에 있는지 결정할 수 있다. 

 

▷ 확장 속성

- UFS2에서 파일이나 디렉토리에 대한 설명 데이터를 저장하기 위해 확장속성이 추가되었다. 확장 속성에는 두 이름 값이 있으며, 사용자 이름공간시스템 이름 공간이라는 두가지 유형이 있다. 파일 내용을 읽을 수 있는 사용자는 파일의 사용자 이름 공간 속성들을 읽을 수 있다. 시스템 이름 공간 속성은 권한이 있는 사용자들이 읽을 수 있다.

- UFS2 inode에는 확장 속성을 위한 3개의 필드가 있다. 하나는 크기값이고, 두번째는 속성들이 어디에 저장되었는지를 나타내는 블록주소이다. 그 블록들은 헤더와 속성값을 포함하는 변동가능한 길이의 데이터 구조체들로 채워진다. 사용자들은 그 속성들을 Setextattr 명령어로 설정이 가능하고 응용프로그램들은 특정 시스템 콜들로 설정할 수 있다.

 

 예제이미지

 

※ inode에 어떠한 데이터들이 존재하는지 확인하는 차원에서 istat 도구를 통해 예제 파일시스템 이미지를 분석해 보았다.

-> 이 파일은 1247880바이트이고, 8KB 블록들이 12개 이상 필요하다. '직접블록' 마지막 줄은 1576부터 8개 중 오직 5개만 사용된 것을 알 수 있다. 또한 블록 384는 간접 블록 포인터로 사용된다. 

 

 

할당 알고리즘

- UFS inode의 할당 방법은 ExtX에서 보았던 것과 같다. 전형적으로 실린더 그룹 중 디렉토리 평균 개수가 작고, 이용가능한 블록들의 평균 개수보다 큰 그룹에 inode를 할당한다. 또한 한 파일에 inode를 부모 디렉토리와 동일한 실린더 그룹에 할당한다. 실린더 그룹에 유효한 inode를 찾을 때, '첫 번째 적용' 전략을 사용한다.

- inode를 할당할 때 전 내용들은 모두 지워지고, MAC-time, 그리고 Create-time(UFS2)을 현재시간으로 설정한다. 연결 카운트를 1로 설정하고, 디렉토리 내부 '.' 이름을 설명하기 위해 디렉토리는 2로 설정한다.

- 파일을 삭제할 때 BSD 시스템들과 솔라리스는 inode 내부에 블록 포인터, 크기, 모드를 제거한다. 비할당된 inode를 찾더라도 전체크기, 내용위치, 파일유형을 알 수 없다. 하지만 간접 블록 포인터 내용은 제거되지 않고 이는 파일 복구에 도움을 준다. 

 

 

 분석기술

- 데이터의 메타데이터 범주를 분석할때 더욱 많은 정보를 얻기 위해서 파일을 설명하는 메타데이터를 찾아야 한다. 이는 inode를 찾아야하고, 그것들의 할당 상태를 판단해야하며, 존재하는 확장된 속성들을 처리해야 한다.

- 특정 inode 위치를 확인하기 위해 먼저 그룹을 찾아야한다. 그룹에 있는 inode 개수로 inode 주소를 나누어 확인할 수 있다. inode테이블 위치는 다음 그룹의 시작조각과 슈퍼블록에서 주어주는 inode 테이블 오프셋을 사용해서 확인할 수 있다. UFS1에서는 그룹에 오프셋이 얼마씩 변하는지 계산할 필요가 잇다. 

- inode를 처리하는 것은 꽤 직접적이다. 모든 필드와 시간들이 인코딩되어있어 그것들을 이해하기 위해서 반드시 해석이 필요한다. 내용이 있는 위치를 확인하기 위해서는 12개의 직접 블록 포인터를 이용한다. 또한 내용이 큰 경우 간접블록들을 읽어야하고 그것들의 내용에는 블록 주소들의 목록이 있다.

- 0 값을 갖는 블록 포인터는 Sparse 블록이고, 모두 0인 블록에 해당한다. 마지막 블록 포인터를 위해 파일의 전체 크기를 고려해야 한다. 마지막 블록은 조각일 수 있고, 다음 조각은 다른 파일로 사용될 수 있다. 

- inode의 할당상태를 결정하기 위해서 그룹 기술자에 있는 그룹 inode 비트맵을 사용한다. 그룹기술자는 그룹 시작주소와 슈퍼블록에서 제공하는 오프셋 값들을 사용하자. inode 비트가 1로 설정되어 있으면 그것은 할당된 것이다.

- 비할당된 모든 inode 엔트리를 조사해서 지워진 파일들의 정보를 찾을 수 있다. inode 비트맵에서 비트가 0이아닌 inode만 추출이 가능하다. 

- 또한 확장된 속성들에 숨겨진 데이터가 있을 수 있기 때문에 이것들도 조사하자. inode에서 저장하고 있는 블록들을 읽고, 각 엔트리를 해석해서 이 작업을 할 수 있다.

 

 

분석 고려사항

- UFS 메타데이터 분석 고려사항은 ExtX 메타데이터와 유사하다. 다만 삭제된 파일들은 UFS 간접 블록 포인터에서는 보전된다. 그래서 간접블록 포인터 위치를 확인하고, 파일을 재구성해서 보구한다. 비할당된 inode엔트리의 MAC-time은 지워진 시간을 반영한다. 할당 전략들은 특정 그룹에 집중하여 수집시 필요하다. 

- BSD 시스템들은 슬랙공간으로 불리는 파일의 마지막 조각에 0을 쓴다. 그래서 지워진 파일들에 비할당된 조각들에서 데이터를 찾을 수 있다. 다행히 적은 개수의 조각들이 할당되고, 영구 삭제된다. 그래서 한 블록은 재할당되지 않은 조각들에 삭제된 데이터를 여전히 포함할 수 있다.(?)

- UFS2 파일시스템의 확장된 속성들은 적은 양의 데이터를 숨기는데 사용될 수 있다. 크기가 두 블록으로 제한되어 있지만, 분석도구들로 이 내용을 확인할 수 있는지, 키워드 검색이 가능한지 확인해보자.

- 데이터를 숨기기 위해 동적 inode 테이블을 활용할 수 있다. 운영체제는 그 영역이 필요할 때까지 inode테이블 엔트리블록을 초기화하지 않는다. 그래서 운영체제가 그 영역을 재사용하고, 그 데이터를 지울때까지는 사용되지 않는 영역에 데이터를 숨길 수 있다.