[Digital Forensic] E-Discovery 전자증거개시제

 

E-Discovery


(1) E-Discovery 전자증거개시제

1-1. E-Discovery 전자증거개시제란?

  • Electronic Discovery의 약자로 우리나라 말로 '전자증거개시제' 혹은 '디지털 증거개시제'라고 함

  • 해당 단어는 미국의 법률이 개정되면서부터 사용

  • 미국에서 민사소송 규칙이 개정되면서 Discovery에 사용되는 증거 범위에 전자 포맷의 문서(ESI)가 포함되어 해당 단어가 사용되기 시작

  • Discovery는 소송자가 공판 전 공판에서 사용될 증거들을 법정에서 사용하는 방법으로 수집하여 법원에 120일 이내에 제출하는 것을 말함

E-Discovery를 시행하는 이유는 모든 소송자가 해당 증거물을 검토할 수 있게 하여 공정한 재판을 하기 위해서이다.

 

ESI에는 PC 문서, 이메일, 메신저 대화 내용 등이 모두 포함되며, 소송에 관련된 어떠한 전자적인 자료도 해당된다고 볼 수 있다.

 

ESI를 증거로 제시할 때에는 무결성 또는 진정성, 신뢰성 등이 보장되어야 한다.

 

현재 여러 국가에서 전자증거개시제를 시행하고 있지만 제일 처음 전자증거개시제를 시행한 곳이 영국과 캐나다이지만 현재로서는 미국에서 가장 많이 활용되고 있다.

 

[그림 1] E-Discovery 일반적 과정

 

위 그림은 EDRM(Electronic Discovery Reference Model)에서 제시하는 전자증거개시제 참조 모델이다.


(2) E-Discovery 과정

2-1. 정보 관리(Information Management) 단계

  • 전자증거개시제에 필요한 정보들을 신속하게 사용할 수 있도록 관리하는 단계

  • 즉, 미리 준비하는 단계라고 말할 수 있음

  • 증거 개시가 요청되면 제한 시일내에 증거 개시가 이루어져야 하기 때문에 미리 필요한 정보를 준비해두는 것

 

2-2. 식별(Identification) 단계

  • 정보 관리 단계에서 관리하였던 정보들 중 증거 개시 가능성이 존재하는 모든 자료를 식별하는 단계

  • 정보를 식별하며 정보의 소유자와 관리자를 명확히 하고 증거의 출처 등을 명확하게 하는 단계

 

2-3. 보존(Preservation) 단계

  • 식별 단계에서 식별한 정보의 무결성과 안전성을 유지하는 단계

  • 실수였든 고의였든 이유를 불문하고 훼손된 증거에 대해서는 법정에서 불이익을 받기 때문에 이 단계는 매우 중요

 

2-4. 수집(Collection) 단계

  • 식별되고 보존된 정보에서 원본의 무결성을 유지하며 증거로 사용될 만한 일련의 데이터(파일 내용, 파일명, 파일 타임라인 등)을 추출해 내는 단계

  • 원본의 보존을 위해 원본의 물리적 복사본을 이용하던가, 논리적 이미징을 수행해 이미지를 통해 데이터를 추출

 

2-5. 처리(Processing) 단계

  • 수집 단계에서 수집 된 데이터들을 연관성이 있는 정보들끼리 결합하는 단계

  • 각각의 데이터는 별 의미가 없어보이지만 결합할 시 증거에 큰 도움이 되는 데이터가 될 수 있음

  • 이러한 이유 외에도 추후 분석 솔루션 등을 이용할 때 효율성 있게 분석하기 위해 데이터들을 결합하기도 함

 

2-6. 검토(Review) 단계

  • 처리 단계에서 처리된 자료들에 대해 관련 사건과 관련 있는지 검토하는 단계

  • 이 단계는 일반적으로 법률 관계자(변호사 등)가 수행하는 단계

 

2-7. 분석(Analysis) 단계

  • 수집 단계에서 수집된 데이터들에서 사건과 관계가 있는 키워드나 문맥 등을 추출해 내는 단계

  • 검토나 처리 단계와 비슷하다고 생각할 수 있는데 위 사진의 세 가지 단계는 상호 관계에 있는 단계들

 

2-8. 제작(Production) 단계

  • 위 세 단계를 거진 정보를 소송 당사자들과 합의한 제출 포맷이나 법정에서 제시한 제출 포맷으로 정보를 제작하는 단계

  • 가끔 합의한 포맷으로 변환하지 않고 원본 데이터를 제출하는 경우도 있지만 대부분은 PDF 등의 포맷으로 변환하여 상대방이 검토하기 좋게 하여 제출함

 

2-9. 제출(Presentation) 단계

  • 제작 단계를 거친 정보를 소송 당사자들끼리 약속한 제출 방법

  • 서로에게 전달하거나 법원에 해당 정보를 제출하는 단계


(3) EDBP란?

3-1) EDBP(Electronic Discovery Best Practice)

  • EDRM에서 추구하고자 하는 법률적, 기술적 가이드라인에 대한 제시와는 달리 법률적인 분야에 더 세부적인 절차를 제시하여 기업들에게 법률 서비스를 제공하는 모델

  • 이런 이유로 EDBP에서는 EDRM의 디지털 포렌식 기술 등을 제외하고 EDRM의 모든 절차를 근거로 하는 법률적인 분야의 내용만 제시

  • 즉, EDBP는 EDRM을 근거로 기업에게 법률 서비스를 제공하는 분야로 볼 수 있음

  • EDBP는 법률적 사실을 제공하기 위해 연방민사소송규칙에 명시된 절차를 중점적으로 하여 모델을 구성하였고, 모델에서 언급하는 과정 중간에 근거들을 제시하여 신뢰성을 더함

 

다음은 EDBP에서 제시하는 EDBP 모델이다.

 

[그림 2] EDBP 모델

 

각 항목을 살펴보면 굉장히 세부적으로 많이 나누어 무언가를 제시하고 있는 것을 볼 수 있다.

 

대부분의 내용을 종합해 생각해보면 EDBP는 법률적 분야를 다루는 모델이어서 그런지 소송 준비 단계에서부터 정책과 관련한 이야기를 많이 다루고, 제시하고 있다.


(4) EDRM과 EDBP의 차이?

 

EDRM과 EDBP의 차이는 제시 모델의 내용에서부터 확인할 수 있다.

 

  • EDRM은 '정보 관리' 항목을 소송 전 준비 단계에서 중요한 부분으로 단계 전반에 걸쳐 다룸

  • EDBP는 '정보 관리'를 소송 전 준비 단계의 일부분으로 다룸

이는 EDBP가 조금 더 자세하고, 여러 주제에 대해 '정보 관리'를 생각하고 있음을 말해주고 있다.

 

EDBP는 기존에 있던 E-Discovery의 판례들을 모델에 적극적으로 제시하고 있다는 것을 '정보 관리'에서 부터 보여주고 있는 것이다.

 

또 EDBP는 정보를 분석하고 식별하는 팀을 구성하여 키워드 검색을 하는 기술적 중심으로 절차를 구성하는 EDRM과는 다르게 절차가 전반적으로 사람 중심이다. 

 

시람 중심이라는 의미는 EDRM의 절차가 주로 면담을 통해서 이루어진다는 것을 의미한다.

 

EDRM 또한 사람들을 만나 절차가 이루어지지만 면담을 통해 여러가지 방안을 제시하는 EDBP와는 달리 내용 확인을 위한 사람과의 만남이 주를 이룬다.


EDBP를 E-Discovery에 이용한다면 소송 준비 단계부터 E-Discovery 비용을 절감할 수 있으며, E-Discovery의 전 과정에서 소송 비용을 절감하기 위한 모델이라는 것을 EDBP 각 단계에서 느낄 수 있다.

 

어찌보면 비용 절감 측면에서 EDBP는 상업적 면이 굉장히 많이 부각될 수 있다.

 

하지만, 세부적 절차와 신뢰성 있는 근거를 제시하는 모델인 만큼 상업적 측면보다는 조금 더 E-Discovery를 준비함에 있어 필요한 모델임이 분명하기에 많은 로펌이나 컨설턴트들이 참조하고 있다는 것을 알아야 한다.


# Reference

 

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

[Digital Forensic] Chain of Custody

 

Chain of Custody


(1) CoC

  • 현재의 증거가 최초로 수집된 상태에서 지금까지 어떠한 변경도 되지 않았다는 것을 보증하기 위한 절차적 방법

  • 미국의 경우 Chain of Custody가 지켜지지 않으면 해당 증거물은 법적 증거 효력을 갖지 못하게 되며 해당 증거물에서 나오는 모든 증거물은 법적 증거효력을 갖지 못함

  • Chain of Custody는 수사 기관 등에서 의도적 증거 조작으로부터 피의자를 보호하려는 성격을 지님

 

1-1. Chain of Custody 부정

  • Chain of Custody 부정 방법 중 대표적인 것은 일시적 증거 무관리 상태를 증명하는 것

  • 일시적 증거 무관리 상태란, 증거 보관자와 증거가 물리적으로 떨어진 상태를 말함

  • 무관리 상태는 증거 보관자가 증거와 떨어져 있는 사이 증거가 변경될 수 있다는 가정을 의미하기 때문에 부정 방법으로 쓰임

 

1-2. Chain of Custody 수행

  • Chain of Custody를 수행하기 위해 작성하는 문서가 있는데 이 문서의 포맷은 어떠한 표준이 있는 것은 아님

  • 각 기관(회사)마다 조금씩 양식의 차이가 있음

  • 그러나 기입하는 내용은 대부분 동일

 

[그림 1] CoC 기록표 예시

 

Chain of Custody는 '연계 보관성'으로 번역되기도 한다.

 

CoC의 가장 중요한 점은 어떠한 물건이 이동하는 과정의 기록이라 할 수 있다.

 

디지털 포렌식 입장에서는 증거물의 이동 과정에서 그 대상의 무결성이 보존되었다는 증거로도 활용되며 그 과정에서 발생되는 사건에 대해서 기록되어야 한다는 것이다.

 

디지털 포렌식에 있어서 무결성이란 그 무엇보다 중요시 하기도 하며 그 무결성에 의해 큰 제약을 받기도 한다.


# Reference

 

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

[Digital Forensic] 안티 포렌식(Anti Forensics)

 

안티 포렌식

 

흔히 어떠한 기술의 반대적 성향을 가진 기술 명칭에는 Anti 라는 단어가 붙어 명명되곤 한다.

 

