Network Forensic #50 (특정 위치에 무선 트래픽이 포함된...)

 

네트워크 포렌식 50번 문제

 

주어진 파일을 다운로드하면 cap 확장자를 가진 패킷 캡처 파일이다.

 

해당 파일 분석을 위해 Wireshark 도구로 분석해보자.

 

Wireshark : 오픈 소스 패킷 분석 프로그램으로 pcap을 이용하여 패킷을 잡아내는 것이 주요 기능

 

다운로드 사이트 : https://www.wireshark.org/download.html

 

Wireshark · Download

Riverbed is Wireshark's primary sponsor and provides our funding. They also make great products that fully integrate with Wireshark. I have a lot of traffic... ANSWER: SteelCentral™ AppResponse 11 • Full stack analysis – from packets to pages • Rich perfor

www.wireshark.org

 

[그림 1] 문제 파일 확인

 

문제 파일을 확인해보면 일반 패킷 파일이 아닌 802.11 프로토콜을 가진 무선 패킷 파일이라는 것을 확인 가능하다.

 

무선 패킷 경우 암호화가 되어 있는 경우가 많기 때문에 평소 확인할 수 있는 패킷 캡처 파일과는 다르게 패킷 내용이 표시가 되지 않는다.

 

따라서 해당 패킷에 대한 암호화를 풀어야 해당 패킷 내용들을 확인할 수 있다.

 

암호를 풀기 위해 aircrack-ng 도구를 사용하여 분석하였다.

 

aircrack-ng : 무선랜 패킷 파일에 대한 종합 분석 도구이며, Monitoring / Attacking / Testing / Cracking 등 다양한 기능을 사용할 수 있다. (airdecap는 같은 폴더에 존재하며, 복호화 도구이다.)

 

다운로드 사이트 : https://www.aircrack-ng.org/

 

Aircrack-ng

This release brings a ton of improvements. Along with bug fixes and improvements for a lot of tools, we have huge improvements under the hood thanks to code cleanup, deduplication, and reorganization of the source code. We also improved our buildbot, and a

www.aircrack-ng.org

[그림 2] aircrack-ng 분석 결과

 

aircrack-ng를 사용하여 분석한 결과, WPA 방식 암호를 사용하는 것을 확인할 수 있으며, ESSID의 이름도 확인 가능하다.

 

ESSID : 접속하고자 하는 네트워크 이름

 

 

해당 패킷이 위처럼 WPA 방식이 아닌 WEP 방식이라면 암호화가 되어 있을 경우에 aircrack-ng를 사용해서 바로 암호를 찾아 복호화를 진행할 수 있다.

 

그러나 해당 패킷은 WPA 방식을 사용하였기 때문에 ESSID와 해당 패스워드를 알아야 복호화가 가능하다.

 

ESSID 패스워드는 해당 도구로 확인이 어렵기 때문에 암호화가 되지 않은 패킷을 사용한 IP 주소를 필터링하여 패스워드 실마리를 찾을 수 있는지 분석하였다.

 

[그림 3] IP 주소 필터링

 

ip.addr == 192.168.43.61 (암호화 되지 않은 패킷의 IP 주소)로 필터링하여 확인해보면 [그림 3]과 같이 GET 메소드를 사용하는 HTTP 패킷을 확인 가능하다.

 

해당 패킷의 상세 분석을 위해 [Follow TCP Stream]을 통해 확인해보자.

 

[그림 4] GET 메소드 Follow TCP Stream eq 0

 

'Hdbgarea'라는 문자열을 확인할 수 있으며 데이터를 보내는 것을 확인 가능하다.

 

해당 문자열을 구글링을 통해 검색해보면 RouterPassView라는 도구를 확인할 수 있다.

 

해당 도구는 라우터의 백업 파일을 이용하여 잃어버린 패스워드를 찾아주는 도구이다.

 

해당 도구를 사용하여 원하는 패스워드를 확인해보자.

 

RouterPassView : 라우터 백업 파일을 이용해 잃어버린 비밀번호를 찾아주는 도구

 

다운로드 사이트 : https://www.nirsoft.net/utils/router_password_recovery.html

 

RouterPassView - Recover lost password from router backup file on Windows

    RouterPassView v1.88 - Recover lost password from router backup file Copyright (c) 2010 - 2019 Nir Sofer See Also Description Most modern routers allow you to backup the configuration of the router into a file, and then restore the configuration from t

www.nirsoft.net

 

[그림 5] 데이터 추출

 

위 도구를 사용하기 위해 'Hdbgana' 문자열이 있는 데이터 부분을 추출해서 파일로 만든 다음, 데이터 파일을 분석해야 한다.

 

ASCII에서 RAW로 바꾼 다음, Save as...를 눌러 저장한다.

 

[그림 6] HxD로 실행 (헤더 부분 제거)

 

저장한 데이터 파일은 패킷의 헤더 부분까지 저장되므로 데이터 부분만 추출하고 싶을 때는 HxD를 실행하여 헤더 부분을 제거한다.

 

이제 RouterPassView를 실행하여 추출한 데이터를 열어보자.

 

[그림 7] 추출된 데이터 파일

 

[File] - [Open Router Config File] 메뉴를 통해 추출한 데이터를 확인해보면 위 그림과 같이 패스워드 확인이 가능하다.

 

이제 해당 패킷의 ESSID와 패스워드를 알았으니 해당 문제 패킷을 airdecap-ng 도구를 사용하여 복호화를 진행해보자.

 

[그림 8] 문제 패킷 파일 복호화

 

위 명령어대로 입력해주면 복호화가 성공적으로 진행되며, 복호화 된 패킷 파일이 생성된다.

 

이제 복호화 된 패킷 파일을 열어 내용을 확인해보자.

 

[그림 9] 복호화 파일 내용 확인

 

복호화 된 파일 내용은 아예 다른 내용인 것을 확인할 수 있다.

 

이제 해당 문제에 대한 플래그를 찾아야 한다.

 

패킷에서 문제의 플래그 포맷을 검색해보면 다음과 같이 패킷 데이터에 문제 플래그 포맷이 확인 된다.

 

[그림 10] 문제 플래그 검색

 

String으로 전환한 다음, 문제의 플래그를 검색해보면 위 화면과 같이 관련된 여러 패킷들이 확인된다.

 

해당 패킷들의 상세 분석을 위해 [Follow TCP Stream] 기능을 통해 확인해보면 문제의 플래그 확인이 가능하다.

 

[그림 11] 플래그 확인

 

이렇게 해서 위 과정을 통하여 해당 문제를 해결할 수 있다.


# Reference

 

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

Network Forensic #41 (우리의 제일 귀여운...)

 

네트워크 포렌식 41번 문제

 

문제 파일로 stego.pcap 파일이 주어진다.

 

pcap 파일 분석을 위해 Wireshark 도구를 통해 분석을 진행해보자.

 

Wireshark : 오픈 소스 패킷 분석 프로그램으로 pcap을 이용하여 패킷을 잡아내는 것이 주요 기능

 

다운로드 사이트 : https://www.wireshark.org/download.html

 

Wireshark · Download

Riverbed is Wireshark's primary sponsor and provides our funding. They also make great products that fully integrate with Wireshark. I have a lot of traffic... ANSWER: SteelCentral™ AppResponse 11 • Full stack analysis – from packets to pages • Rich perfor

www.wireshark.org

 

[그림 1] message.png 요청 발견 

 

분석을 진행하다 보면 3번 패킷에서 message.png 파일을 서버로 요청한 것을 확인할 수 있다.

 

상세 분석을 위해 [Follow TCP Stream] 기능을 통해 분석해보자.

 

