OLE File Format Structure
OLE File Format?
OLE File Format은 MS 오피스인 워드, 엑셀, 파워포인트의 문서 포맷으로 사용되어 왔다. OLE File Format은 내부가 하나의 작은 하드 디스크와 같은 파일 시스템 구조를 가진다. 따라서 OLE File 내부에는 폴더 및 파일과 비슷한 개념으로 Storage와 Stream이 있다.
OLE File Format Structure
OLE File Structure
OLE File은 크게 Header Block 과 Data Block 2개의 블록으로 나뉜다. Header Block은 512Byte의 크기를 가지고 그 이후에 Data Block은 512Byte 이상의 크기를 가지게 된다.
Header Block은 OLE 파일 전체의 주요 정보들을 가지고 있으며, Data Block은 크게 아래의 정보들을 가지고 있다.
- FAT : Sector Index Chain Information
- Mini FAT : MiniSector Chain Information in MiniStream
- Double Indirect FAT(DIFAT) : FAT Sector Location
- Directory Sector : Include Directory Data
- Stream Sector : Include File Data
이 중에서 Data Block의 대부분은 Stream Sector가 차지하고 있다.
OLE Block Structure
OLE Header Block은 OLE File을 512Byte 씩 나누어 번호를 지정한다. 이 때 맨 처음 Block의 번호는 0이 아닌 -1임을 기억해야 한다.
-1 Block이 Header Block이며, 0, 1, 2, ..., n Block이 Data Block이다.
OLE File Format
OLE 구조를 가진 파일을 HxD로 열었다.
512byte는 Header Block 인데 OLE 파일을 구조적으로 나누어 번호를 매긴다고 앞에서 설명한적이 있다. 하지만 번호를 매길 이유가 없을 때(데이터가 없을 때?)는 FF라는 값으로 채워지는 것 같다.
각각의 데이터의 의미는 아래의 표와 같다.
offset | Length(byte) | Description | |
---|---|---|---|
File Header Signature | 0x00 | 8 | OLE File Signature D0 CF 11 E0 A1 B1 1A E1 |
Header CISID | 0x08 | 8 | Reserved Class, set 0x00 |
Minor Version | 0x18 | 2 | Version Number for Summary Change In case major value 0x0003, 0x0004, minor value is 0x003E |
Major Version | 0x1A | 2 | Version Number for Changes each case 0x0003(ver.3) or 0x0004(ver.4) |
Byte Order Identifier | 0x1C | 2 | Byte ordering Little-Endian = LE FE FF Big-Endian = BE FF FE |
Sector Shift | 0x1E | 2 | Size of Sector each case Major ver.3, Sector Shift value is 9 or Major ver.4, Sector Shift value is C ex.) Sector Size 2^9=512 / 2^13 = 4096 |
Mini Sector Shift | 0x20 | 2 | Mini Sector Size Default set 6 Default Sector Size = 2^64 |
Reserved Area | 022 | 6 | set 00 |
Number of Directory Sector | 0x28 | 4 | Number of Directory Sector In case Major = 3, value is 0 |
Number of FAT Sector | 0x2C | 4 | Number of FAT Sector |
SEC ID | 0x30 | 4 | Number of First Directory |
Transaction Signature Number | 0x34 | 4 | Increases Number when File saved specific API If not File is transaction, value = 0 |
Mini Stream Cutoff Size | 0x38 | 4 | set 0xD0001000 |
Mini FAT Location | 0x3C | 4 | Mini FAT Location |
Number of Mini FAT | 0x40 | 4 | Number of Mini FAT |
First DIFAT Sector Location | 0x44 | 4 | First DIFAT Sector Location Means current location here |
Number of DIFAT Sector | 0x48 | 4 | Number of DIFAT Sector |
FAT #n Location | 0x4C ~ 0x1F0 | 4 ~ 1A4 | FAT #n Location Each FAT allocate 4byte If FAT end, set FF (In case Major ver.4 set 00) |
위의 표와 비교해 주요 정보를 확인해 보면 아래와 같다.
- 섹터의 크기 = 09 00 = 2^9 = 512byte
- Mini Sector 크기 = 06 00 = 2^6 = 64byte
- Mini FAT 개수 = 01 00 00 00 = 1개
- FAT 위치 값 = 03 00 00 00, FAT 위치 = 3 + 1 = 4sector
- Root Directory 위치 값= 03 00 00 00, Root Directory 위치 = 3 + 1 = 4sector
- 첫번째 Mini FAT 위치 값= 06 00 00 00 = 6sector, 첫번째 Mini FAT 위치 = 6 + 1 = 7sector
Mini FAT의 위치를 찾아가 봅시다. 위치는 512*7=3584=E00 입니다.
실제로 FAT 구조를 가지고 있는 것을 확인할 수 있습니다.
그 다음은 Root Directory를 살펴볼까요.
Root Directory의 위치는 512*3 = 1536 = 0x600입니다.
해당 구조를 자세히 보면
이런 구조를 가지고 있습니다. 해당 구조에 대한 설명은 아래 표를 참조하시면 될 것 같습니다.
Offset | Length(byte) | Description | |
---|---|---|---|
Directory Entry Name | 0x00 | 64 | Null 문자로 끝이 나야 한다. / \ : ! 의 문자는 사용할 수 없다. |
Directory Entry Name Length | 0x40 | 2 | DIrectory Entry Name 문자열의 길이와 일치해야하한다. null도 길이에 포함해서 계산을 해야하고 64를 초과하면 안된다. |
Object Type | 0x42 | 1 | 파일의 유형에 따라서 값이 달라진다. Unknown or Unallocated = 0x00 Storage Object = 0x01 Stream Object = 0x02 Root Storage Object = 0x05 |
Color Flag | 0x43 | 1 | 0x00 과 0x01 밖에 올 수 없다. 또한 Root의 경우에는 0x01이다. Red = 0x00, Black = 0x01 |
Left Sibling ID | 0x44 | 4 | 왼쪽 스트림 아이디를 포함한다. 값이 없으면 0xFFFFFFFF |
Right Sibling ID | 0x48 | 4 | 오른쪽 스트림 아이디를 포함한다. 값이 없으면 0xFFFFFFFF |
Child ID | 0x4C | 4 | 하위 스트림 아이디를 포함 값이 없으면 0xFFFFFFFF |
CLSID | 0x50 | 16 | 저장소, 루트 저장소의 경우 개체 클래스 GUID가 포함된다. 스트림에서는 모두 0이다. |
State Bits | 0x60 | 4 | 사용자 정의 플래그 |
Creation Time | 0x64 | 8 | 생성시간, Root에는 0이라는 값이 저장된다. |
Modified Time | 0x6C | 8 | 수정시간, UTC 시간으로 저장 |
Starting Sector Location | 0x74 | 4 | Root Storage : 미니스트림의 첫 번재 섹터 Mini FAT : 데이터가 존재하는 곳의 첫 번째 섹터 |
Stream Size | 0x78 | 8 | 값이 4096보다 크거나 같으면 FAT 이고 4096보다 작으면 Mini FAT이다. |
Reference
https://whitesnake1004.tistory.com/584 - 점프리스트 포렌식
http://www.forensic-artifact.com/windows-forensics/jumplist - 내가 공부할 리스트
http://www.hanul93.com/ole-fileformat-bbat/ - 음...?
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb/5af03a5e-66dc-469c-8970-7229a11e2a3f - Microsoft 문서