또 'Anti'라는 단어가 붙은 기술을 보면 대부분 좋지 않은(보안 기술과 반대적인 크래킹 등) 기술들이어서 일반적인 인식 자체가 좋지 않은 기술로 사람들 머리 속에 자리잡게 되곤 한다.

 

하지만 안티 포렌식은 그렇지 않다.


(1) 안티 포렌식이란? 

  • 어떠한 사건을 해결하기 위한 포렌식 기술 수행을 방해하기 위한 것이 목적이므로 좋은 기술이 될 수 없음

  • 현재 포렌식이 각광을 받고 있고 또 그 시장 규모가 예전에 비해 많이 팽창함에 따라 포렌식 연구가 활발히 진행

  • 반면에 안티 포렌식에 대비하는 연구는 아직 미비

  • 대부분의 문서에서는 안티 포렌식의 예로 루트킷을 거론하곤 함

루트킷을 거론하는 이유는 안티 포렌식 기술의 대부분을 루트킷이 수행하기 때문이다.

 

그렇기에 안티 포렌식의 모음이라고 할 수 있는 루트킷을 거론하는 것이다.

 

안티 포렌식에는 여러 종류의 기술들이 존재한다. 그 기술을 수행하는데 있어 방법은 여러 가지이다.

 

그러므로 이 섹션에서는 기술의 종류만 정의할 것이다. (기술의 명칭이 명명되지 않은 이유도 있다)

 

 

1-1. Data Destruction

  • 포렌식을 어렵게 하는 근본적 이유는 데이터 부족

  • 수집된 데이터가 부족하다면 분석할 수 있는 범위가 그만큼 한정되기 때문

  • Data Destruction은 수집될 수 있는 데이터들을 수집되지 못하도록 완전히 삭제 하는 것을 의미

 

데이터 완전 삭제는 일반적으로 Wiping이라고 불린다.

 

그런데 대부분의 문서를 보면 Wiping의 수행 횟수를 제시한다.

 

왜 1번이 아니라 여러 번을 시도하라고 권장하고, 기존 데이터를 다른 데이터로 덮어씌우는 Wiping은 1번만 해도 그 데이터가 완전 삭제되는 것이 아니던가?

 

이유는 바로 요즘 출시되는 하드 디스크의 특성 때문이다.

 

요즘 하드 디스크의 플래터에는 강한 자성을 이용해 데이터를 저장하려고 플래터 표면에 코발트, 크롬, 산화 알루미늄과 같은 자성 물질을 코딩시켜 두는데 이 자성 물질에 데이터가 저장되게 되면 데이터가 저장된 자성 물질 부분에 데이터가 저장되지 않은 자성 물질과 높낮이 차이가 생기게 된다.

 

[그림 1] 데이터가 저장된 자성 물질의 높낮이

 

[그림 1] 상태에서 데이터를 삭제하기 위해 Wiping을 수행하게 되면 자성 높이가 조금은 낮아지게 된다.

 

하지만 기존 자성 물질들과의 높낮이 차이는 아직 있기에 몇 번의 Wiping을 수행해 그 높낮이 차이를 해소하고 자성 물질의 높낮이 차이를 이용해 데이터를 복구할 수 있다는 이론이 존재하기 때문에 혹시라도 모르는 상황을 대비해 여러 문서에서는 최소 3번 이상의 Wiping을 권고하고 있다.

 

[그림 2] Wiping 수행 후 자성 물질의 높낮이 차이

 

 

1-2. Data Hiding

  • 데이터를 숨기는 행위

  • 데이터가 발견되지 못하게 하거나 발견하기까지 시간이 오래 걸리도록 하기 위한 목적의 기술

  • 대부분 파일 시스템의 비할당 영역이나 예약 영역, 슬랙 영역 등에 데이터를 숨기고는 함

  • 요즘은 포렌식 분석 도구들이 이런 부분도 모두 체크하여 분석해주기 때문에 현재의 포렌식 기술에는 크게 영향을 미치지 못함 

 

1-3. Data Transformation

  • 데이터의 형태를 변환하는 기술

  • 대표적으로 암호화를 들 수 있음

  • 분석가가 데이터의 원본과 의미를 알기까지의 시간을 벌거나 데이터의 본래 의미를 숨길 때 사용하는 기술

 

1-4. Data Contraception

  • 데이터를 분석이 불가능한 위치에 저장해 데이터를 아예 찾지 못하게 하는 기술

  • 해당 기술은 포렌식 데이터의 수집량을 줄이기 위한 것이 가장 큰 목적

 

1-5. Data Fabriacation

  • 데이터 분석의 결과를 잘못된 방향으로 흐르게 하는 기술 및 방법

  • 분석가가 분석하는 데이터를 임의로 조작하여 도출되는 결과를 잘못된 결과로 만드는 기술

  • 데이터 조작에 있어 정교함이 필요한 기술

 

1-6. Preventing Data Creation

  • 포렌식 분석에 필요한 데이터 생성을 하지 않도록 시스템 설정을 변경하는 기술

  • 대표적으로 타임라인 분석에 있어 필요한 타임 스탬프 값의 업데이트를 방지하는 기술

  • Windows 시스템의 경우 레지스트리 값을 조작하여 타임스탬프의 업데이트를 하지 않도록 할 수 있음

 

1-7. Overwriting Metadata

  • 대부분의 파일 시스템에서 데이터가 삭제될 경우 해당 데이터의 메타데이터와 데이터가 저장된 파일 시스템 영역의 링크가 끊어져 사용자에게는 파일이 삭제된 것처럼 보임

  • 파일 시스템에는 사용자가 삭제 명령을 내린 데이터가 고스란히 남아 있음

  • 포렌식 도구들은 이러한 원리를 이용해 메타데이터를 분석하고 해당 메타데이터에 대한 데이터를 찾아 복원시켜줌

  • 해당 기술도 이런 원리를 이용해 메타데이터를 임의의 값으로 덮어 씌워 포렌식 도구나 분석가가 메타데이터를 이용해 데이터를 찾지 못하도록 함

 

1-8. Degaussing

  • 앞에서 언급한 기술들이 모두 소프트웨어적 기술이면 디가우징은 하드웨어적 기술

  • 하드 디스크는 일반적으로 자기성분을 이용해 데이터를 디스크에 쓰는데, 이 자기성분보다 더 강한 자기성분을 디스크에 씌우면 디스크는 자기성분을 이기지 못하고 모든 데이터를 휘발시켜 버림

  • 예전의 일반적인 디가우저(디가우징 장비)는 대상 하드 디스크의 데이터를 모두 삭제 시키고 해당 하드 디스크를 사용하지 못하게 했음

  • 요즘 디가우저는 DDOS라는 기술을 사용해 디가우징이 이루어지고 난 후에도 해당 디스크를 재활용할 수 있게 함

  • 원래 디가우징 기술은 안티 포렌식이 아닌 관공서나 군부대 등에서 비밀을 유지하고 정보 유출 방지를 위해 사용되었지만 요즘은 안티 포렌식에도 가끔 사용

 

안티 포렌식의 기술 종류는 위처럼 매우 다양하다.

 

위 종류들의 안티 포렌식 기술들이 모두 적용되거나 하나의 기술만이라도 완전히 적용 된다면 포렌식 수행 과정은 정말 힘들고 험난할 것이다.

 

하지만, 안티 포렌식 기술의 완전한 성공은 현재로서는 어렵다.

 

포렌식은 사실 컴퓨터를 구성하고 있는 각 부품들과 소프트웨어를 개발하는 업체들에 의해 이루어지고 있다고 해도 과언이 아닐만큼 컴퓨터 부품이나 소프트웨어에서 지원하는 기능과 데이터에 많이 의존한다.

 

안티 포렌식은 포렌식과 달리 받쳐주는 받침대 역할의 부품이나 소프트웨어가 턱없이 부족하기 때문에 안티 포렌식을 완전히 수행할 수는 없다.

 

 

EXFORENSIS 블로그의 블로거는 다음과 같은 이유로 안티 포렌식이 실제 침해사고에서 완전히 성공할 수 없다고 언급하였다.

 

  • 대부분의 파일 삭제 도구들은 파일 삭제 흔적(로그 등)을 남긴다.

  • 대부분의 도구에는 도구가 파일 삭제를 수행할 시 원하는 행위를 하도록 하는 옵션이 존재하지만 이 옵션을 설정한다고 하더라도 도구가 설정된 옵션에 따라 파일을 완전히 삭제하지 못할 수도 있다.

  • 비할당 영역의 데이터를 삭제하는 일은 생각만큼 빨리 끝나지 않는다.

  • 포렌식적으로 의미가 있는 데이터를 오나전히 지우는 도구는 존재하지 않는다.

  • 대부분의 사람들은 비밀번호로 컴퓨터를 보호하기 때문에 데이터의 대한 보안을 생각해 데이터를 주기적으로 완전히 삭제하는 일은 하지 않는다.

 

첫 번째에서 언급한 파일 삭제 도구의 흔적은 우리가 일반적으로 알고 있는 완전 삭제 프로그램인 BCWipe에서도 찾아볼 수 있다.

 

[그림 3] BCWipe 프로그램을 이용한 완전 삭제 시도 장면

 

위 [그림 3]은 BCWipe 프로그램을 이용해 결정적인 증거물을 지우려는 장면이다.

 

BCWipe의 로그는 사실 설정이 필요한 부분이지만, 로그 기능을 지원한다는 점을 중요하게 생각해야 한다.

 

개인이 사용할 때에는 로그 기능을 사용하지 않겠지만, 공공기관이나 기업체에서 사용할 때에는 기록이 중요하기 때문에 로그 기능을 활성화해 두는 일이 많다.

 

[그림 4] BCWipe Log 파일 설정 화면

 

위 설정을 통해 파일 삭제 도구도 기록을 남기고 어떤 파일이 지워졌는지 알아낼 수 있다.

 

물론 원본 파일을 복구하지는 못하겠지만 말이다.

 

안티 포렌식의 기술은 현재로선 완벽하지 못한 기술들이 대부분이다.

 

하지만 포렌식은 피의자 입장에서 생각해봐야 하는 분야이다.

 

그러므로 피의자 입장에서 포렌식을 무력화할 방법은 어떤 것이 있는지, 또 그 방법을 어떻게 찾아내고 대응해야 할 것인지에 대한 연구나 고민을 지속적으로 해야할 것이다.

 