[그림 2 Follow TCP Stream 기능 분석

 

TCP Stream을 보면 클라이언트가 message.png 파일을 다운로드 한 기록이 존재한다.

 

혹시 png 파일의 내용을 보면 플래그가 나올 줄 알고 확인해본 결과, 플래그에 대한 아무런 내용도 존재하지 않는다.

 

그래서 다시 pcap 파일을 계속해서 분석한 결과, 중요한 내용을 발견하였다.

 

[그림 3] Urgent pointer 

 

Urgent Pointer : 긴급 데이터 처리를 위해 사용되며, URG 플래그 비트가 지정된 경우에만 유효

 

패킷 세부 정보를 분석하던 도중 Urgent pointer가 사용된 기록을 발견하였다.

 

Urgent pointer로 긴급 메시지가 전송될 때는 별도의 패킷으로 전송되지 않고 일반 데이터에 포함되어 함께 전달된다.

 

Urgent pointer 값 중 0을 제외한 모든 값들에 대한 분석을 위해 tshark 프로그램을 사용하여 0을 제외한 나머지 값들을 추출하여 분석하였다.

 

Tshark : Wireshark 도구의 CLI 버전이라고 할 수 있으며, 리눅스 환경에서 사용 가능

 

설치 방법 : sudo apt-get install Tshark 입력

 

[그림 4] tshark 프로그램 사용

 

위 명령어대로 Urgent pointer 값을 출력하면 여러 값들이 나오는 것을 확인할 수 있다.

 

문제를 해석해보면 스테가노그래피 기법으로 플래그를 숨겼다고 추측해볼 수 있으며, 10진수 0~127 값이 사용되는 아스키 코드가 사용됐을 수도 있다.

 

따라서 플래그 확인을 위해 Python으로 아스키 코드에 매칭 되는 문자열로 변환시켰다.

 

[그림 5] Python 코드

 

Python 코드는 위 코드와 같다.

 

[그림 6] 플래그 확인

 

결과를 확인해보면 변환된 값이 플래그라는 것을 확인할 수 있다.

 

위 과정을 통해 해당 문제를 해결할 수 있다.


# Reference

 

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

[Digital Forensic] EXT 파일 시스템 (3)

 

EXT 파일 시스템 (3)


(16) Ext4 파일 시스템 분석

 

최근에 Ext 파일 시스템은 Ext4 버전으로 업그레이드 되었다.

 

기본 개념에 새로운 기능들이 추가된 Ext4 파일 시스템은 최근 빠르게 Ext3 파일 시스템을 대체하고 있다.

 

이러한 변화에 당연히 포렌식 전문가들은 적응을 해야 한다.

 

Ext4 파일 시스템은 Ext3 파일 시스템의 개선 버전으로 현재 대부분 리눅스에서 사용 중이며, 포렌식 분석 도구들도 대부분 해당 파일 시스템 분석을 지원하고 있다.

 

 

16-1. Ext4 특징

 

대용량 파일 시스템

  • Volume 크기는 1EiB, 파일 용량은 16TB까지 지원

 

Extents

  • 이전 Ext 파일 시스템은 Block mapping을 지원하였는데, Ext4 파일 시스템부터는 Extents 방식을 지원하여 블록 단편화 현상을 줄임

  • Ext4 파일 시스템에서 Block mapping 대신 Extents를 사용한다면 Ext4 이전 파일 시스템에 마운트 될 수 없음

 

호환성

  • Ext4 이전의 파일 시스템을 Ext4 형식으로 변경하여 Ext4 파일 시스템에 마운트하여 성능 향상 상태로 사용할 수 있음

  • 또 Ext4 파일 시스템을 Ext4 이전 파일 시스템에 마운트하여 사용할 수도 있음

 

저널 체크섬

  • 이전 Ext 파일 시스템에는 없던 저널 체크섬이 추가 됨

 

64000개 서브 디렉토리

  • Ext4 파일 시스템 이전 버전들은 서브 디렉토리의 최대 개수가 32000개 였음

  • 하지만 이번 버전에서는 64000개로 늘어나 조금 더 많은 디렉토리를 생성할 수 있게 됨

 

온라인 조각 모음

  • Ext4 파일 시스템에서 새로 생긴 기능

 

파일 시스템 검사 속도 향상

  • 파일 시스템에서 사용하지 않는 부분을 건너띄고 검사하여 검사 속도가 향상 됨

 

타임스탬프

  • Ext4 파일 시스템 이전 버전에서는 초 단위로 1901년 12월 14일 ~ 2038년 1월 18일까지 시간을 기록할 수 있었음

  • Ext 파일 시스템부터는 나노초로 계산되며 1901년 12월 14일 ~ 2514년 4월 25일까지 기록할 수 있게 됨

 

지연 할당

  • 해당 기능은 Ext4 파일 시스템에서 새로 생긴 기능

  • 어떤 파일에 대한 블록 할당을 최대로 지연하여 가능한 연속 블록에 할당되게끔 하는 기능

 

멀티 블록 할당

  • Ext4 파일 시스템 이전 버전에서는 파일 기록에 여러 블록이 필요하면 보통 떨어져 있는 블록들을 할당하여 파일을 기록

  • Ext4 파일 시스템 버전부터는 멀티 블록 할당자를 통해 블록 여러 개를 동시에 할당하여 블록이 연속되어 할당되게끔 함

  • 이러한 기능으로 인해 블록 호출 횟수가 줄어들어 할당 속도도 빨라짐

 

Ext4도 결국 파일 시스템 전체 레이아웃은 Ext4 파일 시스템 이전 버전들과 동일하다.

 

하지만 블록 그룹의 레이아웃이 약간 다르다.

 

[그림 1] Ext4 블록 그룹 레이아웃

  • Group 0 Padding : 32(x86)bit 시스템 부트 섹터 등을 위한 영역이며, 크기는 1024byte

  • Reserved GDT Block : 파일 시스템의 확장을 위해 예약되어 있는 영역

 

보통 슈퍼 블록, 데이터 블록 비트맵, inode 비트맵은 블록 1개 크기이다.


16-2. 슈퍼 블록

  • Ext4에서도 슈퍼 블록의 역할은 대부분 비슷

  • 슈퍼 블록에는 sprase_super라는 플래그 기능이 있으며, 이 플래그가 설정되면 슈퍼 블록 및 그룹 기술자 백업본은 그룹 번호, 0, 3, 5, 7에 존재하게 됨

  • 플래그가 설정되어 있지 않으면 모든 그룹에 존재하게 됨

 

다음 표는 Ext4 파일 시스템의 슈퍼 블록 오프셋 구조에 대한 내용이다.

 

[표 1] 슈퍼 블록 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

inode의 총 개수

252~252

디렉토리 해시에 사용할 해시 알고리즘

4~7

블록의 총 개수

253~253

????

8~11

사용 가능한 블록 개수

254~255

그룹 기술자의 크기

12~15

사용 가능한 블록 개수

256~259

마운트 옵션

16~19

사용 가능한 inode 개수

260~263

Meta_bg 기능 활성화 경우에 첫 번째 메타 블록의 블록 그룹

20~23

첫 번째 데이터 블록

264~267

파일 시스템 생성 시간(s)

24~27

블록 크기 연산의 피연산자

268~335

첫 번째 저널 inode의 68byte 복사본

28~31

조각 크기(사용 X)

336~339

블록 개수의 상위 32bit 

32~35

그룹별 블록 개수

340~343

예약 블록 개수의 상우 32bit

36~39

그룹별 조각 개수(사용 X)

344~347

예약되지 않은 블록 개수의 상위 32bit

40~43

그룹별 inode 개수

348~349

inode 최소 예약 크기

44~47

마운트 시간(s)

350~351

새로운 inode의 최소 예약 크기

48~51

쓰기 시간(s)

352~355

기타 플래그

52~53

fsck 이후 마운트 횟수

356~357

다음 디스크로 이동하기 전 디스크 논리 번호(RAID)

54~55

fsck 이후 최대 마운트 횟수

358~359

다중 마운트 검사 최소 수행 시간

56~57

시그니처(0xEF53)

360~367

다중 마운트 보호가 적용되는 블록

58~59

파일 시스템 상태 플래그

368~371

현재 디스크 논리 번호(RAID)

60~61

오류 감지 후 행위 플래그

372~372

블록 그룹 크기

62~63

마이너 레벨

373~373

?????

64~67

마지막 체크 시간(s)

374~375

?????

68~71

최대 시간과 체크 시간의 차이

376~383

파일 시스템 생성 후 파일 시스템에 기록된 KB 개수

72~75

OS 종류

384~387

활성 스냅샹 inode 번호

76~79

레벨 플래그

388~391

활성 스냅샷 순차 번호(ID)

80~81

예약 블록 UID

400~403

디스크 스냅샷 목록의 첫 번째 inode 번호

82~83

예약 블록 GID

404~407

오류 개수

84~87

예약되지 않은 첫 번째 inode

408~411

처음 오류가 발생한 시점으로부터 지난 시간(s)

88~89

inode 크기(byte)

412~415

첫 번째 오류와 관련된 inode

90~91

해당 슈퍼 블록이 포함된 블록 그룹 차단

416~423

첫 번째 오류와 관련된 블록

92~95

호환 기능 플래그

424~455

오류가 일어난 함수 이름

96~99

비호환 기능 플래그

456~459

오류가 일어난 라인 번호

100~103

읽기 전용 호환 기능 플래그

460~463

가장 최근 오류가 일어난 시간(s)

104~119

128bit 볼륨 UUID

464~467

가장 최근 오류가 일어난 inode

120~199

파일 시스템이 마지막으로 마운트 된 디렉토리

468~471

가장 최근 오류가 일어난 라인 번호

200~203

압축

472~479

가장 최근 오류가 일어난 블록 개수

204~204

????

480~511

가장 최근 오류가 일어난 함수 이름

205~205

????

512~575

마운트 옵션의 ASII 문자열

206~207

예약 GDT 엔트리 개수

576~579

사용자 할당량 파일 inode

208~223

저널 Super Block UUID

580~583

그룹 할당량 파일 inode

224~227

저널 파일의 장치 번호

584~587

오버헤드 블록

228~231

저널 파일 inode

588~591

SuperBlock 체크섬

232~235

삭제되지 않은 inode 목록 시작 위치

592~1023

블록 끝 Padding

236~251

해시 트리

   

 

Ext4로 업그레이드 되면서 슈퍼 블록 또한 많은 것이 추가되었다.

 

 

블록 크기 계산에 필요한 필드

  • 블록 크기는 2**(10+해당 필드 값)으로 계산

 

파일 시스템 상태 플래그

  • 파일 시스템 상태를 나타내는 필드

  • Ext4 파일 시스템 이전 버전들과 동일

 

오류 감지 후 행위 플래그

  • 오류 감지 후 어떠한 조치를 취해야 할지 결정 해주는 플래그가 설정되는 필드

  • Ext4 파일 시스템 이전 버전들과 동일

 

OS 종류

  • 해당 파일 시스템을 생성한 OS 종류를 나타내는 필드

  • Ext4 파일 시스템 이전 버전들과 동일

 

레벨 플래그

  • 파일 시스템 버전을 나타내는 필드

  • Ext4 파일 시스템 이전 버전들과 동일

 

호환 기능 세트 플래그

  • 0x01 : 단편화를 줄이기 위하여 디렉토리 블록을 사전에 할당

  • 0x02 : AFS 서버 inode 지원

  • 0x04 : 파일 시스템 저널 지원

  • 0x08 : 확장 속성 지원

  • 0x10 : 파일 시스템 확장을 위한 GDT 블록 예약

  • 0x20 : 디렉토리가 해시 인덱스를 사용

  • 0x40 : ????

  • 0x80 : ????

 

비호환 기능 세트 플래그

  • 0x01 : 압축

  • 0x02 : 디렉토리 항목을 파일 형식으로 기록

  • 0x04 : 파일 시스템 복구

  • 0x08 : 파일 시스템 별도의 저널 장치

  • 0x10 : 메타 블록 그룹

  • 0x40 : 해당 파일 시스템의 extents 기능을 사용하는 파일

  • 0x80 : 블록으로 파일 시스템 파일 크기를 결정

  • 0x100 : 다중 마운트 보호(아직 구현 X)

  • 0x200 : Flevible 블록 그룹

  • 0x400 : inode의 매우 큰 확장 속성을 사용

  • 0x1000 : 디렉토리 엔트리 내의 데이터

 

읽기 전용 호환 기능 세트 플래그

  • 0x01 : Sparse SuperBlock

  • 0x02 : 해당 파일 시스템은 대용량 파일을 포함(2GB 이상)

  • 0x08 : 해당 파일 시스템의 크기가 블록이 아닌 섹터로 표현

  • 0x10 : 그룹 기술자의 체크섬

  • 0x20 : 디렉토리를 제한

  • 0x40 : 매우 큰 inode 존재

  • 0x80 : 해당 파일 시스템의 스냅샷

 

디렉토리 해시에 사용할 해시 알고리즘

  • 0x0 : Legacy

  • 0x1 : Half MD4

  • 0x2 : Tea

  • 0x3 : 서명되지 않은 Legacy

  • 0x4 : 서명되지 않은 MD4

  • 0x5: 서명되지 않은 Tea

 

마운트 옵션 (파일 시스템이 마운트 될때의 옵션을 결정하는 필드)

  • 0x0001 : 마운트 시 디버깅 정보를 인쇄

  • 0x0002 : 새로운 파일을 포함하는 디렉토리의 GID 획득

  • 0x0004 : UserSpace에서 확장 속성 지원

  • 0x0008 : POSIX ACL 지원

  • 0x0010 : 32비트 UID를 지원하지 않음

  • 0x0020 : 모든 데이터와 메타 데이터를 저널 대상에 포함

  • 0x0040 : 저널 기능이 메타데이터를 저널하기 전 모든 데이터를 디스크로 Flush

  • 0x0080 : 요청 데이터는 메타데이터 기록 후 기록

  • 0x0100 : Flush 기록 해제

  • 0x0200 : 파일 시스템의 블록 메타데이터 위치 추적

  • 0x0400 : 미사용 블록에 대한 저장장치 지원을 취소

  • 0x0800 : 지연 할당 해제

 

기타 플래그(비필수 플래그를 나타내는 필드)

  • 0x0001 : 사용 중인 디렉토리 해시 서명

  • 0x0002 : 사용 중인 서명되지 않은 디렉토리 해시

  • 0x0004 : 개발 코드 테스트

 

블록 그룹 크기

  • 블록 그룹의 크기를 결정하는 필드

  • 2**해당 필드 값 계산식을 이용하여 블록 그룹의 크기를 구할 수 있음


16-3. 그룹 기술자 테이블

  • Ext4 파일 시스템의 그룹 기술자 테이블은 Ext4 파일 시스템 이전 버전들의 내용과 크게 다르지 않음

  • 32bit 시스템과 64bit 시스템 모두 파일 시스템이 적용될 수 있도록 그룹 기술자가 명시해야 하는 블록 비트맵, inode 비트맵 / 테이블 등의 주소를 가지고 있어야 할 오프셋 필드 크기를 8byte(64bit)로 늘림

  • 32bit 시스템에 Ext4 파일 시스템이 적용된다면 하위 bit 오프셋 필드만 사용될 것이고, 64bit 시스템에 Ext4 파일 시스템이 적용된다면 상/하위 오프셋 필드 모두 사용될 것

 

다음 표는 그룹 기술자 오프셋 구조에 대한 내용이다.

 

[표 2] 그룹 기술자 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

블록 비트맵 주소 하위 32비트

32~35

블록 비트맵 주소 상위 32비트

4~7

inode 비트맵 주소 하위 32비트

36~39

inode 비트맵 주소 상위 32비트

8~11

inode 테이블 주소 하위 32비트

40~43

inode 비트맵 주소 상위 32비트

12~13

예약되지 않은 블록 개수 하위 16비트

44~45

예약되지 않은 블록 개수 상위 16비트

14~15

예약되지 않은 inode 개수 하위 16비트

46~47

예약되지 않은 inode 개수 상위 16비트

16~17

디렉토리 개수 하위 16비트

48~49

디렉토리 개수 상위 16비트

18~19

그룹 플래그

50~51

사용하지 않은 inode 개수 상위 16비트

20~23

?????

52~55

?????

24~27

?????

56~59

?????

28~29

사용하지 않은 inode 개수의 하위 16비트

60~63

Padding

30~31

그룹 기술자 체크섬(64bit 기능 활성화 시 설정)

   

 

그룹 플래그

 

그룹 기술자에 대한 플래그 필드로 아래와 같은 플래그 목록들이 설정될 수 있다.

 

오프셋 필드의 크기와 체크섬 필드가 추가된 것을 제외하고는 Ext4 파일 시스템 이전 버전들과 다른 점이 없다.

 

  • 0x1 : inode 테이블 및 비트맵 초기화를 수행하지 않음

  • 0x2 : 블록 비트맵 초기화를 수행하지 않음

  • 0x4 : inode 테이블을 0으로 초기화


16-4. inode

  • 이전 버전들과 마찬가지로 inode 테이블의 각 엔트리로 존재

  • inode 위치는 그룹 기술자 테이블에 정의되어 있음

  • 그룹별 inode는 슈퍼 블록에 정의되어 있음

  • Ext4 파일 시스템 이전 버전들의 inode 표준 크기는 128byte이었는데 Ext4 파일 시스템에서는 256Byte로 늘어남

 

다음 표는 inode 오프셋 구조에 대한 내용이다.

 

[표 3] inode 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~1

모드 타입

100~103

파일 버전(NTFS)

2~3

소유자 UID 하위 16비트

104~107

확장 속성 블록의 하위 32비트

4~7

inode의 크기(Byte) 하위 32비트

108~111

파일 크기의 상위 32비트

8~11

마지막 접근 시간(s)

112~115

조각 주소(사용 X)

12~15

마지막 변경 시간(s)

116~128

?????

16~19

마지막 수정 시간(s)

129~130

inode 크기

20~23

삭제 시간(s)

131~131

?????

24~25

GID 하위 16비트

133~135

추가 변경 시간 bit(초 단위보다 더 정밀)

26~27

하드 링크 개수

136~139

추가 수정 시간 bit(초 단위보다 더 정밀)

28~31

블록 개수의 하위 32비트

140~143

추가 접근 시간 bit(초 단위보다 더 정밀)

32~35

플래그

144~147

생성 시간(s)

36~39

?????

148~151

추가 생성 시간 bit(초 단위보다 더 정밀)

40~99

블록 맵 또는 extents tree 해시 설정 플래그

152~155

버전 번호 상위 32bit

 

모드 타입

  • inode가 할당된 파일이나 디렉토리의 타입과 권한을 나타내는 필드

  • Ext4 파일 시스템 이전 버전들과 동일

 

플래그 (inode의 플래그를 나타내는 필드)

  • 0x00000001 : 해당 파일을 안전하게 삭제해야 함 (아직 구현 x)

  • 0x00000002 : 파일이 삭제되지 않게 보존되어야 함 (아직 구현 x)

  • 0x00000004 : 파일 압축 (아직 구현 x)

  • 0x00000008 : 파일과 디렉토리 모두 할당 가능

  • 0x00000010 : 특정 파일에 할당

  • 0x00000020 : 파일에만 할당 가능

  • 0x00000040 : 해당 inode가 할당된 파일의 덤프 불가

  • 0x00000080 : 접근 시간 업데이트 불가

  • 0x00000100 : 불필요한 파일 압축 (사용 X)

  • 0x00000200 : 파일 저장 영역 중 압축 영역이 하나 이상 있음

  • 0x00000400 : 파일 압축 금지 (사용 X)

  • 0x00000800 : 압축 오류 (사용 X)

  • 0x00001000 : 디렉토리 인덱스 해시

  • 0x00002000 : AFS 디렉토리

  • 0x00004000 : 파일 데이터 저장은 항상 저널링을 사용하여 수행되어야 함

  • 0x00008000 : 파일 병합 불가

  • 0x00010000 : 모든 디렉토리 계층에서 상위에 해당

  • 0x00020000 : 디렉토리 계층에서 상위에 해당

  • 0x00040000 : 대용량 파일

  • 0x00080000 : 해당 inode는 extents를 사용

  • 0x00200000 : 해당 inode는 큰 확장 속성을 사용

  • 0x00400000 : 해당 파일은 파일보다 큰 블록을 가지고 있음

  • 0x00800000 : Ext4 라이브러리 예약

  • 0x004BDFFF : 사용자 표시 플래그

  • 0x004B80FF : 사용자가 수정할 수 있는 플래그

 

오프셋 구조를 보면 156byte까지만 나와 있는데 앞서 설명할 때에는 inode 크기가 256byte라고 하였다.

 

현재로서는 정확하지 않지만 나머지 오프셋 필드들은 확장 속성이나 또 다른 용도로 쓰일 것으로 추측된다.


16-5. Extents Tree

  • Ext4 파일 시스템에서 새로 추가된 기능

  • 이전 버전들의 블록 맵을 대체하는 기능

  • 제일 중요한 점은 블록 할당을 연속으로 하려 한다는 점

  • Extents tree에는 다른 tree들처럼 인덱스 노드와 리프 노드가 존재하고 공통적인 헤더(12byte)가 존재

 

다음 표는 헤더 오프셋 구조에 대한 내용이다.

 

[표 4] 헤더 오프셋 구조

범위(Byte)

설명

0~1

시그니처(0xF30A)

2~3

헤더의 유효 항목 개수

4~5

헤더 항목 최대 개수

6~7

인덱스/리프(leaf) 노드 구별

8~11

?????

 

만약 헤더의 6~7 오프셋의 값이 0이 아니라면 인덱스 노드라는 의미이다.

 

인덱스 노드의 몸통, 즉 헤더 다음에 오는 구조이다.

 

인덱스 노드 오프셋 구조는 다음과 같다.

  • 0~3 : 블록을 가리키는 리프(leaf) 노드

  • 4~7 : 하위 노드 번호의 하위 32bit

  • 8~9 : 이전 필드 상위 16bit

  • 10~11 : ?????

 

헤더에서 6~7 오프셋 필드의 값이 0이라면 리프(leaf) 노드라는 의미이다.

 

리프 노드의 오프셋 구조는 다음과 같다.

  • 0~3 : 해당 노드가 할당된 파일의 첫 번째 블록 주소

  • 4~5 : 하위 노드 번호의 하위 32bit

  • 8~9 : 첫 번째 블록 번호 상위 16bit

  • 10~11 : 첫 번째 블록 번호 하위 16bit

 

[그림 2] Extents Tree (IBM 문서)

 

[그림 2]는 Extents Tree의 전체적인 흐름을 그림으로 표현한 것이다.

 

완전하게 데이터를 연속적으로 할당하는 것은 아니지만 동일한 리프 노드 데이터의 경우 디스크에 조금의 거리는 있지만 가까운 블록에 연속 할당하는 것을 볼 수 있다.

 

이런 점은 포렌식적으로 아주 유용하다.

 

뿔뿔이 흩어져 있는 조각난 데이터는 다시 모아 복구하기가 쉽지 않지만 이렇게 연속적은 블록들은 복구하기가 비교적 쉽기 때문이다.

 

이렇게 Ext4 파일 시스템이 어떻게 이전 버전들과 다른지 알아보아다.

 

업그레이드 버전이어서 전체적 구조나 기술 등의 원리가 바뀌었다고는 볼 수 없었다.

 

그렇기에 중복되는 기술이나 그 기술의 원리 또는 개념 등은 Ext4 파일 시스템 분석을 하면서 제외하였다.


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

 

Ext 파일 시스템 또한 FAT, NTFS와 크게 다르지 않다.

 

Ext 파일 시스템의 경우 디렉토리 엔트리에 숨겨진 데이터가 있는지 확인해 볼 필요가 있다.

 

마지막 디렉토리 엔트리와 블록 사이 공간은 일반적으로 사용되지 않는 공간이기 때문이다.

 

만약 사용된다면 해시 트리에 사용될 것인데, 그마저도 모두 사용되지는 않고 첫 블록만 관리 데이터로 쓰여지고 나머지 블록들은 사용되지 않는 채로 남겨지게 된다.

 

파일 시스템의 여러 구조들을 보며 사용되지 않거나, 사용되지 않는 공간이나 슬랙 공간일 것으로 추측되는 공간들이 있었을 것이다.

 

이러한 공간에는 충분히 데이터가 숨겨져 있을 수 있으므로 한번쯤 분석해보는 것이 좋다. 


# Reference

 

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

[Digital Forensic] EXT 파일 시스템 (2)

 

EXT 파일 시스템


(13) 파일 생성 / 삭제

 

해당 시나리오에서 블록 크기는 1024Byte, 블록 그룹의 블록 개수는 8192개, 블록 그룹별 inode 개수는 2016개이다.

 

또 해당 시나리오에서는 inode 테이블 시작 블록이 5라고 가정하며, 루트 디렉토리 엔트리가 블록 260에 있다고 가정한다.

 

 

13-1. 파일 생성 과정

 

이 과정에서는 dir이라는 디렉토리가 있다고 가정, File.txt 파일을 생성한다는 가정 상황을 시나리오로 한다.

 

  • 일단 파일 시스템 1024byte 오프셋에 위치 하는 슈퍼 블록을 참조하여 블록 크기와 블록 그룹의 블록 개수, 블록 그룹 내의 inode 개수를 파악

  • 슈퍼 블록의 분석이 끝나면 그룹 기술자 테이블을 참조하며, 이 테이블은 각 블록 그룹의 레이아웃을 설명하며 블록 2 ~ 3에 위치

 

위 과정은 다음 [그림 1]과 같다.

 

[그림 1] 생성 과정 1

 

 

  • 파일을 생성할 디렉토리인 dir을 찾으려면 먼저 루트 디렉토리를 찾아야 함

  • 루트 디렉토리는 보통 inode 2를 사용하며, inode 2의 위치는 슈퍼 블록을 참조하여 파악해 둔 블록 그룹별 inode 개수를 이용하면 쉽게 위치를 파악할 수 있고, 해당 시나리오에서는 블록 그룹 0에 위치

  • 블록 그룹 0의 그룹 기술자 테이블을 참조하면 inode 테이블의 위치응 알려주는 엔트리가 있고 그 엔트리를 참조하면 inode 테이블의 위치를 파악할 수 있음

 

위 과정은 다음 [그림 2]와 같다.

 

[그림 2] 생성 과정 2

 

 

  • 블록 5에서 inode 테이블을 읽고, 두 번째 엔트리(inode 2)를 분석하면 루트 디렉토리의 디렉토리 엔트리가 어떤 블록에 위치하는지 알 수 있음

위 과정은 다음 [그림 3]과 같다.

 

[그림 3] 생성 과정 3

 

 

  • 블록 260의 디렉토리 엔트리를 읽고, 디렉토리 엔트리의 내용을 해석

  • 디렉토리 엔트리의 첫 번째와 두 번째 엔트리는 . 과 .. 을 위한 엔트리이고, 각 엔트리 레코드를 참고하여 다음 엔트리 위치를 파악

  • 엔트리 위치 파악이 모두 되었다면 dir 디렉토리를 검색

 

해당 시나리오에서는 inode 5444를 할당 받았다고 가정하며, 이 때 dir 디렉토리의 접근 시간은 업데이트 된다.

 

위 과정은 다음 [그림 4]와 같다.

 

[그림 4] 생성 과정 4

 

 

  • 이번에는 dir 디렉토리의 위치를 알아야 함

  • dir 디렉토리의 inode를 그룹별 inode 수로 나누면 어떤 블록 그룹에 위치하는지 알 수 있음

 

dir 디렉토리 inode(5444) / 슈퍼 블록에서 알아낸 블록 그룹별 inode 수(2016) = 2

 

 

dir 디렉토리는 계산 결과 블록 그룹 2에 위치하며, 또 블록 그룹 2의 그룹 기술자 테이블을 참조하여 inode 테이블이 어디에 위치하는지 알 수 있다.

 

이 시나리오에서는 블록 그룹 2의 inode 테이블이 17889 블록에서 시작한다고 가정한다.

 

 

  • inode 테이블을 읽고 inode 5444의 엔트리를 참조

  • 엔트리를 분석하면 dir 디렉토리의 디렉토리 엔트리가 어떤 블록에 위치하고 있는지 파악할 수 있음

  • 엔트리는 블록 그룹 0에서부터 계산해보면 알 수 있음

 

해당 시나리오에서는 dir 디렉토리의 디렉토리 엔트리가 블록 18556에 있다고 가정한다.

 

위 과정은 다음 [그림 5]와 같다.

 

[그림 5] 생성 과정 5

 

 

  • dir 디렉토리의 디렉토리 엔트리를 읽고 디렉토리 엔트리의 목록을 파악

  • 그 후 디렉토리에서 사용되고 있지 않은 공간을 찾음

  • 생성 할 파일이 필요 공간을 계산하면(고정 8byte + 파일 이름 길이(7byte), 4의 배수로 반올림) 총 16바이트가 필요

  • 만약 해당 디렉토리에 다른 파일이 있다면 파일 이름을 비교하여 그 파일들의 이름과 해당 파일의 이름 순서를 고려해 할당

 

이 때 디렉토리에는 수정 시간과 변경 시간이 업데이트된다.

 

그리고 .. 가 dir 디렉토리의 마지막이라고 가정한다.

 

 

  • 아직 파일이 완전히 생성된 것은 아님

  • 파일에 할당할 inode가 있어야 하는데 하드 디스크 헤더에 부담을 덜어주기 위해 Ext 파일 시스템은 부모와 동일한 그룹 블록에 inode를 할당

  • inode의 할당 상태를 관리하는 inode 비트맵을 찾기 위해 그룹 기술자 테이블을 참조

  • inode 비트맵을 찾아 참조하고 비할당 inode를 검색

  • 그 후 검색이 완료된 inode를 할당하기 위해 해당 inode 비트맵 값을 0에서 1로 변경

 

해당 시나리오에서는 inode 비트맵은 17880 블록에 존재하며, 비할당 inode는 inode 5576이 있다고 가정한다.

 

 

  • inode 테이블에 inode 5576을 초기화하고 타임스탬프 값을 현재 시간으로 업데이트

  • 또 링크 수는 디렉토리 엔트리 링크에 해당하는 1로 설정 (링크는 선으로 표시)

 

위 과정은 다음 [그림 6]과 같다.

 

[그림 6] 생성 과정 6

 

 

  • 이제 파일 내용을 저장하기 위한 블록을 할당해야 함

  • 블록의 할당 상태는 블록 비트맵에서 관리하는데 inode 비트맵을 찾았던 것처럼 그룹 기술자 테이블을 참조하여 블록 비트맵의 위치를 파악하고 비할당된 블록을 찾음

  • 검색이 완료되면 찾은 블록을 할당하기 위해 비트맵 값을 0에서 1로 변경

 

이 때 슈퍼 블록과 그룹 기술자 테이블에 있는 블록 개수 현황들이 업데이트 되며, 해당 시나리오에서는 블록 비트맵은 블록 17881에 위치하고, 할당 할 블록들은 총 5개이며, 20004 ~ 20007, 20010 블록이라고 가정한다.

 

할당이 되면 블록 포인터를 설정해야 하는데 블록 게수가 12개를 넘지 않으므로 직접 포인터로 설정되어 inode에 블록의 주소들이 저장된다.

 

위 과정은 [그림 7]과 같다.

 

[그림 7] 생성 과정 7

  • 파일 내용이 할당된 블록에 저장됨


13-2 파일 삭제

 

파일 삭제는 위 과정과 거의 동일하며 후반부 과정이 조금 다를 뿐이다.

 

위 생성 과정에서 다시 File.txt를 삭제한다고 하였을 때 다음과 같은 과정을 거친다.

 

  • dir 디렉토리의 디렉토리 엔트리를 찾고 그 내용을 분석하여 목록을 파악하는 과정까지는 동일

  • 그 후 File.txt를 삭제하게 되면 File.txt 파일 이전에 존재하는 .. 디렉토리 엔트리의 레코드 값이 증가되어 만약 File.txt를 삭제하게 되면 File.txt가 삭제되어 .. 가 마지막 디렉토리 엔트리라면 블록 끝을 가리키게 됨

 

해당 시나리오에서는 블록의 끝을 1500이라고 가정하고, 이때 dir 디렉토리의 수정 시간과 변경 시간이 업데이트 된다.

 

위 과정은 [그림 8]과 같다.

 

[그림 8] 삭제 과정 1

 

  • inode 테이블의 inode 5576은 파일이 삭제되었다는 것을 표시하기 위해 링크 값을 1에서 0으로 변경

위 과정은 다름 [그림 9]와 같다.

 

[그림 9] 삭제 과정 2

 

  • inode 5576의 할당 상태를 비할당 상태로 변경하기 위해 inode 비트맵의 inode 5576 비트맵을 1에서 0으로 변경

  • 이때 슈퍼 블록과 그룹 기술자 테이블에 있는 비할당 inode 개수 현황이 업데이트 됨

 

  • 또 할당된 파일 내용의 블록을 할당 해제하기 위해 해당 블록의 블록 비트맵 값을 1에서 0으로 변경

  • 블록 포인터 또한 inode에서 제거

  • 이때 해당 inode의 수정 시간, 변경 시간, 삭제 시간이 업데이트 됨

 

위 과정은 다음 [그림 10]과 같다.

 

[그림 10] 삭제 과정 3

 

위처럼 삭제된 후 inode나 블록이 재할당만 되지 않으면 다시 파일을 복구할 수 있다.


(14) 파일 복구

 

Ext 파일 시스템은 Ext4 파일 시스템까지 버전이 출시되어 있는데, Ext2와 Ext3의 파일 삭제 방식이 조금 달라 파일 복구 방법도 조금 다르다.

 

Ext2에서는 파일 복구가 대체로 수월한 편이며, 이유는 파일이 삭제될 때 inode에 블록 포인터 값이 지워지지 않고 계속 남아 있기 때문이다.

 

또 삭제 시간이 업데이트 되어 파일이 언제 삭제되었는지 안다면 그에 맞는 inode를 찾는 일은 좀 더 쉬워짐하지만 블록 포인터 값이 inode에 남아 있다고 하여 100% 해당 파일의 내용을 복구하는 것은 아니다.

 

inode가 가리키고 있는 블록이 재할당되면 그 내용은 전혀 다른 내용이 되기 때문이며, 또 디렉토리 엔트리와 inode의 연결은 영구적으로 삭제가 되서 삭제된 inode를 찾으려면 비할당 inode 엔트리를 검색해야 한다.

 

Ext3에서는 디렉토리 엔트리와 inode 연결이 삭제 되지 않지만, 블록 포인터가 삭제되기 때문에 카빙 기술을 이용하여 파일 복구를 시도해야 한다.

 

카빙을 시도할 때의 정보 수집 범위는 보통 같은 블록 내에 할당하기 때문에 블록 그룹 단위이지만 어떤 OS는 파일 시스템 전체를 할당 대상으로 하기 때문에 OS에 따라 그 정보 수집 범위를 달리해야 한다.

 

만약 파일이 최근에 삭제된 것을 알고 싶다면 저널을 분석하는 것이 좋으며, 이유는 inode의 복사본이 저널 블록에 포함되어 있을지도 모르기 때문이다.


(15) 데이터 구조

15-1. 슈퍼 블록

  • 슈퍼 블록의 파일 시스템에서 1024byte 오프셋에 위치하고, 그 크기 또한 1024byte

 

다음 표는 슈퍼 블록 오프셋 구조에 대한 내용이다.

 

[표 1] 슈퍼 블록 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

파일 시스템에 있는 inode 개수

76~79

주 버전

4~7

파일 시스템에 있는 블록 개수

80~81

예약 블록 사용 가능 UID

8~11

예약 블록 개수

82~83

예약 블록 사용 가능 GID

12~15

비할당 블록 개수

84~87

예약되지 않은 첫 번째 inode

16~19

비할당 inode 개수

88~89

inode 크기

20~23

블록 그룹 0 시작 블록

90~91

슈퍼 블록의 블록 그룹

24~27

블록 크기

92~95

호환성 가능 플래그

28~31

단편 크기

96~99

비호환성 기능 플래그

32~35

각 블록 그룹의 블록 개수

100~103

읽기 전용 속성 플래그

36~39

각 블록 그룹의 단편 개수

104~119

파일 시스템 ID

40~43

각 블록 그룹의 inode 개수

120~135

볼륨 이름

44~47

마지막 파일 시스템 마운트 시간

136~199

마지막 마운트 지점 경로

48~51

마지막 파일 시스템 수정 시간

200~203

비트맵 사용 알고리즘

52~53

파일 시스템 마운트 횟수

204~204

미리 할당된 블록 개수 (파일)

54~55

마운트 가능한 파일 시스템 최대 개수

205~205

미리 할당된 블록 개수 (디렉토리)

56~57

시그니처(0xEF53)

206~207

사용 X

58~59

파일 시스템 상태

208~223

저널 ID

60~61

오류 처리

224~227

저널 inode

62~63

부 버전

228~231

저널 장치

64~67

일관성 검사 간격

232~235

고아 inode 목록의 헤드

72~75

파일 시스템 생성 운영체제

236~1023

사용 X

 

블록 크기

  • 이 값은 직접적인 값이 아닌 간접적인 값

  • 1024를 해당 오프셋의 값만큼 왼쪽으로 쉬프트 연산하여 블록 크기를 구해야 함

 

단편 크기

  • 이 값 또한 블록 크기와 동일한 방법으로 구함

 

파일 시스템 상태

  • 0x0001 : 정상

  • 0x0002 : 오류

  • 0x0004 : 고아 inode 복수

 

오류 처리

  • 1 : 정상

  • 2 : 파일 시스템을 읽기 전용으로 다시 마운트해야 함

  • 3 : 패닉

 

파일 시스템 생성 운영체제

  • 0 : 리눅스

  • 1 : GNU hard

  • 2 : Masix

  • 3 : FreeBSD

  • 4 : Lites

 

주 버전

  • 파일 시스템의 버전을 나타내는 값

  • 일반 버전(0), 동적 버전(1) 두 가지 버전이 존재

  • 값이 1로 설정되어 있지 않으면 84byte 오프셋 앞에 있는 값들은 정확하지 않을 수 있음

 

호환성 기능 플래그

  • 0x0001 : 디렉토리 블록을 미리 할당 (단편화 예방)

  • 0x0002 : AFS 서버 inode 지원

  • 0x0004 : 파일 시스템 저널 지원 (Ext3)

  • 0x0008 : inode가 확장된 속성을 가짐

  • 0x0010 : 파티션 크기 다시 설정

  • 0x0020 : 디렉토리가 해시 인덱스를 사용

 

비호환성 기능 플래그

  • 0x0001 : 압축

  • 0x0002 : 디렉토리 엔트리가 파일 타입 필드를 포함

  • 0x0004 : 파일 시스템 복구 필요

  • 0x0008 : 저널 장치 사용

 

읽기 전용 속성 플래그

  • 0x0001 : Sparse 슈퍼 블록과 그룹 기술자 테이블

  • 0x0002 : 대용량 파일을 포함

  • 0x0004 : B-Tree 알고리즘 사용


15-2. 그룹 기술자 테이블

  • 파일 시스템 블록에 위치하는 그룹 기술자 그룹의 목록을 뜻함

  • 슈퍼 블록 다음 블록에 위치

  • 그룹 기술자 테이블의 엔트리는 각 블록 그룹의 정보를 가지고 있으며, 테이블의 크기는 32byte

 

테이블 파일 시스템 블록의 크기가 4096byte일때는 슈퍼 블록이 0에 위치하고, 그룹 기술자 테이블은 블록 1에 위치한다.

 

또 파일 시스템 블록의 크기가 1024byte 일때는 슈퍼 블록이 1에 위치하고, 그룹 기술자 테이블은 블록 2에 위치한다.

 

 

다음 표는 그룹 기술자 테이블 오프셋 구조에 대한 내용이다.

 

[표 2] 그룹 기술자 테이블 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

블록 비트맵 시작 블록 주소

14~15

그룹에 할당되지 않은 inode 개수

4~7

inode 비트맵 시작 블록 주소

16~17

그룹의 디렉토리 개수

8~11

inode 테이블 시작 블록 주소

18~31

사용 X

12~13

그룹에 할당되지 않은 블록 개수

   

 

블록 비트맵의 시작 블록 주소

  • 해당 오프셋의 값은 오프셋이 아니라 단순히 블록 번호에 불과

 

inode 비트맵의 시작 블록 주소

  • 블록 비트맵의 시작 블록 주소 오프셋과 의미가 동일


15-3. 블록 비트맵

  • 파일과 디렉토리의 내용이 저장되는 블록의 할당 상태를 관리하는 부분

  • 각 비트와 블록은 맵핑 관계

  • 시작 위치는 그룹 기술자 테이블에 정의되어 있음

 

[그림 11] 블록 비트맵 내용

 

각 바이트를 비트로 변환하면 할당 상태를 알 수 있다.


15-4. inode

  • inode 데이터 구조체는 파일이나 디렉토리의 메타 데이터를 저장

  • inode들은 각 블록 그룹에 위치하는 inode 테이블에 위치

  • inode 테이블 위치는 그룹 기술자 테이블에 정의되어 있고, 그룹별 inode 개수는 슈퍼 블록에 정의되어 있음

 

다음 표는 inode 오프셋 구조에 대한 내용이다.

 

[표 3] inode 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~1

파일 크기

88~91

단일 간접 블록 포인터

2~3

사용자 ID 하위 16bit

92~95

이중 간접 블록 포인터

4~7

파일 크기(byte)

96~99

삼중 간접 블록 포인터

8~11

접근 시간

100~103

생성 번호(NFS)

12~15

변경 시간

104~107

확장 속성 블록(파일 ACL)

16~19

수정 시간

108~111

크기 상위 32bit

20~23

삭제 시간

112~115

단편 블록 주소

24~25

그룹 ID 하위 16bit

116~116

블록 단편 인덱스

26~27

링크 개수

117~117

단편 크기

28~31

섹터 개수

118~119

사용 X

32~35

플래그

120~121

사용자 ID 상위 16bit

36~39

사용 X

122~123

그룹 ID 상위 16bit

40~87

직접 블록 포인터 (12개)

124~127

사용 X

 

기본적인 inode의 크기는 128byte이며, 만약 파일 시스템 버전이 동적 버전으로 설정되면 inode의 크기 또한 동적으로 변한다.

 

 

파일 모드

  • 타입과 허가권을 나타냄

  • 오프셋이 2byte 크기인데 bit로 변환하여 3개의 구역으로 나누어 플래그 값들이 설정

 

해당 오프셋의 값을 bit로 변환하여 구역을 나눈 모습을 다음 [그림 12]에서 볼 수 있다.

 

[그림 12] 파일 모드의 bit 구역

 

각 구역에는 다음 목록과 같은 플래그 값이 2진수로 변환되어 들어갈 수 있다.

 

[표 4] 접근 권한 플래그 목록

설명

설명

0x001

기타 사용자 - 실행 권한

0x020

그룹 - 읽기 권한

0x002

기타 사용자 - 쓰기 권한

0x040

사용자 - 실행 권한

0x004

기타 사용자 - 읽기 권한

0x080

사용자 - 쓰기 권한

0x008

그룹 - 실행 권한

0x100

사용자 - 읽기 권한

0x010

그룹 - 쓰기 권한

   

 

계산은 간단하다.

 

[그림 12]에 나와 있는 값을 예로 들어보자.

 

값을 각 자리 별로 분리하여 hex로 변환 후 플래그 목록 값에서 해당하는 값을 찾으면 된다.

 

만약 리눅스의 권한을 숙지하였다면, 해당 2진수 값을 8진수로 변환하여 권한을 바로 파악하는 것도 좋다. (110100100 > 644)

 

  • 110100100 > 100000000, 10000000, 100000, 100

  • 100000000 > 0x100 > 사용자 - 읽기 권한

  • 10000000 > 0x80 > 사용자 - 쓰기 권한

  • 100000 > 0x20 > 그룹 - 읽기 권한

  • 100 > 기타 사용자 - 읽기 권한

 

[표 5] 실행 속성 플래그 목록

설명

0x200

Sticky bit

0x400

Set GID

0x800

Set UID

 

[표 6] inode 파일 타입 플래그 목록

설명

설명

0x1000

FIFO

0x8000

일반 파일

0x2000

문자 장치

0xA000

심볼릭 링크

0x4000

디렉토리

0xC000

유닉스 소켓

0x6000

블록 장치

   

 

타임스탬프(접근, 변경, 수정, 삭제 시간)

  • 해당 오프셋 값들은 UTC 1970년 1월 1일을 기준으로 현재 시간까지의 초 값

  • 이 값들은 2038년 1월부터는 계산이 불가능

 

플래그

  • inode가 할당된 파일에 설정되어 있는 속성들을 표시한  오프셋 필드

 

다음 표는 inode 플래그 목록에 대한 내용이다.

 

[표 7] inode 플래그 목록

설명

0x00000008

동시 업데이트(업데이트 데이터를 디스크에 바로 씀)

0x00000010

고정 파일(내용 수정 불가)

0x00000020

덮어쓰기 불가, 이어쓰기 가능

0x00000040

Dump 불가능 파일

0x00001000

해시 트리 사용 디렉토리

0x00002000

저널링(Ext3)


15-5. 확장 속성

  • Ext 파일 시스템에서 파일이나 디렉토리에 존재

  • 우리가 흔히 알고 있는 권한도 확장 속성에 해당

  • 확장 속성 또한 다른 영역들과 마찬가지로 구조체 형식으로 정의되어 있음

 

확장 속성은 기본적으로 다음의 3가지 영역으로 나누어져 있다.

  • 헤더 영역

  • 이름 엔트리 영역

  • 데이터 영역

헤더 영역 다음에 이름 엔트리 영역이 오는데 일반적으로 영역들은 붙어 있지만, 데이터 영역은 나머지 두 영역과 다르게 블록 마지막에 존재하여 두 영역과 붙어 있지 않다.

 

더군다나 데이터 영역은 블록 마지막에서 블록 처음을 향하여 데이터가 점차 쌓인다.

 

데이터 영역에 있는 데이터들은 속성에 이름 엔트리와 대응되는 데이터들이지만, 이름 엔트리 순서와 데이터 순서가 동일하게 매칭되는 것은 아니다.

 

 

헤더 영역

  • 확장 속성의 헤더 영역은 32byte 크기

  • 시그니처를 가지고 있고 블록의 0byte 오프셋부터 시작

 

다음 표는 헤더 영역 오프셋 구조에 대한 내용이다.

 

[표 8] 헤더 영역 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

시그니처(0xEA020000)

12~15

해시 값

4~7

참고 횟수

16~31

예약 영역

8~11

블록 개수

   

 

  • 참고 횟수 : 확장 속서의 블록은 여러 파일이나 디렉토리에 공유되어 참고 카운트는 해당 블록을 공유 받아 사용 중인 블록이 몇 개인지 판별해 주는 필드

  • 블록 개수 : 확장 속성을 가진 블록이 몇 개의 확장 속성을 가졌는지 판별해 주는 필드 (현재까지는 사용되지 않음)

  • 해시 값 : 중복 속성을 구별할 때 사용되는 해시 값

 

 

이름 엔트리 영역

  • 헤더 영역 바로 다음에 위치

  • 이름 엔트리와 매칭되는 데이터의 정보와 이름 정보가 포함되어 있음

 

다음 표는 이름 엔트리 오프셋 구조에 대한 내용이다.

 

[표 9] 이름 엔트리 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~0

이름 길이

8~11

데이터 크기

1~1

속성 타입

12~15

데이터 해시

2~3

데이터의 위치 오프셋

16~

이름(ASCII)

4~7

데이터가 포함되어 있는 블록 위치

   

 

 

속성 타입

  • 1 : 사용자 공간 속성

  • 2 : POSIX ACL

  • 3 : POSIX ACL 기본

  • 4 : 신뢰성이 있는 공간 속성

  • 5 : LUSTRE

  • 6 : 보안 공간 속성 

 

값 중 3이라는 값을 가지는 속성은 디렉토리에만 해당하며, 5라는 값을 가지는 속성은 현재 리눅스에서는 사용되지 않고 있다.

 

POSIX ACL 속성은 헤더와 엔트리로 구성되어 있다.

 

 

[표 10] POSIX ACL 헤더 오프셋 구조

범위(Byte)

설명

0~3

버전

 

[표 11] POSIX ACL 엔트리 오프셋 구조

범위(Byte)

설명

0~1

타입

2~3

접근 권한

4~7

사용자 / 그룹 ID

 

POSIX ACL 엔트리의 첫 번째 오프셋인 타입 필드는 POSIX ACL 속성이 설정된 엔트리의 허가된 종류를 의미한다.

 

POSIX ACL 허가 타입 목록은 다음과 같다.

  • 0x01 : 사용자 - inode에서 지정

  • 0x02 : 사용자 - 속성에서 지정

  • 0x04 : 그룹 - inode에서 지정

  • 0x08 : 그룹 - 속성에서 지정

  • 0x10 : 효과적인 권한 마스크

  • 0x20 : 기타

 

0x01, 0x04, 0x20의 경우 inode에서 복사된 정보들이다.

 

그렇기에 따로 접근 권한을 설정해 줄 필요가 없다.

 

나머지 값들의 접근 권한 플래그는 엔트리 목록에 있는 필드 중 접근 권한 필드에서 설정해 주어야 한다.

 

접근 권한 필드의 플래그 목록은 다음과 같다.

  • 0x01 : 실행

  • 0x02 : 쓰기

  • 0x03 : 읽기

 

데이터의 위치 오프셋

  • 해당 이름 엔트리와 대응 되는 데이터의 오프셋 위치 

 

데이터가 포함되어 있는 블록 위치

  • 해당 이름 엔트리와 대응 되는 데이터의 블록 위치

  • 현재 리눅스에서는 하나의 블록만 사용하기 때문에 해당 필드에 설정 되어 있지 않을 수도 있음

 

데이터 크기

  • 해당 엔트리와 대응 되는 데이터의 크기


15-6.디렉토리 엔트리

  • 파일이나 디렉토리의 이름을 저장하고, 파일이나 디렉토리에 할당된 inode의 주소를 저장

  • 자신과 맵핑 관계인 디렉토리에 할당 된 블록에 위치

  • 디렉토리 엔트리 데이터 구조에는 두 가지 유형이 존재

  • 하지만 이 두 유형의 크기는 동일하며 차이점은 파일 타입의 유무

  • 디렉토리 엔트리에 어떤 유형이 사용되는지는 슈퍼 블록에서 정의

  • 현재는 파일 타입 필드가 포함된 디렉토리 엔트리 유형을 사용

 

먼저 파일 타입이 없는 데이터 구조를 확인해보자.

 

[표 12] 예전에 사용되었던 디렉토리 엔트리 오프셋 구조

범위(Byte)

설명

0~3

inode 번호

4~5

해당 엔트리 길이

6~7

이름 길이

8~

이름 (ASCII)

 

[표 13] 현재 사용 중인 디렉토리 엔트리 오프셋 구조

범위(Byte)

설명

0~3

inode 번호

4~5

해당 엔트리 길이

6~6

이름 길이

7~7

파일 타입

8~

이름 (ASCII)

 

inode 번호

  • 우리가 흔히 보는 inode 번호를 나타냄

 

해당 엔트리 길이

  • 해당 구조체를 포함하고 있는 엔트리 길이

 

이름 길이

  • 해당 디렉토리 엔트리가 할당된 파일(디렉토리)의 이름 길이

 

이름

  • 이름 길이에 따라 이름 필드의 크기는 달라짐

 

파일 타입

  • 해당 디렉토리 엔트리가 할당된 것이 파일인지 디렉토리인지를 구분하여 주는 필드

 

파일 타입은 다음과 같은 목록 갑들에 따라 구분

  • 0 : 정의되지 않은 타입

  • 1 : 정규 파일

  • 2 : 디렉토리

  • 3 : 문자 장치

  • 4 : 블록 장치

  • 5 : FIFO

  • 6 : 유닉스 소켓

  • 7 : 심볼릭 링크

 

두 번째 디렉토리 엔트리들을 찾으려면 해당 엔트리의 크기를 해당 디렉토리 시작 오프셋에서 더하면 두 번째 디렉토리 엔트리를 찾을 수 있다.

 

이러한 식으로 계속 다음 디렉토리 엔트리를 찾으면 되는데 만약 디렉토리 엔트리 크기가 이름 길이에 비해 볼 필요할 정도로 크다면 그 디렉토리 엔트리와 다음 디렉토리 엔트리 사이에 파일이 삭제되었음을 의미한다.


15-7. 해시 트리

  • Ext 파일 시스템에서 디렉토리의 엔트리들을 정렬하기 위해 사용하는 알고리즘

  • 각 노드는 디렉토리의 각 블록

  • 노드에는 노드 기술자라는 데이터 구조체가 있는데 노드 기술자는 다음 계층의 블록을 알려주는 역할을 함

  • 노드 기술자는 헤더와 엔트리로 나누어 지는데, 헤더는 디렉토리 엔트리 다음에 위치

 

다음 표는 노드 기술자 헤더 오프셋 구조에 대한 내용이다.

 

[표 14] 노드 기술자 헤더 오프셋 구조

범위(Byte)

설명

0~3

사용 X

4~4

해당 버전

5~5

해당 구조체 길이

6~6

리프(leaf) 레벨

7~7

사용 X

 

노드 기술자 엔트리는 노드의 해시 값 중 가장 작은 해시 값과 노드의 디렉토리 블록을 저장하고 있다.

 

[표 15] 노드 기술자 엔트리 오프셋 구조

범위(Byte)

설명

0~3

노드의 가장 작은 해시 값

4~7

블록 주소

 

첫 번째 노드 기술자 엔트리의 경우 최소 해시 값이 0이어야만 해서 해시 값이 설정되지 않는다.

 

이러한 이유로 첫 번째 노드 기술자 엔트리의 구조는 [표 15]와 조금 다른데 그 형태는 [표 16]과 같다.

 

[표 16] 첫 번째 노드 기술자 엔트리 오프셋 구조

범위(Byte)

설명

0~1

노드 기술자 최대 번호

2~3

노드 기술자 번호

4~7

첫 번째 노드의 블록 위치

 

저널

  • 저널링은 파일 시스템이 손상되었을 때 복구를 하기 위하여 평상시에 메타데이터 업데이트 사항을 기록해 두는 기술

  • Ext3 파일 시스템에는 저널을 위한 4개의 블록이 존재

  • 저널 슈퍼 블록, 기술자 블록, 적용 블록, 취소 블록이 4가지 블록에 해당

  • 이 4개의 블록의 데이터 구조체는 모두 동일한 헤더를 가짐

 

다음 표는 저널 블록들의 표준 헤더 오프셋 구조에 대한 내용이다.

 

[표 17] 저널 블록들의 표준 헤더 오프셋 구조

범위(Byte)

설명

0~3

시그니처(0xC03b3998)

4~7

블록 타입

8~11

순서 번호

 

블록 타입 (4개의 블록들을 구분하는데 사용)

  • 1 : 기술자 블록

  • 2 : 적용 블록

  • 3 : 슈퍼 블록 버전 1

  • 4 : 슈퍼 블록 버전 2

  • 5 : 취소 블록

 

블록 타입이 기술자 블록 값을 가지면 해당 저널 블록은 다음 표와 같은 구조를 가진다.

 

[표 18] 기술자 블록 오프셋

범위(Byte)

설명

범위(Byte)

설명

0~11

표준 헤더

16~19

엔트리 플래그

12~15

파일 시스템 블록

20~35

UUID

 

엔트리 플래그 (어떤 상태인지를 나타내주는 플래그)

  • 0x01 : 저널 블록 취소

  • 0x02 : 엔트리는 이전 UUID를 보유

  • 0x04 : 이번 트랜젝션으로 블록이 삭제

  • 0x08 : 기술자 블록의 마지막 엔트리

 

기술자 블록의 20~35 오프셋 필드인 UUID는 SAME_UUID 플래그가 설정되지 않으면 존재하지 않는 필드이다.

 

엔트리 플래그의 UUID 또한 마찬가지이며, 엔트리 플래그의 트랜젝션 블록 삭제 플래그는 현재 사용되지 않고 있다.

 

슈퍼 블록 버전 1과 2는 구조가 조금 다르기 때문에 값 또한 다른 것이다.

 

버전 1과 2는 다음과 같은 공통 구조체를 가진다.

 

[표 19] 슈퍼 블록 버전 1과 2의 공통 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~11

표준 헤더

24~27

첫 번째 트랜젝션 순서 번호

12~15

저널 블록 크기

28~31

첫 번째 트랜젝션 저널 블록

16~19

저널 블록 개수

32~35

오류 번호

20~23

저널의 실제 시작위치 블록

   

 

버전 1이라면 [표 19]의 36byte만 사용하지만, 버전 2일 경우 추가적인 오프셋 구조를 가진다.

 

추가적인 오프셋 구조는 [표 20]과 같다.

 

[표 20] 버전 2일 경우의 사용하는 추가적인 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

36~39

호환 기능

68~71

슈퍼 블록 복사본 위치

40~43

비호환 기능

72~75

트랜젝션별 저널 블록 최대 개수

44~47

읽기 전용 호환 기능

76~79

트랜젝션별 파일 시스템 블록 최대 개수

48~63

저널 GUID

80~255

사용 X

64~67

저널을 사용하는 파일 시스템 개수

256~1023

저널을 사용하는 파일 시스템 ID(16byte)

 

취소 블록은 포쥰 헤더를 기본적으로 가지고 있고, 독자적인 정보로는 취소된 파일 시스템 블록들의 목록을 가지고 있다.

 

취소 블록의 구조는 다음과 같다.

 

[표 21] 취소 블록의 오프셋 구조

범위(Byte)

설명

0~11

표준 헤더

12~15

취소 데이터의 크기(Byte)

16~

파일 시스템 블록 주소(4Byte) 목록


# Reference

 

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

[Digital Forensic] EXT 파일 시스템 (1)

 

EXT 파일 시스템


(1) EXT 파일 시스템?

  • Minix라는 리눅스 초기 파일 시스템의 문제점 해결을 위해 고안된 파일 시스템

  • UFS(Unix File System)을 기초로 만들어져, 현재 Ext 4까지 업데이트 됨

  • UFS에서 쓸모 없는 기능들을 제외하여 구조를 이해하는데 어려움은 크게 줄음

  • 파일과 관련된 모든 데이터들을 한 곳에 모아 두어 하드 디스크 헤드가 데이터를 읽을 때 불필요한 동작을 하지 않도록 설계

 

1-1. Ext 레이아웃

 

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

 

[그림 1] Ext 파일 시스템 레이아웃

 

위 [그림 1]을 보듯이 구조는 간단하다.

 

블록 그룹들의 개수는 시스템 환경에 따라 달라지지만, 마지막 블록 그룹을 제외한 나머지 블록 그룹들은 같은 블록 수를 가진다.

 

블록 그룹에는 Super Block, Inode Table 등이 존재한다.

 

 

1) Super Block (Block 1개의 크기)

  • Block의 크기 (1KB, 2KB, 4KB)

  • 블록 총 개수

  • 블록 그룹 개수

  • Inode 개수

  • 블록 그룹 내의 블록 / Inode 개수

 

