Security/Forensics

[File Structure] OLE(Object Linking and Embedding) 파일 구조

bonggang 2019. 10. 17. 03:55

기초 개념


OLE 파일(CFB, Compound File Binary) 포맷은 일반적으로 복합 문서를 지칭하며 MS의 문서 포맷으로 사용된다.

폴더 역할의 스토리지(Storage)와 파일 역할의 스트림(Stream)으로 구성되어 있으며 512byte의 섹터 단위로 저장되어있다.

출처: [MS-CFB]: Compound File Binary File Format 공식 문서

 

CFB(OLE)의 구성 요소


OLE 파일은 헤더 블록(512byte)과 데이터 블록(512byte~)으로 구분할 수 있다.

 

 

헤더 블록

OLE 파일 전체의 주요 정보들을 가지고 있다.

Header Signature 8bytes 0x0000 0xD0 CF 11 E0 A1 B1 1A E1
Header CLSID 16bytes 0x0008 사용되지 않는 클래스 ID 저장(전부 0)
Minor Version 2bytes 0x0018 0x003E(Major가 0x0003 혹은 0x0004)
Major Version 2bytes 0x001A 0x0003(ver3) 혹은 0x0004(ver4)
Byte Order 2bytes 0x001C 0xFFFE
Sector Shift 2bytes 0x001E 0x0009(ver3, 512bytes) 혹은 0x000C(ver4, 409)
- major version에 따라 변경, 섹터 사이즈 명시
Mini Sector Shift 2bytes 0x0020 0x0006 - mini stream size 64bytes 명시
reserved 6bytes 0x0022 모두 0
Number of Directory Sectors 4bytes 0x0028 directory 섹터의 개수 - ver3일 경우 0
Number of FAT Sectors 4bytes 0x002C FAT 섹터의 개수
First Directory Sector Location 4bytes 0x0030 directory stream 시작 넘버
Transaction Signature Number 4bytes 0x0034  
Mini Stream Cutoff Size 4bytes 0x0038 0x00001000
First Mini FAT Sector Location 4bytes 0x003C mini FAT 시작 위치
Number of Mini FAT Sectors 4bytes 0x0040 mini FAT sectors 개수
First DIFAT Sector Location 4bytes 0x0044 DIFAT 시작 위치
Number of DIFAT Sectors 4bytes 0x0048 DIFAT 섹터 개수
DIFAT 436bytes 0x004C ver4에서는 헤더 사이즈(512bytes)가 섹터 사이즈(4096bytes)보다 작기에 남은 부분은 모두 0으로 채움

 

+)위의 예시를 기반으로 directory entry를 찾아가는 법을 설명하겠다.

먼저 first directory sector location를 확인해서 위치를 찾아야한다. 위 예시의 값은 0x01이다.

0x01은 10진수로 1이다. 즉, 1번째 블록에 위치한다는 것을 뜻한다. 512byte 기준이므로 512를 곱해주고 헤더가 -1이므로 512를 더하면 위치 값을 확인할 수 있다.

directory entry 위치 = 512(헤더가 -1 섹터)+512*(first directory sector location의 10진수)

해당 위치로 가면 Root Entry를 확인할 수 있다. 이것이 directory entry의 시작을 알리는 문자열이다.

 

 

Directory Entry

directory sector의 그룹으로 각각의 storage object나 stream object가 single directory entry를 표현한다. 128bytes로 고정되어 있으며 directory entry 안의 이름은 unicode UTF-16 code points다.

Directory Entry Name 64bytes 0x00 UTF-16으로 인코딩 된 storage 혹은 stream의 이름
Directory Entry Name Length 2bytes 0x40 길이는 64를 넘지않음.
Object Type 1byte 0x42 0x00(Unknown or unallocated), 0x01(Storage Object), 0x02(Stream Object), 0x05(Root Storage Object)
Color Flag 1byte 0x43 0x00(red), 0x01(black)
Left Sibling ID 4bytes 0x44 left sibling stream ID, 없을경우 NOSTREAM (0xFFFFFFFF)
Right Sibling ID 4bytes 0x48 right sibling stream ID, 없을경우 NOSTREAM (0xFFFFFFFF)
Child ID 4bytes 0x4C child object의 stream ID
CLSID 16bytes 0x50 0으로 채워짐, 0이 아닐 경우는 object class GUID가 시작 어플리케이션 파라미터로 쓰일 경우
State Bits 4bytes 0x60 기본값은 0
Creation Time 8bytes 0x64  
Modified Time 8bytes 0x6C  
Starting Sector Location 4bytes 0x74 시작 섹터 위치(stream object), 모두 0(storage object) 
mini stream 시작 섹터(root storage object)
Stream Size 8bytes 0x7C user-defined data size