지구 어디에선가 안티 포렌식 기술을 연구해 한 순간에 악성코드나 불법적인 행위를 통해 공개할 수 있다.

 

이렇게 될 경우 해당 안티 포렌식 기술에 대응하기 위해 연구하는 동안 또 다른 추가 피해가 생기고 정상적 침해에 대한 대응을 못할 수도 있다.

 

포렌식 연구가 활발히 진행되는 만큼 안티 포렌식과 관련된 연구도 진행되어야 할 것이다.


# Reference

 

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

[Digital Forensic] PE 구조 분석

 

PE 파일 구조

 

포렌식에서 메모리 분석을 통해 파일을 카빙한다거나 하드디스크 이미지에서 파일을 카빙하여 해당 파일이 무엇인지 분석하려고 할 때 꼭 필요한 지식이기에 PE 구조를 상세하게 공부해 볼 것이다.

 

일반적으로 포렌식에서 파일을 분석할 경우는 악성코드로 의심되는 파일을 분석하는 경우로 정적 분석과 동적 분석을 하게 된다.

 

리버스 엔지니어링 같은 경우에는 정적 분석에 속하며, 정적 분석을 할 경우 어셈블리어와 메모리 구조 등에 대한 지식도 있어야 하지만, PE 구조에 대한 지식도 있어야 하기에 이렇게 상세히 PE 구조를 알아보려고 한다.

 

PE(Portable Executable) 파일 포맷은 윈도우에 해당하는 파일 포맷으로 .exe, .dll, .cpl, .sys, .scr, .drv, .vxd, .ocx 확장자를 가진 파일들에게서 볼 수 있다.

 

PE 구조를 보다 보면 IMAGE로 시작하는 구조체들을 많이 보게 되며, 이는 윈도우에서 실행 파일을 IMAGE라는 명칭으로 대신하기 때문에 구조체 이름도 그렇게 지은 것이다.


PE 구조는 다음 그림과 같다.

 

[그림 1] PE 구조 도식화


(1) DOS 영역

  • 윈도우 실행 파일을 DOS 모드에서 실행하려고 할 때, 사용자에게 에러 메시지를 보여주기 위해 존재

  • 실제로 이 영역은 윈도우 실행 파일이 윈도우에서 실행할 때에는 아무런 영향을 주지 않는 부분이어서 볼만한 내용이 많지 않음

  • DOS MZ Header와 DOS Stub Program 영역으로 이루어짐

 

 

1-1. DOS MZ Header

  • WinNT.h 헤더 파일에 정의되어 있음

  • 눈 여겨 볼 구조체 멤버는 e_magic과 e_lfanew 구조체 멤버

  • 다른 구조체 멤버들은 사용하지 않거나 PE 파일 포맷 내에서는 사실상 의미가 없음

 

e_magic

  • 이 구조체 멤버는 DOS MZ Header의 맨 앞(PE 파일 맨 앞)을 나타내며 16진수는 '4D 5A' 값을 가짐

  • 아스키코드로 변환하면 MZ라는 값을 가짐

  • MZ는 도스를 최초로 설계한 사람 중 한 명인 Mark Zbikowksi의 이니셜

  • 모든 윈도우의 실행 파일은 MZ로 시작하기 때문에 이 값을 검색해 실행 파일을 찾을 수도 있음

 

e_lfanew

  • 이 구조체 멤버는 PE 파일의 머리 격인 IMAGE_NT_HEADER를 가리키는 오프셋 값을 가짐

 

DOS MZ Header의 구조체 구조는 다음과 같다.

 

[그림 2] DOS MZ Header의 구조체 구조

 

 

다음 그림은 notepad.exe의 DOS MZ Header 영역을 보여준다.

 

[그림 3] DOS MZ Header 영역

 

  • 4D 5A : e_magic

  • F0 00 00 00 : e_lfanew (E0 00 00 00)

이 두 값이 올바르면 프로그램은 실행하는데 문제가 없다.

 

 

1-2) Dos Stub Program

  • 사용자가 DOS 모드에서 윈도우용 실행 파일을 실행하였을 때 문구를 출력해주기 위한 코드가 있는 부분

 

출력하는 문구는 다음과 같다.

 

'This Program cannot be run is DOS mode'

 

 

이 부분은 오프셋 0x40 ~ 0x7F까지이다.

 

[그림 4] DOS Stub Program 부분


(2) PE Header 영역

  • PE 파일의 시작 부분

  • PE File Signature, PE File Header, PE File Optional Header 영역이 있음

  • IMAGE_NT_HEADERS 구조체로 이루어짐

[그림 5] IMAGE_NT_HEADERS 구조체 정보

 

위쪽에 정의된 구조체는 32bit 구조체이며 아래는 64bit 구조체이다.

 

어느 정도 직관적인 구조체 멤버 이름을 통해서 왜 PE 헤더 영역이 3가지로 나누여졌는지 알 수 있다.

 

 

2-1. PE File Signature

  • DOS의 e_magic 구조체 멤버처럼 PE 영역의 시작을 알리는 값을 가지고 있는 영역

  • 모든 파일에서 그 값은 항상 동일

  • 그 값은 'PE/0/0(0x50)/0x45/0x00/0x00)'

  • 메모리나 파일 시스템 분석에서 삭제된 실행 파일을 찾는 데에 중요한 단서가 됨

 

PE File Signature 값은 다음 그림과 같다.

 

[그림 6] PE File Signature 영역

 

여기서 중요한 것은 DOS MZ Header 설명 부분에서 설명한 것과 같이 DOS MZ Header 영역의 e_lfanew 구조체 멤버는 IMAGE_NT_HEADER의 주소를 가지고 있다고 설명하였으며, 여기서 그 사실 확인이 가능하다.

 

 

2-2. PE File Header

  • 실행 파일 자체의 메타데이터를 가지고 있음

  • 길이는 20바이트

  • 구조체는 IMAGE_FILE_HEADER 구조체 사용

 

구조체 정보는 다음 그림과 같다.

 

[그림 7] IMAGE_FILE_HEADER 구조체 정보

 

[그림 8] PE Header 영역 오프셋 구조

 

1) Machine

  • 실행 파일이 사용하는 CPU를 나타내는 번호를 가지고 있음 

 

Machine 종류는 다음 표와 같다.

 

 

[표 1] Machine 목록

CPU 종류

설명

IMAGE_FILE_MACHINE_UNKNOWN

0x00

어떤 머신에도 적용이 가능한 종류

IMAGE_FILE_MACHINE_AM33

0x01D3

마쯔시다 AM33

IMAGE_FILE_MACHINE_AMD_64

0x8664

64bit CPU(Intel 포함)

IMAGE_FILE_MACHINE_ARM

0x01C0

ARM(Little Endian)

IMAGE_FILE_MACHINE_EBC

0x0EBC

EFI Byte Code

IMAGE_FILE_MACHINE_I386

0x014C

Intel 386 또는 그 이후 Processor

IMAGE_FILE_MACHINE_IA64

0x0200

Intel Itanium Processor

IMAGE_FILE_MACHINE_M32R

0x9041

미쯔비시 M32(Little Endian)

IMAGE_FILE_MACHINE_MIPS16

0x0266

MIPS16

IMAGE_FILE_MACHINE_MIPSFPU

0x0366

MIPS(FPU 지원)

IMAGE_FILE_MACHINE_MIPSFPU16

0x0466

MIPS16(FPU 지원)

IMAGE_FILE_MACHINE_POWERPC

0x01F0

Power PC(Little Endian)

IMAGE_FILE_MACHINE_POWERCFP

0x01F1

Power PC(부동소수점 지원)

IMAGE_FILE_MACHINE_R4000

0x0166

MIPS(Little Endian)

IMAGE_FILE_MACHINE_SH3

0x01A2

Hitachi SH3

IMAGE_FILE_MACHINE_SH3PSP

0x01A3

Hitachi SH3 DSP

IMAGE_FILE_MACHINE_SH4

0x01A6

Hitachi SH4

IMAGE_FILE_MACHINE_SH5

0x01C2

Thumb

IMAGE_FILE_MACHINE_WCEMIPSV2

0x0169

MIPS(Little Endian WCE V2)

 

 

2) NumberOfSections(NoS)

  • 실행 파일이 가지고 있는 섹션의 개수를 의미

  • 만약 섹션을 삭제, 추가하면 이 구조체 멤버의 값 또한 변경 필요

 

3) TimeDataStamp

  • 실행 파일이 컴파일된 시간으로 이 시간은 컴파일 한 컴퓨터의 시스템 시간을 의미

  • 32비트 유닉스 포맷으로 GMT를 기준으로 함

  • 만약 '0x4A5BC60F' 값이 저장되어 있다면, 이 값을 10진수로 변환하였을 경우 '1247528463'라는 숫자를 의미

 

우리가 알아볼 수 있는 날짜로 변환하게 되면 다음과 같다.

 

[그림 9] Python을 이용하여 변환

 

4) PointerToSymbolTable(PTST)

  • COFF 심볼 파일의 오프셋을 값으로 가짐

  • 컴파일러에 의해 생성된 OBJ 파일이나 디버그 모드로 만들어져 COFF 디버그를 가진 PE 파일에서만 사용됨

  • COFF 심볼 테이블은 이제 더 이상 사용하지 않아 이 값은 반드시 0으로 설정되어야 함

 

5) NumberOfSymbols(NoS)

  • 심볼 테이블에 있는 엔트리 개수를 나타냄

  • COFF 심볼 테이블은 더 이상 사용되지 않으므로 반드시 0으로 설정되어야 함

 

6) SizeOfOptionalHeader(SOOH)

  • Optional Header의 크기를 값으로 가짐

  • 실행 파일에서만 필요하며, 일반적으로 32bit 시스템은 E0의 값을 가짐

 

7) Characteristics(Char)

  • 파일의 속성을 결정하는 값을 가짐

 

Characteristics의 값들은 다음 표와 같다.

 

 

[표 2] Characteristics

속성 이름

설명

IMAGE_FILE_RELOCS_STRIPPED

0x0001

실행 파일 전용, 이 파일은 재배치되지 않으므로 반드시 지정된 베이스 주소에 로그 필요, 지정된 베이스 주소가 사용 불가능하면 에러 발생

IMAGE_FILE_EXECUTABLE_IMAGE

0x0002

실행 파일 전용, 실행 파일은 검증되었으며 실행 가능, 이 값이 설정되어 있지 않으면 그것은 링크 에러 의미