Super Block은 블록 크기가 2KB, 4KB이어도 고정적으로 1KB만 사용한다.

 

즉, 4KB의 블록을 할당 받아도 3KB는 쓰지 않는다.

 

 

2) Inode Table

  • inode라는 데이터 구조체를 포함하고 있는 테이블

  • 각 블록 그룹에 1개씩만 존재

 

3) inode

  • 파일과 디렉토리의 메타데이터를 포함하는 데이터 구조체

  • 고정된 크기를 가짐

 

[그림 2] 블록 내의 관계

 

디렉토리 엔트리는 파일 이름과 파일 inode 포인터를 포함하는 데이터 구조체이다.


(2) 기능

 

 

Ext에는 여러 가지 기능이 존재한다.

 

이 중 주의깊게 보아야 할 기술은 호환성 기능이다.

 

2-1. 호환 기능

  • 마운트 하려는 파일 시스템에 저널링, 확장 속성 등 운영체제에서 지원하지 않는 기능이 있더라도 해당 파일 시스템을 마운트하는 기능

 

2-2. 비호환 기능

  • 마운트 하려는 파일 시스템에 압축, 암호 등 기능이 포함되어 있으면 해당 파일 시스템을 마운트하지 않는 기능

 

2-3. 읽기 전용 호환 기능

  • 비호환 기능처럼 운영체제가 지원하지 않는 기능을 가진 파일 시스템을 강제적으로 마운트 한다면 읽기 전용으로 마운트하는 기능


(3) 슈퍼 블록

  • 파일 시스템의 시작(부트 섹터 제외)으로 부터 1024Byte에 위치

  • 크기는 1024Byte이지만 실제로는 이보다 조금 더 작음

  • 설정 값만 포함하고 있고 부트 코드는 포함하고 있지 않음

  • 복사본은 보통 블록 그룹의 첫 블록(슈퍼 블록)에 저장 

 

슈퍼 블록에 저장되는 정보는 다음과 같다.

 

  • 각 블록의 크기

  • 전체 블록의 수

  • 블록 그룹별 블록 개수

  • 예약 블록 수

  • inode 전체 개수

  • 블록 그룹별 inode 개수

  • 볼륨 이름

  • 마지막 수정 시간

  • 마지막 마운트 시간

  • 마지막 마운트 경로

  • 무결성 식별 실행 여부 값

 

많은 정보들이 포함되어 있지만 마지막 수정 시간부터의 값들은 부가적 데이터이다.

 

또 슈퍼 블록은 비 사용중인 inode 블록들의 전체 개수에 대한 데이터를 기록하기도 하는데 이것의 이유는 inode와 블록들을 할당할 때 참고하기 위해서다.

 

슈퍼 블록에는 앞 글에서 설명한 세 가지의 호환성 기능 말고도 sparse 슈퍼 블록 기능이라고 있는데 이 기능에 대해서 다음과 같이 설명할 수 있다.

 

 