IMAGE_FILE_LINK_NUMB_STRIPED

0x0004

COFF 라인 번호는 더 이상 사용하지 않으므로 이 값은 반드시 0이어야 함

IMAGE_FILE_LOCAL_SYMS_STRIPED

0x0008

로컬 심볼에 대한 COFF 심볼 테이블은 더 이상 사용하지 않으므로 이 값은 반드시 0이어야 함

IMAGE_FILE_AGGRESIVE_ES_TRIM

0x0010

해당 값은 윈도우 2000과 그 이후 버전에서는 더 이상 사용되지 않으므로 반드시 0이어야 함

IMAGE_FILE_LARGE_ADDRESS_AWARE

0x0020

애플리케이션은 2GB보다 큰 주소를 다룰 수 있음

?????

0x0040

예약 영역

IMAGE_FILE_BYTES_REVERSED_LO

0x0080

Little Endian, 해당 필드는 더 이상 사용하지 않으므로 반드시 0이어야 함

IMAGE_FILE_32BIT_MACHINE

0x0100

머신이 32bit Processor를 사용

IMAGE_FILE_DEBUG_STRIPED

0x0200

해당 실행 파일에는 디버깅 정보가 없음

IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP

0x0400

해당 실행 파일이 이동형 저장 장치에 있다면 실행 파일 전체를 페이지 파일로 복사함 

IMAGE_FILE_NET_RUN_FROM_SWAP

0x0800

해당 실행 파일이 네트워크로 연결된 저장 장치에 있다면 실행 파일 전체를 페이지 파일로 복사

IMAGE_FILE_SYSTEM

0x1000

이 실행 파일은 시스템 파일

IMAGE_FILE_DLL

0x2000

해당 실행 파일은 DLL 파일, 사실상 실행 파일로 취급

IMAGE_FILE_SYSTEM_ONLY

0x4000

해당 파일은 오직 Single Processor가 있는 머신에서만 실행되어야 함

IMAGE_FILE_BYTES_REVERSED_HI

0x8000

Big Endian, 해당 필드는 더 이상 사용되지 않으므로 0값을 가져야 함

 

PE Header 영역의 세 번째 영역인 PE File Optional Header 영역을 알아보기 전에 알아두어야 할 개념은 바로 RVA이다.

 

PE File Optional Header 영역에서 자주 언급되기 때문에 미리 알아두고 이해하는 것이 훨씬 효과적이다.

 

 

2-3. RVA (Relative Virtual Address)

  • 실행 파일이 프로세스를 만들고 실행 파일의 코드와 데이터가 가상 메모리에 맵핑이 되면 메모리에 맵핑되는 지점의 시작 주소가 베이스 주소가 됨

  • RVA는 가상 메모리 상의 베이스 주소를 기준으로 로드된 실행 파일의 상대적 위치를 의미

 

가상 메모리에서의 가상 주소는 아래와 같은 형식으로 구할 수 있다.

 

 

가상 주소 = 베이스 주소(Base Address) + RVA

 

 

RVA는 가상 메모리에 맵핑된 이후의 오프셋 값이므로 PE 파일상의 오프셋과 같다고 생각하면 안된다.

 

물론 PE 파일은 가상 메모리에 그대로 맵핑이 되어 순서가 맵핑 되기 전과 같지만, 가상 메모리에 맵핑이 되면 섹션 사이에 패딩이 생겨 오프셋 값이 달라진다.

 

 

2-4. PE File Optional Header

  • 실행 파일의 실행 정보가 담긴 부분

  • 필수적인 부분이므로, PE File Header보다 더 중요

  • Option이라는 이름이 붙은 이유는 오브젝트가 이 영역을 선택적으로 가질 수 있기 때문

  • 정작 오브젝트에서는 별다른 기능을 발휘하지 않음

 

PE File Optional Header 부분은 IMAGE_OPTIONAL_HEADER 구조체로 되어 있다.

 

크기가 유동적이고 앞서 보았던 IMAGE_NT_HEADER의 SizeOfOptionalHeader 구조체 멤버에 의해 크기가 결정되고, PE File Header 바로 뒤에 위치 한다.

 

IMAGE_OPTIONAL_HEADER 구조체는 Standard Fields, NT additional Fields, IMAGE_DATA_DIRECTORY로 구분이 된다.

 

 

Standard Fields

  • 파일을 로드하고 실행하는 것에 대한 정보가 들어있음

[그림 10] Standard Fields

 

[그림 11] Standard Field 영역 오프셋 구조

 

1) Magic

  • 실행 파일의 상태를 나타내는 부호 없는 정수 값을 가짐

  • 이 값이 '0x010B' 라면 일반적인 실행 파일을 뜻하며, '0x0107' 이라면 ROM 이미지, '0x020B'라면 64bit Executable 타입이라는 것을 의미

 

2) MajorLinkerVersion(V1)

  • 링커의 상위 버전 넘버를 저장하는 멤버

 

3) MinorLinkerVersion(V2)

  • 링커의 하위 버전 넘버를 저장하는 멤버

 

4) SizeOfCode

  • 코드 섹션(.text)의 크기 정보를 가지고 있음

  • 코드 섹션이 여러 개라면 그것들의 합에 대한 값을 가짐

 

5) SizeOfInitialized Data

  • 초기화된 데이터 섹션의 크기를 값으로 가짐

  • SizeOfCode 멤버와 마찬가지로 자신이 담당하고 있는 섹션의 수가 여러 개라면 그들의 합에 대한 값을 가짐

 

6) SizeOfUninitialized Data

  • 초기화되지 않은 데이터 섹션의 크기를 값으로 가짐

  • 섹션이 여러 개일 경우 SizeOfInitialized Data 구조체 멤버와 동일한 성격을 가짐

 

7) AddressOfEntry Point

  • 메모리에 맵핑된 상태에서의 실행 코드 주소를 가짐

  • 이 주소는 절대적 주소가 아닌 상대적 주소(RVA)

  • 보통 .text 섹션 내의 특정 주소를 가리킴

  • 실행 파일에서의 이 주소는 실행 코드의 시작 주소

  • 디바이스 드라이버에서는 초기화 함수의 주소가 됨

  • 반면 DLL 파일은 이 값이 선택적이며, 이 값이 없다면 반드시 0으로 되어야 함

 

8) BaseOfCode

  • 실행 파일이 메모리에 맵핑된 상태에서의 코드 섹션(.text) 주소를 가짐

  • 이 값은 상대적 주소인 RVA 값

 

9) BaseOfData

  • 실행 파일이 메모리에 맵핑된 상태에서의 데이터 섹션(.data) 주소를 가짐

  • 이 값은 상대적 주소인 RVA 값

 

 

NT Additional Fields

  • 해당 영역은 Standard Fields 바로 다음부터 시작되며, 많은 구조체 멤버로 이루어짐

  • 이 영역에서 제공되는 정보는 윈도우 링커와 로더가 사용하는 정보

 

다음 그림은 해당 영역의 오프셋 구조이다.

 

[그림 12] NT Additional Fields

 

[그림 13] NT Additional Fields 영역 오프셋 구조

 

1) ImageBase

  • 가상 메모리에 로드된 실행 파일의 주소를 가짐

  • 이 값은 반드시 64KB이어야 함

  • ImageBase 구조체 멤버 값과 Standard Fields의 BaseOfCode 값을 더하면 .text 섹션의 가상 메모리 주소

 

2) SectionAlignment

  • 가상 주소에 맵핑될 때 섹션이 할당 받을 가상 주소의 기준 값을 가짐

  • 섹션은 메모리에 맵핑될 때 섹션별로 맵핑되기 때문

  • 섹션의 시작 주소는 항상 메모리 페이지의 배수여야 하므로 이 값은 FileAlignment와 같거나 커야 함

  • 기본 값은 페이지의 크기와 같음

 

3) FileAlignment

  • PE 파일 내에서 섹션들이 시작하는 주소의 기준 값

  • 따라서 PE 파일 내에서의 섹션이 시작하는 주소는 항상 이 값의 배수가 됨

  • 이 값은 2에서 512 사이에 있는 2의 제곱이거나 64KB가 되지만 기본 값은 512

  • SectionAlignment의 값이 메모리 페이지 크기보다 작다면 FileAlignment의 값과 동일해야 함

 

4) MajorOperatingSystemVersion(mOS1)

  • 실행 파일을 실행하는데 필요한 OS의 최소 상위 버전 값을 가짐

 

5) MinorOperationSystemVersion(mOS2)

  • 실행 파일을 실행하는데 필요한 OS의 최소 하위 버전 값을 가짐

 

6) MajorImageVersion(mIV1)

  • 실행 파일의 상위 버전의 값을 가짐

 

7) MinorImageVersion(mIV2)

  • 실행 파일의 하위 버전의 값을 가짐

 

8) MajorSubsystem(mSV1)

  • 실행 파일을 실행하는데 필요한 서브 시스템의 상위 버전의 값을 가짐

 

9) MinorSubsystem(mSV2)

  • 실행 파일을 실행하는데 필요한 서브 시스템의 하위 버전의 값을 가짐

 

10) Win32Version

  • 이 멤버는 VC++6.0 SDK까지는 예약 영역이었음

  • 7.0부터 지금의 이름으로 바뀌었으며, 하지만 여전히 사용하지 않아 보통 0으로 되어 있음

 

11) SizeOfImage

  • 메모리에 로드 되었을 때 실행 파일의 크기 값을 가짐

  • 이 값은 헤더를 포함했을 때의 크기이며, 반드시 SectionAlignment의 배수여야 함

  • 이 값을 기준으로 해서 가상 메모리에서 실행 파일을 맵핑할 공간을 예약

 

12) SizeOfHeader

  • DOS Stub, PE 헤더, 섹션 헤더의 합 값을 가짐

  • 이 값은 무조건 FileAlignment의 배수여야 함

 

13) Checksum

  • 실행 파일의 체크섬 값을 가짐

  • 체크섬 알고리즘은 IMAGEHELP, DLL 파일에 있으며 이 값은 모든 드라이버와 부팅 시 로드 된 DLL 파일, 중요한 윈도우 프로세스가 로드한 DLL 파일을 검증할 때 사용

 

14) Subsystem

  • 실행 파일을 실행하는데 필요한 서브 시스템의 값을 가짐

 

다음 표는 Subsystem 값 목록표이다.

 

 

[표 3] Subsystem 값 목록표

상수

값 

목록표

IMAGE_SUBSYSTEM_UNKNOWN

0

알 수 없는 SubSystem

IMAGE_SUBSYSTEM_NATIVE

1

디바이스 드라이버와 Native Windows Process

IMAGE_SUBSYSTEM_WINDOWS_GUI

2

Windows GUI SubSystem

IMAGE_SUBSYSTEM_WINDOWS_GUI

3

Windows CUI SubSystem

IMAGE_SUBSYSTEM_POSIX_CUI

7

Posix CUI Subsystem

IMAGE_SUBSYSTEM_WINDOWS_CE_GUI

9

Windows CE

IMAGE_SUBSYSTEM_EFI_APPLICATION

10

EFI (Extensible Firmware Interface) Application

IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER

11

Boot Service가 있는 EFI 드라이버

IMAGE_SUBSYSTEM_RUNTIME_DRIVER

12

Runtime Service가 있는 EFI 드라이버

IMAGE_SUBSYSTEM_EFI_ROM

13

EFI ROM Image

IMAGE_SUBSYSTEM_XBOX

14

XBOX

 

15) DLLchr(DllCharacteristics)

  • PE 파일이 DLL 파일인 경우 파일의 속성정보를 의미

 

16) SizeOfStackReserve

  • 예약할 스택의 크기 값을 가짐

 

17) SizeOfStackCommit

  • 커밋할 스택의 크기 값을 가짐

 

18) SizeOfHeapReserve

  • 예약할 힙의 크기 값을 가짐

19) SizeOfHeapCommit

  • 커밋할 힙의 크기 값을 가짐

 

20) LoaderFlags

  • 예약된 영역으로 0으로 채워져 있음

 

21) NumberOfRvaAndSize

  • Optional Header의 나머지 부분에 있는 데이터 디렉토리 엔트리의 숫자 값을 가짐

 

 

IMAGE_DATA_DIRECTORY

  • WinNT.h를 보면 IMAGE_OPTIONAL_HEADER 안에 있지만, 사실은 NT Additional Fields 하부 구조체

 

구조체 선언은 다음 그림과 같다.

 

[그림 14] IMAGE_DATA_DIRECTORY 구조체

 

WinNT.h에 명시되어 있는 것을 보면 IMAGE_DATA_DIRECTORY의 엔트리 개수는 16개로 정의되어 있다.

 

[그림 15] 엔트리 정의

 

[그림 16] 엔트리 목록

 

엔트리는 [그림 16]과 같이 정의되고, 마지막은 0으로 예약되어 있기 때문에 16개가 되는 것이다.

 

[그림 17] 엔트리 오프셋 구조

 

각 부분은 주소와 크기로만 나누어진다.


(3) Section

3-1) Section Header

  • 섹션 헤더 영역에는 각 세션의 헤더들이 있으며, 섹션들은 이 헤더에 메타 데이터와 메모리에 로드될 때 필요한 정보를 저장

 

섹션 헤더의 구조체 형태는 다음 그림과 같다.

 

[그림 18] IMAGE_SECTION_HEADER 구조체

 

위 [그림 18]에는 보이지 않지만 IMAGE_SIZEOF_SHORT_NAME은 8바이트로 정의되어 있으며, 이름 길이가 8바이트를 넘어가게 되면 8바이트 이후는 잘리며, 8바이트 보다 짧을 경우 남는 공간은 NULL로 채워진다.

 

 

다음 그림은 .text 섹션의 헤더 영역 오프셋 구조이다.

 

[그림 19] IMAGE_SECTION_HEADER 오프셋 구조

 

1) Name

  • 섹션의 이름 부분

  • 8바이트 내에서 사용자가 임의로 수정 가능 

 

2) VirtualSize

  • 메모리에 로드되는 섹션의 전체 크기

  • 이 필드는 실행 파일에서만 존재하고 오브젝트 파일에서는 0으로 설정되어 있음

  • SizeOfRawData보다 크다면 섹션의 나머지 부분은 0으로 채워짐

 

3) VirtalAddress

  • 메모리에 로드 되었을 때의 RVA 값을 가짐

  • 오브젝트 파일의 경우 0으로 설정 됨

 

4) SizeOfRawData

  • 실행 파일의 경우 디스크 상에서 초기화된 데이터의 크기를 말함

  • Optional Header의 FileAlignment 값의 배수이어야 함

  • VirtualSize보다 작다면 섹션 나머지 부분은 0으로 채워짐

  • 오브젝트 파일의 경우 0으로 설정 됨

 

5) PointerToRawData(PotToRawData)

  • PE 파일 내에서의 섹션 위치의 오프셋을 값으로 가짐

  • 실행 파일의 경우 이 값은 무조건 FileAlignment의 배수여야 함

 

6) PointerToRelocations(PotToRelocations)

  • 섹션 재배치에 대한 시작 지점 오프셋을 값으로 가짐

  • 이 값은 보통 오브젝트 파일에 사용

  • 실행 파일의 경우 0으로 설정 됨

 

7) PointerToLineNumbers(PotToLineNumbers)

  • 해당 섹션에 대한 Line-Number 엔트리의 시작 지점 주소 값을 가짐

  • Line-Number 엔트리는 COFF 포맷으로 지금은 사용하지 않기 때문에 0으로 설정 되어 있음

 

8) NumberOfRelocations(Nolo)

  • 해당 섹션의 재배치 엔트리 숫자를 값으로 가짐

  • 실행 파일의 경우 항상 0으로 설정되어 있음

 

9) NumberOfLineNumber(Nolo)

  • 해당 섹션에 대한 Line-Number 엔트리의 숫자를 가짐

 

10) Characteristics

  • 해당 섹션의 속성 정보를 표시하는 값을 가짐

 

 

Characteristics에 대한 속성 목록은 다음 표와 같다.

 

[표 4] 속성 목록표

종류

설명

IMAGE_SCN_CNT_CODE

0x00000020

실행 코드를 가지고 있음

IMAGE_SCN_CNT_INITIALIZED_DATA

0x00000040

초기화된 데이터를 가지고 있음

IMAGE_SCN_CNT_UNINITIALIZED_DATA

0x00000080

초기화되지 않은 데이터를 가지고 있음

IMAGE_SCN_MEM_NOT_CACHED

0x04000000

캐시될 수 없음

IMAGE_SCN_MEM_NOT_PAGED

0x08000000

페이징되지 않음

IMAGE_SCN_MEM_SHARED

0x10000000

메모리에서 공유될 수 없음

IMAGE_SCN_MEM_EXECUTE

0x20000000

코드로서 실행될 수 없음

IMAGE_SCN_MEM_READ

0x40000000

읽기가 가능

IMAGE_SCN_MEM_WRITE

0x80000000

쓰기가 가능

 

더 많은 속성들이 있지만 중요한 것만 목록화 한 내용이다.

 

더 많은 속성들은 WinNT.h 파일을 참고하면 확인 가능하다.

 

만약 섹션 이름이 임의로 바뀌어 어떠한 섹션인지 파악이 되지 않는다면 섹션 속성 정보를 보는 것도 하나의 방법이다.

 

섹션 속성 정보들은 각 섹션마다 기본적으로 정의되어 있어 섹션 속성 정보만 봐도 어떠한 섹션인지 파악 가능하다.

 

 

앞에서 알아본 PE 구조들은 실행 파일들의 정보나 메모리에 로드될 때의 정보 등이었다.

 

이제 알아볼 섹션은 실행 파일의 동작에 관한 정보들이다.

 

섹션에는 여러 가지 섹션이 있는데, 대부분 .text, .data, .rdata, .rsrc, .edata, .idata, .reloc 섹션이 많이 사용된다.

 

 

분석하고자 하는 파일의 섹션 정보는 PE File Header를 보면 NumberOfSections에 색션 개수가 나타나 있으며, 각 섹션의 위치 정보 등은 Section Header 영역을 보면 확인할 수 있다.

 

[그림 20] NumberOfSections

 

[그림 21] 섹션 헤더 영역의 섹션 이름

 

 

3-2. .text 섹션

  • 실행 파일의 소스코드가 들어있는 섹션

  • 초기화되거나 초기화되지 않은 변수, import와 export 테이블 정보를 제외한 나머지 소스코드들이 저장됨

 

해당 섹션의 기본 속성 정보는 다음과 같다.

  • IMAGE_SCN_CNT_CODE

  • IMAGE_SCN_MEM_EXCUTE

  • IMAGE_SCN_MEM_READ

 

섹션의 위치와 크기는 섹션 헤더(PointerToRawData, SizeOfRawData)를 참고하면 알 수 있으며 .text 섹션 헤더에서의 PE 파일 내에서의 .text 섹션 위치와 크기를 확인할 수 있다.

 

[그림 22] .text 섹션의 오프셋과 크기

 

위 [그림 22]의 빨간색 박스를 보면 PE 파일 내에서의 주소를 확인할 수 있다.

 

.text 섹션의 마지막 오프셋은 주소와 크기를 더하게 되면 결과 값이 나오게 된다.

 

.text 섹션의 마지막 오프셋으로 이동한 다음, 섹션의 모습을 보면 어느 정도 데이터가 있다가 나머지는 0으로 채워져 있는 것을 확인할 수 있다.

 

이러한 이유는 SizeOfRawData의 경우 FileAlignment(IMAGE_OPTIONAL_HEADER)의 배수가 되어야 하므로 실제 데이터의 크기를 가지고 있는 VirtualSize 값을 FileAlignment의 값의 배수로 올림하여 크기가 늘어나 채울 데이터가 없어 0으로 채운 것이다.

 

실제 메모리에 .text 섹션이 올라갈 때는 0을 제외하고 올라가게 된다.

 

 

이러한 방법으로 모든 섹션의 영역을 찾을 수 있다.

 

이 방법을 계속 섹션마다 사용하여 영역을 찾는 것을 보여줄 수는 없기 때문에 이후에 나오는 섹션들은 특징과 속성 정보 등만 소개한다.

 

 

3-3. .data 섹션

  • 읽기/쓰기가 가능한 일반적인 데이터를 위한 섹션

  • 정적 변수와 전역 변수가 저장

 

해당 섹션의 기본 속성 정보는 다음과 같다.

  • IMAGE_SCN_CNT_INITIALIZED_DATA

  • IMAGE_SCN_MEM_READ

  • IMAGE_SCN_MEM_WRITE

 

 