스파스 슈퍼 블록

  • 해당 기능은 기본적으로 Ext 파일 시스템이 리눅스에 생성될 때 활성화 되어 있는 기능

  • 슈퍼 블록과 그룹 기술자 테이블의 복사본을 일부 블록 그룹에 포함되도록 함

  • 이 기능으로 인해 파일 시스템의 시작 위치를 판별하는데 어려움이 생길 수 있음

  • 슈퍼 블록 볼륨 레이블이라는 것이 존재하는데, 이것은 파일 시스템을 구분하기 위해 사용


(4) 그룹 기술자 테이블 블록

  • 슈퍼 블록 다음으로 오는 블록

  • 해당 테이블의 복사본은 sparse 슈퍼 블록 기능이 활성화되어 있지 않으면 각 블록 그룹에 존재하게 됨

  • 해당 테이블에는 파일 내용 이외에 슈퍼 블록, 그룹 기술자 그룹, inode 테이블, inode 비트맵, 블록 비트맵의 설정 데이터에 대한 정보들이 포함되어 있음


(5) 부트 코드

  • 슈퍼 블록 이전에 위치

  • 크기는 1024Byte

  • 즉 MBR 영역과 첫 번째 블록 그룹의 슈퍼 블록 영역 사이에 존재하는 것


(6) 블록

  • Ext 파일 시스템의 블록은 NTFS와 FAT 파일 시스템의 클러스터와 아주 유사한 개념

  • 보통 1024, 2048, 4096 Byte의 크기를 가짐

  • 모든 블록에는 주소가 주어지며, 모든 블록들은 블록 그룹에 속해야만 함

  • 예약 영역(부트 섹터와 부트 코드가 있는 영역)의 블록들은 블록 그룹에 속하지 않음

어떤 그룹에 속한 블록인지를 결정하기 위해서는 다음과 같은 계산을 수행해야 한다.

 

 

그룹 = (해당 블록 - 첫 번째 데이터 블록) / 그룹별 블록 수

 

 

블록 할당

  • 각 블록 그룹에 존재하는 블록 비트맵에 의해서 결정

  • 위치는 그룹 기술자 테이블에 정의되어 있음

  • 블록 비트맵 내용은 비트로 구성되어 있는데 이 비트는 각 블록과 맵핑 관계

  • 어떠한 특정 비트가 어떠한 블록과 맵핑 관계에 있는지 확인하려면 블록 비트맵이 포함되어 있는 블록 그룹의 시작에서 확인하고자 하는 블록의 상대적 주소를 계산해야 함

상대적 주소를 계산하려면 블록 그룹의 첫 번째 블록을 확인해야 하는데 확인 방법은 다음 계산식을 수행하면 된다.

 

 

첫 번째 블록 = 블록 그룹 x 그룹별 블록 수 + 첫 번째 데이터 블록

 

 

Ext 파일 시스템은 관리 목적으로 파일 시스템에 할당된 많은 블록들이 있는데 이 블록들 때문에 NTFS처럼 파일에 모든 블록을 할당하지 않는다.

 

관리 목적으로 파일 시스템 할당된 블록들은 다음과 같은 것들이 있다.

 

  • 슈퍼 블록

  • 그룹 기술자 테이블

  • 블록과 inode의 비트맵 블록

  • inode 테이블


(7) inode

  • Ext 파일 시스템의 메타데이터들은 모두 inode에 저장

  • Ext 파일 시스템에서 inode는 모두 동일한 크기를 가지며, 슈퍼 블록에 정의

  • inode Table이라는 집합체에 저장되어 있음

  • 이 테이블은 각 블록 그룹에 존재하며 크기는 슈퍼 블록에 정의되어 있음

  • inode 테이블 위치는 그룹 기술자 테이블에서 정해줌

 

보통 inode의 1 ~ 10번은 예약되어 있고, 할당 된 상태이다.

 

슈퍼 블록은 이런 예약 inode들을 제외한 첫 번째 inode를 값으로 가지고 있다.

 

각 inode 필드 중에는 고정된 번호를 가지는 필드가 있고 추가 정보로는 확장 속성과 간접 블록 포인터가 있다.

 

또 inode의 할당 상태는 각 그룹에 존재하는 inode 비트맵이 결정한다.

 

 

소유권

  • 해당 정보는 사용자, 그룹 ID로 인해 저장

  • 유닉스에서는 모든 사용자에게 ID를 할당하고 사용자 ID를 사용자 이름으로 변화하는데 /etc/passwd 파일을 사용

  • inode에 사용자 ID는 chown 등의 명령어를 통해 충분히 변경 가능하기 때문에 해당 사용자가 해당 파일을 생성 했다고 전적으로 신뢰하여서는 안 됨

 

타임스탬프

  • inode는 일시적인 정보로 타임스탬프 값을 가짐

  • 한 가지 특이한 점은 기존의 타임스탬프라고 하면 변경, 수정, 접근 시간이 있는데 inode는 여기에 삭제 시간까지 포함

  • 타임스탬프 값은 1970년 1월 1일 UTC를 시작으로 현재 시간까지 경과된 초를 값으로 가짐

  • 하지만 타임스탬프 정보 또한 전적으로 신뢰하여서는 안 됨

  • 이유는 Touch 명령어로 수정이 가능하기 때문

 

모드 필드

  • 파일 타입, 기본 허가권 등의 값이 포함

  • 유닉스에서는 모든 것이 파일로 취급되는데 그 취급되는 유형에는 무수히 많은 유형들이 있음

  • 파일 타입은 이러한 유형들을 말하는 것

  • 기본 허가권은 퍼미션(Permission)에 해당하는 것으로, 이는 운영체제가 다루는 데이터가 아닌 사용자가 다루는 데이터이므로 부가 데이터에 속함

  • 모드 필드는 파일이나 디렉토리가 갖는 특별한 속성을 포함하고 있음

  • 'sticky bit'라는 것이며, 해당 속성이 파일이나 디렉토리에 설정되면 오직 소유주만이 파일이나 디렉토리의 내용을 지울 수 있음