3-4. .rdata 섹션

  • 읽기 전용 섹션으로 상수와 배열로 직접 정의된 문자열과 런타임 라이브러리에서 사용하는 에러 메시지 등이 저장

 

해당 섹션의 기본 속성 정보는 다음과 같다.

  • IMAGE_SCN_CNT_INITIALIZED_DATA

  • IMAGE_SCN_MEM_READ

 

 

3-5. .idata, .edata 섹션

  • .idata 섹션은 import table이 들어 있으며, .edata 섹션은 export table이 의미

  • 이 섹션들은 실행하는데 꼭 필요한 섹션은 아님

 

.idata 섹션의 기본 속성 정보는 다음과 같다.

  • IMAGE_SCN_CNT_INITIALIZED_DATA

  • IMAGE_SCN_MEM_READ

  • IMAGE_SCN_MEM_WRITE

 

.edata 섹션의 기본 속성 정보는 다음과 같다.

  • IMAGE_SCN_CNT_INITIALIZED_DATA

  • IMAGE_MEM_READ

 

 

3-6. .reloc 섹션

  • PE 파일이 메모리 상에 로드될 때 재배치에 관해 참조하는 정보가 들어있는 섹션

  • 실행 파일의 경우 이 섹션은 필요하지 않을 수 있지만, DLL 파일의 경우 메모리에 로드될 때 재배치를 염두하고 있기 때문에 이 섹션이 없으면 실행되지 않을 수도 있음

 

.reloc 섹션의 기본 속성 정보는 다음과 같다.

  • IMAGE_SCN_MEM_READ

  • IMAGE_SCN_CNT_INITIALIZED_DATA

  • IMAGE_SCN_TYPE_NOLOAD

 

이렇게 해서 PE 포맷을 모두 알아보았다.

 

조금만 더 깊숙이 들어가면 그 구조는 매우 복잡하며, 알아야 할 것들이 너무 많기 때문에 포렌식 업무를 수행함에 있어 알아두어야 할 것들만 소개하였다.

 

앞서 말했듯이 PE 포맷은 파일 카빙, 파일 시그니처 탐지에 유용하게 사용될 수 있어 이렇게 소개하였다.

 

포렌식 관점에서 PE 구조를 보면 파일 생성 시간 값을 저장하는 PE File Header 영역에 TimeDataStamp 구조체 멤버가 중요하고 또 파일의 종류를 결정하는 PE File Header 영역에 Characteristics 구조체 멤버가 중요하다.


# Reference

 

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

[Digital Forensic] Registry 분석

 

레지스트리 분석


(1) 레지스트리란?

  • 윈도우 포렌식에서 메모리 분석과 함께 제일 중요하게 여겨지고 있는 분석

  • 윈도우에서의 모든 정보가 저장되어 있는 데이터베이스

  • 윈도우 3.1부터 시작되었으며, 시작은 .ini 파일처럼 단순 구조로 시작

  • 모든 정보가 저장되어 있는 만큼 포렌식 과정에서 얻고자 하는 정보도 들어 있음

  • 오늘 날의 레지스트리는 복잡하고 양이 매우 방대

 

1-1. 레지스트리 용어

 

[그림 1] 레지스트리 키 설명

 

  • 루트키 : 레지스트리 최상위 키

  • 서브키 : 루트키 하위에 있는 키, 메모리에만 존재

  • 키 : 레지스트리에서 폴더처럼 데이터를 가지고 있는 것

 

[그림 2] value와 data

 

  • value : 폴더에 속한 파일처럼 키에 속한 값의 이름

  • data : value가 가지고 있는 값

  • Hive : 서브키 아래의 트리 구조를 의미하며 서브키와 달리 하드디스크 상에 파일로 존재

 

많이 쓰이는 루트키의 용어는 다음과 같다.

 

  • 1) HKCR : HKEY_CLASSES_ROOT의 약자

  • 2) HKCU : HKEY_CURRENT_USER의 약자

  • 3) HKLM : HKEY_LOCAL_MACHINE의 약자

  • 4) HKU : HKEY_USERS의 약자

  • 5) HKCC : HKEY_CURRENT_CONFIG의 약자


1-2. 루트키

  • 총 5개의 루트키로 이루어짐

  • 루트키들 중 파일로 존재하는 HKLM, HKU는 Master key이며 나머지 루트키들은 Derived key

  • Master key는 Derived key의 원본을 말하며, Windows의 Configuration Manager가 각 하이브 파일을 읽어 구성하는 값들

  • Derived key는 Master key의 심볼릭 링크 값들을 말하며, 해당 값들은 파일로 존재하지 않으며 메모리에만 존재하기 때문에 시스템 전원(On/Off) 상태에 따라 유지나 재구성 됨

 

[그림 3] 루트키

 

  • HKEY_CLASSES_ROOT : 파일 확장자와 확장자가 사용할 프로그램의 맵핑 정보가 정의

  • HKEY_CURRENT_USER : 현재 시스템에 로그온하고 있는 사용자가 설정한 시스템 환경 정보(네트워크, 응용 프로그램 등의 정보)가 정의

  • HKEY_LOCAL_MACHINE : 시스템의 하드웨어 구성에 필요한 초기화 파일과 소프트웨어 정보, 드라이버 정보 등이 정의

  • HKEY_USER : 시스템에 있는 모든 계정과 그룹에 대한 시스템 환경 정보가 정의

  • HKEY_CURRENT_CONFIG : 시스템이 부팅 시 사용하는 하드웨어 프로파일 정보(글꼴, 프린터 정보 등의 부가적 정보)가 정의

 

HKLM과 HKU는 독자적인 정보를 가지고 있는 반면에 HKCU, HKCR, HKCC는 독자적 정보가 아닌 HKLM과 HKU의 심볼릭 링크 정보로 이루어져 있다.

 

즉 HKLM, HKU 루트키는 Master Key에 해당하며, 나머지 HKCU, HKCR, HKCC는 Derived Key에 해당

 

 

1) HKEY_CLASSES_ROOT

  • 해당 루트키는 하위 서브키로 HKLM\SOFTWARE\Classes와 HKU\<SID>\Classes의 심볼릭 링크 정보를 가짐 (.btapp)

  • .btapp 서브키는 HKCR에는 존재하지만, HKLM의 서브키에는 존재하지 않음

  • HKCR은 자신만의 서브키가 없고 HKLM과 HKU의 Classes 서브키 심볼릭 정보를 가져와 자신의 서브키로 만듦

  • HKCR은 많은 양의 하위 키들을 가지고 있으며, 대부분의 서브키들은 HKLM의 심볼릭 링크 서브키를 뜻함

  • 나머지 서브키들은 HKU에서 가져옴

 

HKCR은 파일과 프로그램간의 맵핑 정보를 담당한다고 하였다.

 

HKCR 서브키들 중 .mp3라는 서브키의 데이터를 보면 다음 그림과 같다.

 

[그림 4} HKCR 서브키 .mp3

 

각 value와 data를 .mp3를 실행하는 프로그램의 정보가 들어 있는데 (기본값) 은 value가 정해지지 않았을 때 default로 정해지는 value이며, 키당 하나만 생성이 가능하다.

 

(기본값)에서 가리키고 있는 곳으로 따라가면 프로그램의 전체 경로와 명령어 옵션을 알 수 있다.

 

[그림 5] (기본값)이 가리키는 곳

 

기본값이 가리키는 키의 하위 키인 Shell키의 Open\Command 키로 가면 [그림 5]와 같이 프로그램을 실행시키는 명령 행과 옵션을 볼 수 있다.

 

 

2) HKEY_CURRENT_USER

  • 현재 로그온한 사용자의 정보를 서브키로 가짐

  • 이 서브키들은 HKU 루트키에서 가져온 것들 

[그림 6] HKCU 서브키의 출처

 

[그림 6]을 보면 HKU 서브키들 중 S1002 계정의 서브키들이 HKCU의 서브키와 동일한 것을 볼 수 있다.

 

즉 현재 S1002 계정이 로컬에 로그온되어 있다는 뜻이 된다.

 

각 서브키들이 어떠한 의미를 뜻하는지는 다음과 같다.

 

 

3) HKCU 서브키

  • AppEvent : 이벤트 정보

  • Console : 명령 프롬프트의 비쥬얼 설정 정보

  • Control Panel : 화면 보호기, 키보드/마우스 등의 환경설정 정보

  • Environment : 환경 변수 정보

  • EUDC : 최종 사용자가 정의한 문자 정보

  • Identifies : 윈도우 메일 계정 정보

  • Keyboard Layout : 키보드 레이아웃 설정 정보

  • Network : 네트워크 드라이브 맵핑 정보

  • Printers : 프린터 연결 정보

  • Sessions information : 현 세션의 정보

  • Software : 현재 로그온한 사용자의 소프트웨어 목록

  • UNICODE Program groups(Win XP) : 현재 로그온한 사용자가 지정한 '시작' 메뉴 환경 설정 정보

  • system(Win 7) : HKLM/SYSTEM 서브키의 일부

  • Volatile Environments : 휘발성 환경 변수 정보

 

 

4) HKEY_USERS

  • 시스템의 모든 계정 정보를 담고 있는 루트키

  • 루트키와 각 서브키의 계정 프로파일이 있다는 것만 제외하면 HKU의 서브키들은 HKCU 서브키와 동일

  • 계정 프로파일은 각 키들의 (기본값)에 링크되어 있음

 

다음은 HKU를 구성하는 하이브들의 목록과 하이브들의 저장 경로이다.

 

HKU\<로컬 사용자의 계정 SID>

  • Win XP : Documents and Settings\LocalService\NTUSER.DAT

  • Win Vista/7 : %System Root% \ServiceProfiles\LocalService\NTUSER.DAT

HKU\<네트워크 사용자 계정 SID>

  • Win XP : Documents and Settings\NetworkService\NTUSER.DAT

  • Win Vista/7 : %System Root% \ServiceProfiles\NetworkService\NTUSER.DAT

HKU\<사용자 SID>

  • Win XP : Documents and Settings\<user name>\NTUSER.DAT

  • Win Vista/7 : Users\%UserName%\NTUSER.DAT

HKU\<사용자 SID>_Classes

  • Win XP : Documents and Settings\<user name>\LocalSettings\ApplicationData\Microsoft\Windows\UsrClass.dat

  • Win Vista/7 : Users\%UserName%\AppData\Local\Microsoft\Windows\UsrClass.dat

HKU\.DEFAULT

  • %System Root% \System32\Config\Default

 