그리고 SUID, GUID라고 하는 것도 있으며, 이 두 가지 속성은 권한이 없는 사용자가 특정 권한을 가지고 프로그램을 실행토록 하는 권한이다.

 

 

링크 카운트

  • 링크 카운트 값은 inode를 가리키는 파일 이름의 개수를 뜻함

 

블록 포인터

  • inode에는 파일에 할당할 12개의 블록 주소가 저장되어 있는데 이것들을 직접 포인터라고 부름

  • 하지만 요즘은 파일 용량이 커져 12개의 블록 가지고는 부족할 때가 있음

  • 이럴 때 하나의 블록을 나머지 블록들의 주소를 저장할 공간으로 할당하여 해당 블록에 나머지 블록들의 주소를 저장하며, 이를 간접 포인터라고 함

  • 만약 간접 포인터를 사용하고도 블록이 더 필요하면 직접 포인터와 간접 포인터를 혼합한 이중 간접 포인터를 사용해야 함

  • 또 더 많은 공간이 필요하다면 삼중 간접 포인터를 사용해야 함

 

[그림 3] inode 포인터

 

파일을 강제로 특정 크기를 갖게 끔 생성하거나 블록 내용이 모두 0일 때는 스파스 블록이라고 부른다.

 

스파스 블록에는 어떠한 데이터도 쓸 수 없으며, 스파스 블록이 블록 포인터에 포함될 경우 블록 주소가 0으로 표시된다.

 

 

타임 스탬프 업데이트

 

 

Ext에는 4개의 시간 값이 있으며, 각 시간 값이 언제 업데이트 되는지 알아보도록 하자.

 

대부분의 지워진 파일들은 수정 시간, 변경 시간, 삭제 시간이 동일하다.

 

 

1) 접근 시간

  • 파일이나 디렉토리 내용을 읽을 때 업데이트 됨

  • 복사, 새로운 볼륨으로 이동할 때에도 업데이트 됨

2) 수정 시간

  • 파일이나 디렉토리 내용이 변경될 때 업데이트

  • 복사할 때에도 결국 새로운 파일 내용을 생성하는 경우가 되어 현재 시간으로 업데이트 됨

  • 또 네트워크로 전송할 때에도 네트워크에서 전송받는 시스템의 현재 시간으로 업데이트 됨

3) 변경 시간

  • 파일이나 디렉토리의 메타데이터가 변경될 때 업데이트 됨

  • 예를 들어 파일이나 디렉토리 생성, 퍼미션 변경, 소유권 변경 등의 정보가 변경될 때 업데이트 됨

4) 삭제 시간

  • 파일이 삭제될 때 업데이트 됨

  • 이 시간 값은 inode가 새롭게 할당 되면 삭제


(8) 디렉토리 엔트리

  • Ext 파일 시스템에서는 파일과 디렉토리의 구분을 inode에 있는 특별한 타입 값으로 구분 지음

  • 디렉토리들은 디렉토리 엔트리 데이터 구조체의 목록을 포함하는 블록들을 할당받게 됨

  • 디렉토리 엔트리는 파일 이름과  메타데이터가 어디 있는지 설명하는 데이터 구조체

모든 디렉토리는 자신과 부모를 나타내는 . 과 .. 디렉토리 엔트리를 포함하고 또 이 두 개를 엔트리 시작으로 삼는다.

 

. 과 .. 다음으로는 디렉토리 내의 파일과 하위 디렉토리의 엔트리들이다.

 

모든 파일 이름은 동적이어서 디렉토리 엔트리의 길이 또한 동적이다.

 

이러한 이유로 디렉토리 엔트리에는 이름 길이를 식별하는 디렉토리 엔트리 레코드 값이 존재한다.

 

디렉토리 엔트리의 길이는 이름 이외에 고정된 8Byte가 있어 4의 배수로 반올림 된 레코드 값과 8Byte를 더하여 결정한다.

 

레코드 값은 이름의 길이만큼 값이 주어져 다음 디렉토리 엔트리의 위치를 판별하는데 사용될 수 있다.

 

[그림 4] 디렉토리 엔트리 기본

 

마지막 디렉토리 엔트리의 레코드 값은 블록의 마지막을 가리키며, 마지막 디렉토리 엔트리 이후의 공간은 비할당 공간으로 남겨 둔다.

 

[그림 4]의 경우 이름 길이대로 레코드 값이 설정되어 다음 디렉토리 엔트리 바로 앞을 가리키고 있다.

 

하지만 파일이 삭제되면 파일의 이름이 변경되는데 운영체제는 그러한 파일을 화면상으로 출력하지 못한다.

 

또 운영체제는 삭제 파일 이전의 디렉토리 엔트리의 레코드 값을 삭제 파일 다음 디렉토리 엔트리가 위치한 곳까지의 거리로 값을 증가시켜 삭제된 파일을 숨긴다.

 

하지만 말 그대로 숨겼을 뿐 데아터는 지워지지 않아 복구가 가능하다.

 

[그림 5] 파일을 삭제한 경우

 