%System Root%는 Windows의 루트 위치를 말하며 Windows 운영체제가 설치된 드라이브의 Windows 폴더를 의미한다.

 

 

5) HKEY_CURRENT_CONFIG

  • 시스템이 시작할 때 사용되는 하드웨어 프로파일을 저장

  • 별도의 하이브를 갖고 있지 않음

  • 프로그램이 현재 활성화된 하드웨어를 알아보기 위해 이 루트키 참조

 

 

6) HKEY_LOCAL_MACHINE

  • 자체 하이브를 갖고 있으며, 시스템의 하드웨어, 소프트웨어 드라이버의 환경설정 정보를 가짐

  • HKLM 하이브 중 일부는 관리자 계정으로도 접근하지 못하는 하이브가 있으며, 시스템 계정으로 접근 가능

 

HKLM 하위 하이브 목록과 위치는 다음과 같다.

 

  • HKLM\BCD00000000(Win Vista/7) : <Boot Partition> \Boot\BCD

  • HKLM\COMPONENTS(Win Vista/7) : %SystemRoot%\System32\Config\COMPONENTS

  • HKLM\HARDWARE : 메모리

  • HKLM\SAM : %SystemRoot% \System32\Config\SAM

  • HKLM\SECURITY : %SystemRoot% \System32\Config\SECURITY

  • HKLM\SOFTWARE : %SystemRoot% \System32\Config\SOFTWARE

  • HKLM\SYSTEM : %SystemRoot% \System32\Config\SYSTEM

  • HKLM\SYSTEM\Clone : 메모리

 

위에서 알 수 있듯이 하이브는 모두 확장자가 없으며, HARDWARE와 Clone 하이브는 메모리에 존재한다.

 

그러므로 Live Response 과정에 이러한 휘발성 하이브에 대한 덤프 수집 부분도 추가하는 것이 좋다.

 

 

이제부터는 각 하이브에 대해 알아보도록 하자.

 

1) HKLM\HARDWARE

  • 해당 하이브는 휘발성 정보로 메모리에 존재

  • 모니터 포트 등 부팅 시 관련된 하드웨어 장치와 드라이버 맵핑 정보들을 저장

  • 중요한 것은, 하이브 파일이 존재하지는 않지만 Derived Key가 아님

 

2) HKLM\SAM

  • 해당 하이브는 사용자의 로컬 계정 정보(사용자 패스워드, 사용자 프로필 등)와 그룹 정보를 갖고 있음 (리눅스 /etc/passwd와 비슷)

  • 만약 조사하고자 하는 시스템이 도메인 컨트롤러라면 AD(Active Directory)에 도메인 계정과 그룹 정보를 가짐

  • 이 하이브는 일반 관리자 계정으로도 접근이 불가능하며, 시스템 계정으로만 접근 가능

 

시스템 계정 권한을 얻는 방법에는 여러 가지가 있으며 대체로 조사 과정에서는 통합 포렌식 도구들을 통해 얻는다.

 

대표적인 도구로는 psExec를 이용하여 일시적으로 얻는 방법이 있다.

 

 

3) HKLM\SECURITY

  • 이 하이브는 시스템 범위의 보안 정책과 사용자 권한 할당 정보, 현재 시스템의 패스워드 또는 마지막 로그온 사용자의 패스워드 등의 정보를 가짐

  • 이 하이브 또한 시스템 계정으로만 접근이 가능하며 위 SAM 접근했던 방식과 동일하게 접근 가능

  • 시스템 계정이 아닌 경우에 해당 하이브의 하위에는 아무것도 없는 것처럼 보이지만, 시스템 계정 권한으로 접근하면 많은 서브키들을 볼 수 있음

 

4) HKLM\SYSTEM

  • 해당 하이브는 시스템이 부팅될 때의 환경 설정 정보를 가짐

  • 이런 정보들은 시스템이 정상적 부팅되었을 때 복사되며, 시스템이 비정상적으로 종료되었을 때 복사해 둔 정보를 바탕으로 부팅할 수 있는 옵션을 사용자에게 제공

  • 이런 복사본은 일반적으로 '마지막으로 성공한 구성'이라고 부름

  • 해당 하이브에서 중요한 것은 바로 CurrentControlSet 키

 

CurrentControlSer 키는 ControlSet001이나 또는 ControlSet002 둘 중 어느 하나의 대한 링크이다.

 

ControlSet은 시스템 환경 설정 정보를 담고 있는 키로 보통 2개 이상의 키가 존재한다.

 

CurrentControlSet은 부팅에서 사용된 ControlSet 키의 링크이고, 같은 레벨에 있는 Select 키에서 확인 가능하다.

 

예를 들어, Current value의 값이 1로 되어 있으면, 이것의 의미는 ControlSet001로 부팅되었다는 의미이다.


1-3. HKCU 서브키 타입

 

[그림 7] 데이터 타입

 

레지스트리를 보면 [그림 7]과 같은 데이터 타입들이 존재한다.

 

레지스트리에는 여러 가지 데이터 타입들이 존재하는데 데이터 타입들은 다음 표와 같다.

 

 

[표 1] 데이터 타입 목록

종류

설명

REG_NONE

0x00

타입 없음

REG_SZ

0x01

고정 길이의 유니코드 문자열

REG_EXPAND_SZ

0x02

Embeded 환경 변수들이 가질 수 있는 가변 길이 유니코드 문자열

REG_BINARY

0x03

Binary Data

REG_DWORD

0x04

32bit Integer

REG_DWORD_LITTLE_ENDIAN

0x04

32bit Integer, Little Endian 방식

REG_DWORD_BIG_ENDIAN

0x05

32bit Integer, Big Endian 방식

REG_LINK

0x06

Unicode Symbolic Link

REG_MULTI_SZ

0x07

Unicode 문자열의 배열, Null 문자가 문자열의 끝을 의미

REG_RESOURCE_LIST

0x08

Hardware Resource 설명

REG_FULL_RESOURCE_DESCRIPTOR

0x09

Hardware Resource 설명

REG_RESOURCE_REQUIPMENTS_LIST

0x0A

필요한 Resource 목록

REG_QWORD

0x0B

64bit Integer

REG_QWORD_LITTLE_ENDIAN

0x0C

64bit Integer, Little Endian 방식


1-4. ROT 방식의 서브키

  • HKCU\software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist 아래에 있는 서브키들은 value를 ROT-13 방식으로 저장

  • 레지스트리에서 해당 키의 서브키들만 이러한 방식 사용

 

[그림 8] UserAssist 서브키의 ROT-13 저장 방식

 

ROT-13은 현대 암호들과 비교해보면 암호라고 할 수 없지만 이러한 방법이 있다는 것을 모른다면 UserAssist 서브키들의 값을 보았을 때 이 값이 무엇을 파악하는데 어느 정도의 시간이 소요될 것이다.


1-5. 하이브 구조

  • 하이브의 구조를 파악함으로써 비할당 영역이나, 메모리 등에서 하이브를 추출(카빙)할 수 있는 방법을 구상할 수 있음

  • 해당 하이브가 어떠한 이름을 갖고 있는지, 어떠한 데이터를 갖고 있는지 파악 가능

 

하이브의 파일 구조 베이스 블록, 하이브 빈, 셀로 이루어져 있으며, 다음 그림과 같다.

 

[그림 9] 하이브 구조

 

블록

  • 하이브는 파일 시스템이 클러스터라 불리는 논리적 저장 단위를 사용하는 블록이라는 논리적 단위 사용하는데 그 단위를 의미

  • 블록 크기는 4KB이며, NTFS에서의 일반적인 클러스터 크기와 같음

  • 파일 시스템의 경우 클러스터가 4KB일 경우 모든 파일의 물리적 크기가 4KB씩 증가하고, 클러스터가 1비트면 파일의 물리적 크기가 1비트씩 증가

  • 하지만, 하이브는 파일의 크기 증가 기준이 논리적 바이트이기 때문에 언제나 4바이트씩 증가

 

베이스 블록 (Hive Header)

  • 하이브의 첫 번째 블록이며, 하이브의 여러 정보들이 들어 있음

  • 하이브의 시작이 되는 부분이기 때문에 하이브 헤더 역할을 함

  • 아직까지 완벽히 연구된 영역이 아니기 때문에 각 오프셋이 뭘 의미하는지 알 수 없음

 

[그림 10] 베이스 블록 오프셋 구조

  • Signature : 베이스 블록의 시그니처는 'regf"

  • Seqn Number 1 : 하이브에 문제가 없다면 다음에 나올 Seqn Number2와 동일하여야 함

  • Seqn Number 2 : 하이브에 문제가 없다면 앞에 나온 Seqn Number1과 동일하여야 함

  • TimeStamp : Windows 64bit 형식의 시간 값

  • Major Version : 상위 버전의 번호

  • Minor Version : 하위 버전의 번호

  • Root Cell : 첫 번째 key cell의 포인터 값으로서 Offset 단위

  • Last Hive Bin : 마지막 하이브 빈의 포인터 값으로 Offset 단위

  • Only Value 1 : 무조건 값이 1인 Offset

  • CheckSum : 무결성 검증을 위한 CheckSum 값

 

하이브 빈

  • 레지스트리는 4KB를 기준으로 증가하는 동시에 내부에서 4KB 크기의 하이브 빈이라는 논리적 단위 생성

  • 블록과 하이브 빈의 크기는 4KB로 동일하기 때문에 블록 하나가 하이브 빈 하나를 구성할 수도 있고 여러 블록이 하이브 빈 하나를 구성할 수도 있음

  • 하이브의 크기를 결정짓는 블록과 다르게 하이브의 논리적 구조를 결정짓는 요소로 작용

 

베이스 블록은 시그니처가 달라 하이브 빈이라고 부르지 않는다.

 

각각의 하이브 빈은 다음 하이브 빈까지의 상대적 거리를 저장하며, 윈도우는 레지스트리를 읽어 들일 때 하이브 빈을 기본 단위로 삼는다.

 

셀이라는 논리적 단위를 사용하게 되면 잦은 호출로 인해 시스템 속도 저하를 일으킬 수 있고 단편화가 발생할 수 있다.

 

이런 이유로 윈도우에서는 빈 하이브 빈이 생기면 인접 하이브 빈과 결합시키고, 마지막 하이브 빈이 비게 되면 하이브를 축소시킨다.

 

[그림 11] 하이브 빈 헤더의 오프셋 구조

  • Signature : 하이브 빈의 시그니처는 hbin

  • Offset : 첫 번째 하이브로부터의 상대적 거리를 나타내는 값으로 Offset 단위

  • Size : 하이브 빈의 크기로 4096 배수

  • TimeStamp : Windows 64bit 형식의 시간 값

 

하이브 빈 헤더 이후로는 각 셀들이 위치하게 된다.

 

 

  • 하이브 빈보다 더 작은 논리적 저장 단위

  • 실제 레지스트리 데이터를 저장할 때 사용되는 단위

  • 셀 헤더에는 셀의 전체 길이가 저장되며, 이 값은 무조건 8바이트의 배수

 

셀이 하이브 빈에 위치하고 있는 모습은 다음과 같다.

 

[그림 12] 하이브 빈 내부의 셀 위치 모습

 

셀은 처음 그 구조가 시작될 때 셀의 크기를 나타내는 Cell Length 필드 (0x0~3)부터 시작된다.

 

셀의 크기는 Cell Length 필드까지 포함하여 그 크기를 나타낸다.

 

Cell Length 필드 이후에는 각 셀들의 고유 구조(0x4~)가 시작된다.

 

 

1) Key Cell

  • 레지스트리의 키를 가지고 있는 셀

  • '키 노드(Key node)'라고도 불림

  • 가장 최근에 키를 수정한 시간이 기록되며, 이 셀이 바로 Root cell

  • 파일 시스템과 비교하면 해당 셀은 디렉토리 역할을 하는 셀

 

[그림 13] key cell 오프셋 구조

  • Hive Bin Header : Hive Bin Header 필드

  • Cell Length : 해당 셀의 길이를 나타내며, 해당 필드도 포함

  • Signature : 시그니처(nk)를 나타내는 필드

  • Flag : 셀의 상태 플래그를 나타냄

  • TimeStamp : Windows 64bit 형식의 시간 값을 가짐

  • Parent key : 부모 키의 오프셋을 값으로 가짐

  • Subkey Count : 서브키의 개수를 나타내며, Subkey Count 1 필드는 비휘발성 성격을 가지며 Subkey Count 2 필드는 휘발성 성격을 가짐

  • Subkey-list : Subkey-list의 오프셋을 값으로 가지며, Subkey-list 1 필드는 비휘발성 성격을 가지며 Subkey-list 2 필드는 휘발성 성격을 가짐

  • Value-list :  Value-list의 오프셋을 값으로 가짐

  • Security key Cell : Security key의 오프셋을 값으로 가짐

  • Name Length : 키 이름의 길이를 나타냄

  • Class Name Length : 클래스 이름의 길이를 나타냄

  • Key name : 키 이름을 나타내며 해당 필드의 길이는 가변적

 

위에서 말한 상태 플래그 목록은 다음과 같다.

  • 0x0001 : 휘발성 키

  • 0x0002 : 다른 하이브의 마운트 포인트

  • 0x0004 : 루트 키

  • 0x0008 : 삭제 불가능한 키

  • 0x0010 : 링크되어 있는 키

  • 0x0020 : 키의 이름을 ASCII 형태로 저장

  • 0x0040 : 미리 정의되어 있는 키

  • 0x0080 : 알 수 없음

  • 0x1000 : 알 수 없음

  • 0x4000 : 알 수 없음

 

 

2) Subkey-list cells

  • Subkey-list cell은 레지스트리 키의 인덱스 목록을 구성하는 셀

  • 다음에 설명할 두 종류의 엘리먼트 셀과의 결합으로 키들의 인덱스를 구성

[그림 14] subley-list cell 기본 오프셋 구조

  • Signature : 시그니처를 나타내는 필드이며 'lf(Fast Leaf), lh(Hash Leaf), ri(Index Root), li(Index Leaf)' 중 어느 하나가 시그니처로 저장될 수 있음

  • Count : Subkey-list에 있는 엘리먼트들의 개수를 나타냄

  • Subkey-list Element : 다수의 Subkey-list 엘리먼트들을 나타내는데 크기는 4Byte 또는 8Byte가 될 수 있음

 

만약 subkey-list cell의 시그니처가 FL(lf), HL(lh)이라면 subkey-list cell 기본 구조에서 Subkey-list Element 필드 부분에 다음과 같은 구조가 위치하게 된다.

 

[그림 15] FL, HL 타입의 오프셋 구조

  • KN Cell : key cell의 오프셋을 값으로 가짐

  • Hash : 해쉬 값을 가짐

 

또 만약에 Subkey-list ell의 시그니처가 IR(ri), IL(li)이라면 subkey-list cell 기본 구조에서 Subkey-list Element 필드 부분에 다음과 같은 구조가 위치하게 된다.

 

[그림 16] IR, IL 타입의 오프셋 구조

  • Offset : 타입이 IR인 경우 해당 필드는 또 다른 Subkey-list Cell의 오프셋 값을 가짐

  • 그렇지 않은 경우 Subkey의 Offset 값을 가짐

 

 

3) Value-list Cell

  • Value-list cell은 Value cell들의 인덱스 목록을 가짐

 

[그림 17] value-list cell 오프셋 구조

  • Offset : Value Cell 오프셋을 값으로 가지고 있으며, Subkey-list cell의 Subkey-list Element 필드처럼 반복 되어 위치

 

 

4) value cell

  • 해당 셀은 value와 data, data의 타입이 들어 있는 셀

  • key cell이 파일 시스템에 디렉토리라면 해당 셀은 파일과 비교할 수 있는 셀 (시그니처는 vk)

 

[그림 18] value cell 오프셋 구조

  • Cell Length : 해당 셀의 길이를 나타내며, 해당 필드도 길이에 포함

  • Signature : 시그니처(vk)를 나타내는 필드

  • Value Length : Value의 길이

  • Data Length : Data의 길이

  • Data : Data 위치의 오프셋을 값으로 가짐

  • Value Type : Value의 타입을 결정짓는 필드

  • Flag : 해당 필드가 0일 경우 Value는 아스키 코드로 저장되고, 아닐 경우 UTF-16LE 방식으로 저장

  • Value : Value가 저장되어 있는 필드이며, 길이는 가변적

 

 

5) Data cell

  • Data cell은 레지스트리의 data를 저장하고 있는 cell

  • data 크기에 따라 총 3가지의 셀로 구분

  • Big Data cell, Big Data Indirect cell, Data cell로 구분

  • Big Data cell은 크기가 큰 데이터를 직접 저장하지 않고 해당 데이터가 어디에 있는지 알려주는 Big Data Indirect cell의 위치 값을 가짐

  • Big Data Indirect cell은 실제 데이터가 저장되어 있는 Data cell의 위치를 저장

  • Data cell은 실제 데이터를 저장하고 있는 cell

 

[그림 19] Big Data cell 오프셋 구조

  • Signature : 해당 셀의 시그니처가 저장되는 필드로 시그니처는 db

  • Indirect cell : Big Data Indirect cell의 위치를 저장하고 있는 필드, 오프셋 단위로 저장

 

[그림 20] Big Data Indirect cell 오프셋 구조

  • Data cell : Data cell의 위치를 저장하고 있는 필드

 

[그림 21] Data cell 오프셋 구조

  • Data : 실제 데이터가 저장되는 필드로, 그 크기는 가변적

 

 

6) Security-descriptor cell

  • key cell의 Security-descriptor 정보를 가지며 시그니처는 sk

  • 이 셀을 공유하고 있는 모든 키 노드의 개수도 같이 기록

 

[그림 22] security-descriptor cell 오프셋 구조

  • Cell Length : 해당 셀의 길이를 나타내며 해당 필드도 포함

  • Signature : 시그니처를 나타내는 필드

  • Previous SK cell : 이전 SK 셀의 오프셋을 값으로 가짐

  • Next SK Cell : 다음 SK 셀의 오프셋을 값으로 가짐

  • Key node Count : 해당 셀을 공유하고 있는 키 노드들의 개수를 값으로 가지고 있는 레퍼런스 카운터

  • Size : Security descriptor의 크기를 나타냄

 

Security descriptor의 크기 다음부터는 SID, SID Group 등이 위치하는데 그 길이가 가변적이다.

 

일반적으로 레지스트리의 어떤 키와 value, data를 찾아가는데에 지금까지 설명했던 구조들이 참고된다.

 

앞서 설명한 각 셀들의 구조만 이해하고 있따면 자신이 직접 레지스트리 뷰어 제작이 가능할 수도 있다.

 

 

다음 그림은 각 구조들이 어떻게 레지스트리를 구성하게 되는지 간략하게 그림으로 표현한 것이다.

 

[그림 23] 하이브의 전체적 흐름

 

간단하게 설명하면, 처음 Hive header에서 Root cell 필드를 참조해 Root cell이 어디에 위치하고 있는지 파악한 후 Root cell로 이동한다.

 

그 후, Root cell, 즉 Root Key cell에서 Subkey-list cell의 위치를 나타내는 필드의 값을 참조해 Subkey-list cell이 위치하고 있는 곳으로 이동한다.

 

Subkey-list cell 위치에서 시그니처를 참조한다.

 

시그니처가 lf(Fast Leaf)라면 엘리먼트 구조는 Key cell의 위치를 가지고 있는 필드와 해시 값을 저장하고 있는 해시 필드로 구성된다.

 

 

Key cell의 위치를 저장하고 있는 필드를 참조해 key cell이 어디 있는지 파악하고 그곳으로 이동한다.

 

레지스트리 키에는 하나의 value와 data만 존재하는 것이 아니기 때문에 바로 Value cell로 이동하는 것이 아니라 Key cell에서 Value-list cell로 이동해야 한다.

 

Key cell 구조를 보면 여러 가지 cell들의 위치를 저장하는 필드가 존재하는데 그 중 Value-list cell 위치를 저장하는 필드가 존재한다.

 

해당 필드를 참조해 Value cell이 위치하고 있는 곳으로 이동하고, Value cell에서 data의 위치를 저장하고 있는 필드를 참조해 data가 있는 위치로 이동해 데이터를 읽는다.

 

만약 데이터가 위치하고 있는 곳에 Big data 종류의 cell이 있다면 또 한 번 이동해야 한다.

 

 

이와 같은 기본 원리로 레지스트리의 데이터를 읽을 수 있으며, 레지스트리의 서브키, 즉 하위키가 많아질수록 하이브의 구조는 더 커지고 복잡해진다.


# Reference

 

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

[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

+ Recent posts