[그림 5[의 경우 file2.txt를 삭제한 경우인데 이렇게 하면 사용자는 파일이 지워진 것으로 인식하게 될 것이다.

 

하지만 데이터는 그대로 블록에 남아 있다.

 

만약 이름의 길이와 레코드의 길이를 비교했을 때 레코드의 길이가 필요 이상으로 크다면 현재 디렉토리 엔트리와 다음 디렉토리 엔트리 사이에 파일이 존재했던 것으로 볼 수 있다.


(9) 링크

  • Ext 파일 시스템에서 제공하는 링크는 하드 링크와 소프트 링크가 있음

  • 하드 링크는 같은 파일 시스템에 있는 파일이나 디렉토리에 추가적인 이름을 정의하는 것

  • 소프트 링크는 다른 파일 시스템에 있는 파일이나 디렉토리에 추가적인 이름을 정의하는 것

  • 하드 링크는 링크가 생성되면 원본 이름인지 링크 이름인지 구분할 수 없는 특징이 있음 

[그림 6] 하드 링크

 

[그림 6]처럼 원본 inode를 하드 링크가 같이 가리키고 있기 때문에 같은 파일 시스템에 존재해야 하며 또 원본 파일 이름이 어떤 것인지 구분할 수 없는 것이다. (하드 링크가 모두 해제 되지 않는 이상 파일은 삭제되지 않음)

 

소프트 링크는 심볼릭 링크 파일 타입으로 인해 생성된다.

 

파일이 하나 생성되었기 때문에 소프트 링크 파일만의 inode가 존재하며 해당 inode의 블록 또한 할당된다.

 

소프트 링크 파일이 가리키고자 하는 파일의 전체 경로가 60 글자를 넘지 않으면 목적 파일이나 목적 디렉토리의 전체 경로는 소프트 링크 파일에 할당된 inode나 블록에 저장된다.

 

 

소프트 링크 파일의 블록은 블록 포인터로서 목적 파일을 가리키게 되는데 이와 같은 과정은 다음과 같다.

 

[그림 7] 소프트 링크


(10) 마운트

  • 디렉토리들은 파일과 볼륨을 마운트하는데 사용될 수 있음

  • 어떠한 파일 시스템이 디렉토리에 마운트되면 해당 디렉토리가 가지고 있던 파일들은 보이지 않게 됨

  • 이 방법은 파일을 숨기는데 사용될 수 있음

[그림 8] 마운트


(11) 해시 트리

  • NTFS의 b-tree와 비슷한 개념

  • 그 정렬 기준이 파일 이름이 아닌 해시 값

  • 파일 시스템이 생성될 때 사용자에 따라 사용 여부가 달라짐

  • 만약 사용자가 사용하낟고 설정하면 슈퍼 블록에서 호환 플래그 기능을 설정해 줌

  • 해시 트리를 사용하게 되면 블록은 트리 구조에서 노드가 되며 그 노드는 각 파일들을 포함하게 됨

Ext 파일 시스템에도 b-tree가 있지만 아직 표준은 아니다.


(12) 저널링

  • 파일 시스템의 손상을 대비하여 복구를 위해 파일 시스템의 변경 사항을 기록해 두는 기능

  • Ext에서 저널은 슈퍼 블록에서 그 위치를 지정하여 주기 때문에 파일 시스템 어느 곳이든 위치할 수 있지만 보통 inode 8을 사용

슈퍼 블록에는 저널을 위한 호환 설정 필드가 있는데 이 값을 어떻게 설정하는가에 따라 로컬 저널 기능의 활용 여부를 결정할 수 있다.

 

만약 로컬 저널 기능을 비활성화로 설정하면 외부 저널을 사용할 수 있다.

 

하지만, 이 저널의 데이터는 로컬에 저장되지 않으며, 저널에는 두 가지 동작 모드가 있다.

 

첫 번째로는 메타 데이터의 업데이트만을 기록하는 모드이고, 두 번째는 파일 시스템의 모든 업데이트를 기록하는 모드이다.

 

그리고 메타데이터 업데이트만을 기록하는 모드가 바로 default 이다.

 

 

Ext3의 저널링은 블록 수준에서 수행되는데 만약 어떠한 inode가 1비트 변경된다면 해당 inode를 포함하고 있는 블록 모두 저널에 업데이트된다.

 

저널의 첫 번째 블록은 슈퍼 블록은 위한 것이며, 전체적인 정보를 저장하는데 사용된다.

 

그 뒤로 이어지는 블록들은 저널 엔트리를 위해 사용되고 만약 저널 업데이트가 마지막 블록까지 진행되었다면 다시 처음 블록으로 돌아온다. (저널의 블록 크기는 파일 시스템 블록 크기와 동일)

 

 

업데이트는 하나의 묶음을 기준으로 처리되는데, 각 묶음은 순서 번호를 가지고 있다.

 

이 순서 번호는 같은 블록에 대해서는 동일하다.

 

각 묶음은 기술자 블록을 시작으로 하며, 기술자 블록은 묶음의 순서 번호와 어떤 파일 시스템 블록이 업데이트 되었는지 나타내는 목록을 포함한다.

 

만약 새로운 블록에서 업데이트가 발생하면 기존에 있던 묶음 뒤 블록에 기록된다.

 

또, 저널에 기록되었던 파일 시스템 블록은 취소가 가능하며, 취소를 할 경우 취소 블록이라는 곳에 그 목록이 순서 번호와 함께 저장이 된다.


# Reference

 

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

[Digital Forensic] NTFS 파일 시스템 (4)

 

NTFS 파일 시스템


(17) 데이터 구조

17-1. Fixup

  • NTFS에서 신뢰성을 향상시키기 위해 사용하는 저장 기술

  • 데이터가 저장된 섹터의 손상 여부를 판단

 

해당 기술의 원리는 일반적인 섹터의 마지막 2바이트를 특정 시그니처로 교체해 두고, 원래의 2바이트 값은 Fixup 배열에 저장하여 교체해 둔 시그니처가 다른 값으로 교체되지 않았다면 섹터가 손상되지 않은 것으로 보고 배열에 있는 원래의 값을 다시 섹터 마지막 2바이트에 넣는다.

 

오직 이 기술은 데이터 구조체에만 사용되며 클러스터 등에는 사용되지 않는다.

 

17-2. MFT 엔트리

  • MFT(Master File Table)는 NTFS에서 핵심적인 부분

  • 파일과 디렉토리에 대한 엔트리를 가짐

  • MFT 엔트리의 크기는 일정하며, 그 크기는 부트 섹터에서 정의하고 일반적 크기는 1024byte

 

다음 표는 MFT 엔트리 오프셋에 대한 구조이다.

 

[표 1] MFT 엔트리 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

시그니처(FILE)

22~23

플래그

4~5

Fixup 배열 오프셋

24~27

MFT 엔트리 실제 크기

6~7

Fixup 배열 엔트리 개수

28~31

MFT 엔트리 할당 크기

8~15

$LogFile 순서 번호

32~39

기본 레코드 파일 참조

16~17

순서 번호

40~41

다음 속성 ID

18~19

링크 카운트

42~1023

속성과 Fixup 배열 값

20~21

첫 번째 속성 오프셋

   

 

시그니처

  • MFT 엔트리의 시그니처로 'FILE'이란 문자열로 정해져 있음

  • 하지만 chkdsk가 엔트리에 오류를 발견하면 시그니처는 'FILE'이 아닌 'BAAD'로 교체 됨

 

Fixup 배열 오프셋

  • 해당 오프셋은 MFT 엔트리의 시작으로부터 상대적인 오프셋

 

$LogFile 순서 번호

  • 해당 번호는 응용 프로그램 참조 모델에서 알아본 저널링에 사용되는 번호

 

순서 번호

  • 엔트리가 할당되거나 비 할당 될 때 증가하는 값

  • 운영체제에 의해 결정

 

링크 카운트

  • 하드 링크의 개수를 나타냄

 

플래그

  • 해당 오프셋 값은 '0x0001'로 설정된다면 해당 엔트리가 사용 중이라는 것을 의미

  • '0x0002'로 설정된다면 해당 엔트리가 디렉토리에 할당된 엔트리라는 것을 의미

 

다음 속성 ID 필드까지를 'MFT 엔트리 헤더'라고 한다.

 

 

17-3. 속성

  • MFT 엔트리의 대부분은 속성으로 되어 있으며 그 속성들은 속성 헤더와 속성 내용으로 나뉘게 됨

  • 속성 헤더는 모두 같은 데이터 구조체를 지님

  • 속성 내용은 거주 속성과 비거주 속성으로 나뉘어 조금씩 다른 데이터 구조체를 지님

 

다음 표는 속성 헤더 오프셋에 대한 구조이다.

 

[표 2] 속성 헤더 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

속성 타입 식별자

4~7

속성 길이

8~8

비거주 플래그

12~13

플래그

9~9

이름 길이

14~15

속성 식별자

10~11

속성 이름 오프셋

   

 

비거주 플래그

  • 해당 오프셋 값은 속성 내용이 비거주 속성일 경우 셋팅괴는 값으로 비거주 속성일 경우 '0x01'로 설정

 

속성 이름 오프셋

  • 속성 헤더의 시작으로부터 상대적인 오프셋 값

 

플래그

  • 해당 값은 속성의 압축(0x0001), 암호화(0x4000), sparse(0x8000)을 의미하는 값

 

속성 식별자

  • MFT에서 속성에 대한 고유 번호

 

속성 헤더 바로 다음으로는 거주 또는 비거주 속성 데이터 구조체가 위치한다.

 

 

다음 표는 거주 속성 오프셋 구조이다.

 

[표 3] 거주 속성 오프셋 구조

범위(Byte)

설명

0~15

일반 헤더

16~19

내용 크기

20~21

내용 오프셋

 

다음 표는 비거주 속성 오프셋 구조이다.

 

[표 4] 비거주 속성 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~15

일반 헤더

36~39

사용 x

16~23

Runlist 시작 VCN

40~47

속성 내용 할당 크기

24~31

Runlist 끝 VCN

48~55

속성 내용 실제 크기

32~33

Runlist 오프셋

56~63

속성 내용 초기화 크기

34~35

압축 블록 크기

   

 

VCN

  • 논리적 파일 주소에 대한 다른 이름

  • 해당 값의 시작과 끝은 여러 MFT 엔트리들이 하나의 속성을 설명할 필요가 있을 때 사용

 

Runlist 오프셋

  • 해당 값은 속성 헤더 시작 오프셋에서의 상대적인 값

 

MFT 엔트리에 대한 기본적인 분석은 끝났지만 이 정도 분석으로 MFT 엔트리의 분석이 끝나는 것은 아니다.

 

MFT 엔트리에 할당되는 표준 속성들을 모두 분석해야 MFT 엔트리 분석이 모두 끝이 난다.

 

 

STANDARD_INFORMATION 속성

  • 해당 속성은 항상 거주 속성으로 타입 식별자는 16

  • 또 모든 파일과 디렉토리에 존재하며, 파일이나 디렉토리를 위한 기본 메타데이터 파일들을 포함

 

다음 표는 $STANDARD_INFORMATION 속성의 오프셋 별로 의미하는 것을 분석한 것이다.

 

[표 5] $STANDARD_INFORMATION 속성 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~7

생성 시간

40~43

버전 번호

8~15

파일 변경 시간

44~47

클래스 ID

16~23

MFT 변경 시간

48~51

소유자 ID (3.0 버전 이상)

24~31

파일 접근 시간

52~55

보안 (3.0 버전 이상)

32~35

플래그

56~63

할당 크기 (3.0 버전 이상)

36~39

버전 번호 중 최대 번호

64~71

업데이트 순서 번호 (USN) (3.0 버전 이상)

 

4개의 시간 값

  • 해당 시간 값들이 우리가 흔히 속성 창에서 볼 수 있는 시간 값

  • 1601년 1월 1일 UTC부터 100 나노초 단위로 계산되어 저장

 

플래그

  • 해당 파일에 적용될 수 있는 속성들 중 어떠한 속성을 나타내는 값이 저장되는 오프셋

 

보안 ID

  • 이 값은 $Sparse 파일의 인덱스 값

  • 보안 ID 값이 아님

 

플래그 오프셋에 대한 정보는 다음과 같다.

  • 0x0001 : 읽기 전용

  • 0x0002 : 숨김

  • 0x0004 : 시스템

  • 0x0020 : 아카이브

  • 0x0040 : 장치

  • 0x0080 : #일반

  • 0x0100 : 임시

  • 0x0200 : Sparse 파일

  • 0x0400 : 재파싱 지점

  • 0x0800 : 압축

  • 0x1000 : 오프라인

  • 0x2000 : 빠른 검색을 위한 인덱스 외의 내용

  • 0x4000 : 암호화

 

 

$FILE_NAME 속성

  • 해당 속성 타입 식별자는 48

  • 파일 이름과 부모 디렉토리 정보 저장을 위해 MFT 엔트리에 위치

  • 디렉토리 인덱스에서 사용

  • MFT 엔트리에서 사용될 때에는 포함되어 있는 정보가 필수적이지 않지만, 디렉토리 인덱스에서 사용될 때에는 다름

  • 해당 속성은 위에서 설명한 $STANDARD_INFORMATION 속성과 함께 필수적인 속성

  • 항상 거주 속성

 

또 해당 속성은 일반적으로 $STANDARD_INFORMATION 속성과 $DATA 속성 가운데에 위치하게 되는데 만약 하나의 파일에 여러 MFT 엔트리가 할당 될 경우 다른 비기준 엔트리의 속성을 포함하는 $ATTRIBUTE_LIST 속성이 $STANDARD_INFORMATION 속성과 $FILE_NAME 속성 사이에 위치한다.

 

 

다음 표는 $FILE_NAME 속성에 대한 오프셋 구조이다.

 

[표 6] $FILE_NAME 속성 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~7

부모 디렉토리 파일 참조

48~55

파일 실제 크기

8~15

파일 생성 시간

58~59

플래그

16~23

파일 수정 시간

60~63

재파싱 값

24~31

MFT 수정 시간

64~64

이름 길이

32~39

파일 접근 시간

65~65

네임스페이스

40~47

파일 할당 크기

66~

이름

 

부모 디렉토리 파일 참조

  • 해당 값의 상위 2바이트는 부모 디렉토리의 순서 번호

  • 하위 6바이트는 부모 디렉토리의 MFT 엔트리 번호

 

플래그

  • 해당 오프셋 값은 $STANDARD_INFORMATION의 플래그 값과 동일

 

네임스페이스

  • 이름 필드의 값이 어떤 형식인지 나타내는 값을 가짐

  • 흔히 파일 이름 규칙을 뜻함

 

이름

  • 이름 오프셋의 길이는 파일명에 따라 달라짐

  • 정확한 길이를 알고자 하면 이름 길이 오프셋을 참고하면 됨

 

 

$DATA

  • 해당 속성은 고유한 구조체를 가지고 있지 않음

  • 헤더 이후로는 파일 내용 데이터만 존재

  • 타입 식별자는 128이며 크기는 정해져 있지 않음

  • 하지만 내용이 700Byte 이상이라면 비거주 속성이 되어 클러스터가 할당

 

 

$ATTRIBUTE_LIST

  • 해당 속성은 MFT 엔트리에 존재하는데 $STANDARD_INFORMATION 속성과 $FILE_NAME 속성 사이에 위치

  • 타입 식별자는 32

  • MFT 엔트리에 여러 속성들이 할당되어 엔트리 크기인 1024Byte를 초과할 때 사용

  • 해당 속성 내용으로는 기준 MFT 엔트리에 포함되려 했던 속성들의 엔트리 리스트가 목록화 되어 있음

 

속성 시작 VCN은 여러 MFT엔트리들이 단일 속성을 ㅓㄹ명해야 할 때 필요하며, 이름 오프셋은 해당 엔트리 시작으로부터 상대적 오프셋 값이다.

 

 

다음 표는 $ATTRIBUTE_LIST에 대한 오프셋 구조이다.

 

[표 7] $ATTRIBUTE_LIST 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

속성 타입 식별자

8~15

속성 시작 VCN

4~5

해당 엔트리 길이

16~23

속성이 위치하려 했던 엔트리

6~6

이름 길이

24~24

속성 ID

7~7

이름 오프셋

   

 

 

$OBJECT_ID

  • 해당 속성은 64 타입 식별자를 가짐

  • 이름 대신 파일을 지칭하는 128bit의 오브젝트 식별자를 포함

  • 해당 속성은 간단한 구조로 되어 있음

  • 총 4개의 필드로 구성되어 있으나 보통 첫 번째 필드만 설정되어 있음

 

다음 표는 $OBJECT_ID 오프셋에 대한 구조이다.

 

[표 8] $OBJECT_ID 오프셋 구조

범위(Byte)

설명

0~15

오브젝트 ID

16~31

파일이 생성된 볼륨 ID

32~47

파일이 생성될 때 받은 오브젝트 ID

48~63

파일이 생성될 때 받은 도메인 ID

 

$OBJECT_ID 속성 구조를 보면 오브젝트 ID 필드가 존재하는데 이 필드는 \$Extend\ObjID 인덱스들을 정렬할 때 사용되기도 한다.

 

 

$REPARSE_POINT

  • 해당 속성은 식별자 192를 가짐

  • 해당 속성은 재파싱 지점의 파일에 할당 됨

  • 8~9 오프셋 범위와 12~13 오프셋 범위는 바이트 오프셋 16에서 상대적인 오프셋 값을 가짐

 

다음 표는 $REPARSE_POINT 속성 오프셋에 대한 구조이다.

 

[표 9] $REPARSE_POINT 속성 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

Reparse 타입 플래그

10~11

대상 이름 길이

4~5

Reparse 데이터 크기

12~13

대상의 출력 이름 오프셋

6~7

사용 x

14~15

출력 이름 길이

8~9

대상 이름 오프셋

   

 

 

INDEX_ROOT

  • 해당 속성은 타입 식별자 144를 가짐

  • 항상 거주 속성

  • 해당 속성의 엔트리는 항상 인덱스 트리의 루트

 

다음 표는 $INDEX_ROOT 속성 헤더 오프셋에 대한 구조이다.

 

[표 10] $INDEX_ROOT 속성 헤더 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~3

인덱스 속성 타입

12~12

인덱스 레코드 크기(클러스터)

4~7

수집 정렬 규칙

13~15

사용 x

8~11

인덱스 레코드 크기

16~

노드 헤더

 

인덱스 내의 속성 타입

  • 인덱스에 포함되어 있는 엔트리의 속성 타입을 포함하는 오프셋

  • 엔트리가 속성을 사용하지 않는 경우 0으로 설정

 

수집 정렬 규칙

  • $INDEX_ALLOCATION 속성에서 정렬되는 규칙

 

인덱스 레코드 크기(Byte)

  • 인덱스 레코드의 바이트 크기를 포함하는 오프셋

 

인덱스 레코드 크기(클러스터)

  • 인덱스 레코드 크기만큼 필요한 클러스터 수

 

$INDEX_ROOT 속성 헤더는 16바이트의 크기를 가지며, 노드 헤더 또한 16바이트의 크기를 가진다.

 

[그림 1] $INDEX_ROOT 속성의 레이아웃

 

 

$INDEX_ALLOCATION

  • 큰 디렉토리일 경우 인덱스 엔트리가 $INDEX_ROOT 속성에 적합하지 않음

  • 이러한 경우 비 거주 속성인 해당 속성이 사용 됨

  • 해당 속성 내용은 인덱스 레코드로 이루어져 있는데, 인덱스 레코드의 크기는 고정

  • 정렬된 트리의 노드 하나를 포함하고 있음

  • 인덱스 레코드의 크기는 $INDEX_ROOT 속성 헤더의 정의되어 있으며, 보통 4096Byte

  • 해당 속성의 타입 식별자는 160이며 해당 속성의 내용인 인덱스 레코드는 특별한 헤더 데이터 구조체로 시작

  • 헤더 다음으로 노드 헤더와 인덱스 엔트리의 목록이 옴

 

[그림 2] $INDEX_ALLOCATION 속성 레이아웃

 

다음 표는 인덱스 레코드 헤더에 대한 오프셋이다.

 

[표 11] 인덱스 레코드 헤더 오프셋

범위(Byte)

설명

범위(Byte)

설명

0~3

시그니처(INDX)

8~15

$LogFile 순서 번호(LSN)

4~5

Fixup 배열 오프셋

16~23

전체 인덱스 스트림에서 해당 레코드 VCN

6~7

Fixup 배열 엔트리 수

24~

노드 헤더

 

시그니처

  • 인덱스 레코드에는 시그니처가 존재

  • 시그니처는 'INDX'

 

Fixup 배열 오프셋

  • 해당 오프셋의 값은 Fixup 배열의 오프셋 주소

  • 인덱스 레코드 헤더 시작 부분에서 상대적

 

 

BITMAP

  • 해당 속성은 인덱스 레코드의 할당 상태를 관리하는 속성

  • 모든 인덱스 레코드가 할당되는 것은 아니며 운영체제 판단에 의해 필요 시 할당

  • $BITMAP 속성은 MFT 엔트리 할당 추적을 위해 $MFT에 의해 사용

  • 해당 속성은 타입 식별자 176을 가지며 각 바이트를 비트로 변환하여 인덱스 레코드와 맵핑

[그림 3] $BITMAP 속성 내용

 

[그림 3]을 분석해 보면 첫 바이트가 0x01인데 비트로 변환 시 0000 0001이다.

 

이것은 인덱스 레코드 0이 할당 되었다는 것을 의미한다.

 

만약 0x02 바이트여서 0000 0010이라면 인덱스 레코드 1이 할당 되었다는 것을 의미한다.

 

 

인덱스 노드 헤더 데이터 구조체

  • $INDEX_ROOT 속성과 $INDEX_ALLOCATION 속성 다음에 위치하게 되는 16Byte의 크기를 가짐

 

다음 표는 노드 헤더 오프셋에 대한 구조이다.

 

[표 12] 노드 헤더 오프셋 구조

범위(Byte)

설명

0~3

인덱스 엔트리 목록 시작에서의 오프셋

4~7

인덱스 엔트리 목록 마지막에서의 오프셋

8~11

할당된 인덱스 엔트리 목록 버퍼 마지막에서의 오프셋

12~15

플래그

 

인덱스 엔트리 목록 시작 오프셋

  • 해당 값은 노드 헤더 시작에서 상대적

 

인덱스 엔트리 목록의 마지막 오프셋

  • 해당 값은 노드 헤더 마지막에서 상대적

 

플래그

  • 플래그는 설정되지 않거나 0x01로 설정되는 경우 밖에 없음

  • 0x01로 설정되는 경우 인덱스 엔트리 목록에 있는 엔트리에 의해 지정된 자식 노드가 있다는 것을 의미

 

 

17-4. 인덱스 엔트리

 

표준 인덱스 엔트리

  • 말 그대로 인덱스 엔트리의 표준 레이아웃을 가진 인덱스 엔트리

  • 어떠한 내용도 가질 수 있는 엔트리

 

다음 표는 인덱스 엔트리 오프셋에 대한 구조이다.

 

[표 13] 표준 인덱스 엔트리 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~7

????

12~15

플래그

8~9

엔트리 길이

16~

내용

10~11

내용 길이

   

 

플래그

  • 0x01 : 자식 노드가 존재

  • 0x02 : 인덱스 엔트리 목록에서 마지막 엔트리

 

디렉토리 인덱스 엔트리

  • 파일 이름을 사용하는 디렉토리 인덱스는 자신만의 데이터 구조체를 가짐

 

다음 표는 디렉토리 인덱스 엔트리 오프셋에 대한 구조이다.

 

[표 14] 디렉토리 인덱스 엔트리 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0~7

파일 이름의 MFT 파일 참조

12~15

플래그

8~9

해당 엔트리 길이

16~

내용

10~11

$FILE_NAME 속성 길이

   

 

플래그

  • 표준 인덱스 엔트리의 플래그와 동일

표준 인덱스 엔트리와 디렉토리 인덱스 엔트리 마지막 8바이트는 $INDEX_ALLOCATION에 있는 자식 노드의 VCN 값을 가지고 있다.


(18) 메타데이터 파일

 

$MFT

 

해당 메타데이터 파일은 앞 내용에서 많이 언급하였으므로 해당 메타데이터 파일의 일반적 구조와 속성은 생략하고, 고유 속성인 $BITMAP 속성만 분석해 볼 것이다.

 

  • $BITMAP 속성은 NTFS의 MFT 엔트리 할당 상태를 관리하는 속성

  • 각 비트가 MFT 엔트리의 맵핑되어 MFT 엔트리가 할당되면 해당 MFT 엔트리와 맵핑 관계인 비트가 1로 설정

[그림 4] $MFT 파일의 $BITMAP 속성 오프셋

 

[그림 4]를 보면 F로 설정된 오프셋과 0으로 설정된 오프셋이 있는데 F로 설정된 오프셋이 할당 상태를 뜻하고 0으로 설정된 오프셋이 비할당 상태를 뜻한다.

 

MFT 엔트리 맵핑 관계는 각 오프셋을 비트로 변환하면 알 수 있다.

 

  • 0 오프셋 (FF) : 1111 1111 (MFT 엔트리 0 ~ 7 할당)

  • 1 오프셋 (FF) : 1111 1111(MFT 엔트리 8 ~ 15 할당)

  • 2 오프셋 (00) : 0000 0000 (MFT 엔트리 16 ~ 23 할당)

  • 3 오프셋 (FF) : 1111 1111 (MFT 엔트리 24 ~ 31 할당)

  • 4 오프셋 (7B) : 0111 1011 (MFT 엔트리 32 ~ 33 할당, 34 비할당, 35 ~ 38 할당, 39 비할당)

  • 5 오프셋 (00) : 0000 0000 (MFT 40 ~ 47 비할당)

  • 6 오프셋 (00) : 0000 0000 (MFT 엔트리 48 ~ 55 비할당)

  • 7 오프셋 (00) : 0000 0000 (MFT 엔트리 56 ~ 63 비할당)

 

$Boot

  • 해당 메타데이터 파일은 MFT 엔트리 여덟 번째에 위치

  • 부트 섹터와 부트 코드를 포함

  • 부트 섹터는 항상 섹터 0에서 시작하며, 부트 섹터를 제외한 섹터들은 부트 코드를 위해 사용

  • 부트 섹터에서 체크해야 할 부분들은 섹터와 클러스터의 크기를 정의하는 부분 (이 부분이 없으면 어떠한 것도 위치 파악 불가능)

  • 다음으로 MFT 엔트리 크기를 정의하는 부분을 체크해야 함

  • MFT 엔트리의 인덱스 레코드를 의미하는 필드들은 모두 특별한 형식을 가짐

 

만약 MFT 엔트리나 인덱스 레코드를 의미하는 필드들의 값이 0보다 크면 각 데이터 구조체에서 사용하는 클러스터 수를 값으로 가지게 된다.

 

또 0보다 작다면 각 데이터 구조체에 있는 바이트 수 밑이 2인 로그 값을 저장한다.

 

이러한 현상은 클러스터 크기가 단일 MFT 엔트리나 인덱스 레코드보다 클 경우 일어난다.

 

보통은 1024Byte이지만 이 값은 언제든지 수정될 수 있기 때문이다.

 

 

다음 표는 $Boot 파일의 오프셋이다.

 

[표 15] $Boot 파일 오프셋

범위(Byte)

설명

범위(Byte)

설명

0 ~ 2

부트 코드 점프 명령

32 ~ 35

사용 X

3 ~ 10

OEM 이름

36 ~ 39

사용 X

11 ~ 12

섹터별 Byte(512, 1024, 2048, 4096)

40 ~ 47

섹터 총 개수

13 ~ 13

클러스터별 섹터 수

48 ~ 55

$MFT 파일의 클러스터 번호

14 ~ 15

예약 영역

56 ~ 63

$MFTMirr 파일의 클러스터 번호

16 ~ 18

언제나 O

64 ~ 67

파일 레코드 세그먼트별 클러스터 개수

19 ~ 20

사용 X

68 ~ 71

인덱스 블록별 클러스터 개수

21 ~ 21

장치 타입

72 ~ 79

볼륨 시리얼 번호

22 ~ 23

언제나 O

80 ~ 83

체크섬

24 ~ 25

저장 장치 트랙별 섹터 수

84 ~ 509

부트 코드

26 ~ 27

저장 장치 헤드 개수

510 ~ 511

시그니처(0xAA55)

 

$AttrDef

  • 해당 메타데이터 파일은 MFT 엔트리 다섯 번째에 위치

  • 파일 시스템 속성들의 이름과 식별자 정의

 

다음 표는 $AttrDef 파일의 오프셋이다.

 

[표 16] $AttrDef 파일 오프셋

범위(Byte)

설명

범위(Byte)

설명

0 ~ 127

속성 이름

140 ~ 143

플래그

128 ~ 131

타입 식별자

144 ~ 151

최소 크기

132 ~ 135

출력 규칙

152 ~ 159

최대 크기

136 ~ 139

수집 규칙

   

 

플래그

  • 0x02 : 인덱스에서 속성이 사용

  • 0x40 : 항상 거주 속성

  • 0x80 : 비거주 속성

 

 

$BITMAP

  • 해당 메타데이터 파일은 클러스터 할당 상태를 관리하는 파일

  • 해당 비트맵의 내용은 $DATA 속성에 저장

  • 각 비트별로 클러스터와 맵핑되어 있는데 어떠한 클러스터의 할당 상태를 알고자 할 때 해당 메타데이터 파일 해당 클러스터의 비트를 찾아야 함

  • 하지만 무작정 찾기에는 매우 시간이 오래 걸림

이러한 시간 낭비를 줄이기 위해 다음과 같은 계산식을 적용한다.

 

$BITMAP 내의 바이트 오프셋 = 클러스터 번호 / 8

$BITMAP 내의 클러스터 비트 오프셋 = 클러스터 번호 - 8 x $BITMAP 내의 바이트 오프셋

 

 

$Volume

  • 해당 메타데이터 파일은 두 개의 속성으로 이루어져 있으며 이 속성을 중점적으로 해당 메타데이터 파일을 분석해야 함

  • 해당 메타데이터 파일은 MFT 엔트리 네 번째에 위치

  • 가지고 있는 속성으로는 $VOLUME_NAME과 $VOLUME_INFORMATION이 있음

 

 

VOLUME_NAME

  • 해당 속성은 $VOLUME 파일이 할당되었을 경우만 사용되는 속성

  • 타입 식별자는 96

  • 파일 내용으로는 파일 시스템의 볼륨 이름을 저장하고 있음

[그림 5] $VOLUME_NAME 속성 내용

 

VOLUME_INFORMATION

  • 해당 속성은 $VOLUME 파일의 두 번째 속성

  • 내용으로는 파일 시스템 버전을 포함

  • 타입 식별자는 112

 

다음 표는 $VOLUME_INFORMATION 속성 오프셋 구조이다.

 

[표 17] $VOLUME_INFORMATION 속성 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0 ~ 7

사용 x

9 ~ 9

부 버전

8 ~ 8

주 버전

10 ~ 11

플래그

 

플래그

  • 0x0001 : 불량

  • 0x0002 : $LogFile 크기 재정의

  • 0x0004 : 다음 업그레이드 볼륨

  • 0x0008 : NT 시스템에 마운트 됨

  • 0x0010 : 변경저널 삭제

  • 0x0020 : 오브젝트 ID를 교정

  • 0x8000 : Chkdsk에 의해 수정

 

 

$ObjId

  • NTFS에서는 다른 파일 시스템과 달리 파일 이름 말고도 오브젝트 ID를 사용하여 파일을 구별할 수 있음

  • 어떠한 파일을 포함하는 인덱스는 $INDEX_ROOT 속성과 $INDEX_ALLOCATION 속성을 일반적으로 가짐

  • 파일을 직접적으로 포함하고 있는 인덱스 엔트리는 특정 데이터 구조체를 가지고 있음

 

다음 표는 $ObjId 파일의 오프셋 구조이다.

 

[표 18] $ObjId 파일 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0 ~ 1

파일 정보 오프셋

16 ~ 31

오브젝트 ID

2 ~ 3

파일 정보 크기

32 ~ 39

파일 참조

4 ~ 7

사용 x 

40 ~ 55

파일이 생성된 볼륨 ID

8 ~ 9

인덱스 엔트리 크기

56 ~ 71

파일이 생성될 때 받은 오브젝트 ID

10 ~ 11

오브젝트 ID 크기

72 ~ 87

파일이 생성될 때 받은 도메인 ID

12 ~ 15

플래그

   

 

플래그

  • 0x01 : 자식 노드가 존재

  • 0x02 : 목록에서 마지막 엔트리

 

 

$Quota

  • 해당 메타데이터 파일은 $INDEX_ROOT와 $INDEX_ALLOCATION 속성을 일반적으로 사용

  • 두 개의 인덱스를 가짐 

 

두 개의 인덱스는 다음과 같다.

  • $O 인덱스 : 하나의 SID와 소유자 ID를 연결시키는 역할

  • $Q 인덱스 : 할당 정보에 자신의 ID를 연결시키는 역할

 

[표 19] $O 인덱스 오프셋의 구조

범위(Byte)

설명

0 ~ 1

소유자 ID 오프셋

2 ~ 3

소유자 ID 길이

4 ~ 7

사용 x

8 ~ 9

인덱스 엔트리 크기

10 ~ 11

SID 크기

12 ~ 15

플래그

16 ~ (16+SID 크기 -1)

SID

소유자 ID 오프셋 ~

소유자 ID

 

소유자 ID 오프셋

  • 해당 오프셋 값은 $O 인덱스 시작으로부터 상대적

 

플래그

  • 0x01 : 자식 노드가 존재

  • 0x02 : 목록에서 마지막 엔트리

 

소유자 ID

  • 해당 오프셋은 소유자 ID 오프셋(0~1)을 참조

  • 해당 바이트 오프셋부터 소유자 ID 길이 만큼까지가 오프셋 범위

 

 

[표 20] $Q 인덱스 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0 ~ 1

할당 정보 오프셋

2 ~ 3

할당 정보 크기

4 ~ 7

사용 x

8 ~ 9

인덱스 엔트리 크기

10 ~ 11

소유자 ID 크기

12 ~ 15

플래그

16 ~ 19

소유자 ID

44 ~ 51

임계치

20 ~ 23

버전

52 ~ 59

절대 제한 값

24 ~ 27

할당 플래그

60 ~ 67

초과 시간

28 ~ 35

사용자에게 할당된 바이트 영역

68 ~ 79

SID

36 ~ 43

마지막으로 할당된 시간

   

 

소유자 ID 크기

  • 해당 오프셋의 값은 언제나 '0x0004'

 

플래그

  • 0x01 : 자식 노드 존재

  • 0x02 : 목록에서 마지막 엔트리

 

할당 플래그

  • 0x00000001 : 기본 한계치를 사용

  • 0x00000002 : 한계에 도달

  • 0x00000004 : ID 삭제

  • 0x00000010 : 데이터 사용을 관찰

  • 0x00000020 : 강제적으로 데이터 사용

  • 0x00000040 : 사용량 추적을 요청

  • 0x00000080 : 사용량에 거의 도달하면 로그 생성

  • 0x00000100 : 한계 값에 도달하면 로그 생성

  • 0x00000400 : 기한을 지남

  • 0x00000800 : 사용을 금함

 

 

$LogFile

  • 해당 메타데이터는 MFT 엔트리 세 번째에 위치

  • NTFS 저널링에 사용

  • 속성은 표준 속성을 가지고 있고, 로그 데이터를 내용으로 가지고 있는데 이 내용은 $DATA 속성에 포함되어 있음

  • 하지만 오프셋 구조는 아직 정확히 알려진 바가 없음

 

$UsrJrnl

  • 해당 메타데이터 파일은 변경 저널링에 사용

  • 파일에 변경이 발생하면 해당 메타데이터 파일에 관련 정보가 기록

  • 해당 파일도 $ObjId, $Quota 등의 파일과 마찬가지로 MFT 예약 엔트리에 있지 않고 $Extend 메타데이터 파일에 포함

  • 해당 메타데이터 파일에는 두 가지 $DATA 속성이 존재

 

두 가지의 $DATA 속성은 다음과 같다.

  • $J : 이 속성은 sparse 속성이며, 다른 크기로 된 데이터 구조체 목록을 포함하고 있음

  • $Max : 사용자 저널링 최대 설정의 대한 정보를 포함하고 있음

 

[표 21] $J 속성의 오프셋 구조

범위(Byte)

설명

범위(Byte)

설명

0 ~ 3

해당 저널 엔트리 크기

40 ~ 43

변경 유형 플래그

4 ~ 5

주 버전

44 ~ 47

출처 정보

6 ~ 7

부 버전

48 ~ 51

보안 ID (SID

8 ~ 15

해당 엔트리와 관련된 엔트리 번호

52 ~ 55

파일 속성

16 ~ 23

부모 디렉토리 엔트리 번호

56 ~ 57

파일 이름 크기

24 ~ 31

엔트리 USN

58 ~

파일 이름

32 ~ 39

타임스탬프

   

 

변경 유형 플래그

  • 0x00000001 : 기본 $DATA 속성이 덮어 씌워짐

  • 0x00000002 : 기본 $DATA 속성이 추가됨

  • 0x00000004 : 기본 $DATA 속성이 줄어듦

  • 0x00000010 : 이름이 있는 $DATA 속성이 덮어 씌워짐

  • 0x00000020 : 이름이 있는 $DATA 속성이 추가됨

  • 0x00000040 : 이름이 있는 $DATA 속성이 줄어듦

  • 0x00000080 : 파일이나 디렉토리가 생성됨

  • 0x00000100 : 파일이나 디렉토리가 삭제됨

  • 0x00000400 : 파일의 확장된 속성이 변경됨

  • 0x00000800 : 보안 기술자가 변경됨

  • 0x00001000 : 이름이 변경되고, 변경 저널 엔트리가 이전 이름을 가지고 있음

  • 0x00002000 : 이름이 변경되고, 변경 저널 엔트리가 새로운 이름을 가지고 있음

  • 0x00004000 : 인덱스 상태 변경

  • 0x00008000 : 파일이나 디렉토리 속성이 변경됨

  • 0x00010000 : 하드 링크 생성 또는 삭제

  • 0x00020000 : 압축 상태 변경

  • 0x00040000 : 암호 상태 변경

  • 0x00080000 : 오브젝트 ID 변경

  • 0x00100000 : Reparse 지점값 변경

  • 0x00200000 : 이름이 있는 $DATA 속성이 있는 생성 또는 삭제, 변경됨

  • 0x80000000 : 파일 또는 디렉토리가 닫힘

 

[표 22] $Max 속성 오프셋 구조

범위(Byte)

설명

0 ~ 7

최대 크기

8 ~ 15

할당 크기

16 ~ 23

USB ID

24 ~ 31

최하위 USN

 

$Max 오프셋 구조를 보면 포렌식적 의미를 가진 정보는 없다.

 

NTFS는 여러 가지 기능과 복합적 구조로 인해 분석하기 어려운 편에 속하는 파일 시스템이다.

 

또 아직까지 알려지지 않은 데이터 구조체 필드로 인해 또 어떠한 포렌식적 의미의 정보가 있는지 알 수 없는 파일 시스템이다.


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

 

NTFS에서도 FAT 파일 시스템과 마찬가지로 비할당 영역이나 슬랙 공간을 주시해야 한다. (모든 파일 시스템이 동일)

 

FAT 파일 시스템의 부트 섹터에는 데이터를 숨길 공간이 연속적으로 존재하므로 숨길 가능성이 높았다.

 

하지만 NTFS의 부트 섹터 영역은 그 공간들이 FAT 파일 시스템과 비슷하게 있지만 일부 필드의 값이 무조건적으로 0으로만 설정되어 있어야 파일 시스템이 마운트되기 때문에 이러한 필드들을 제외하고 데이터를 숨기기에는 까다로워 숨기기에는 적합하지 못하다.

 

NTFS의 구조를 아는 공격자라면 부트 섹터보다는 $Boot 파일 이후의 영역에 데이터를 숨길 것이다.

 

또한, NTFS 파일 시스템에도 볼륨 슬랙이 존재하므로 볼륨 슬랙을 체크하는 것이 좋다.


# Reference

 

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

+ Recent posts