1. PNG 파일 분석

PNG 파일 최근에 다운 받은 게 space ctf에서 썼던 empty.png 파일이 있었다. empty라서 하얀 사진이 특징이다.
먼저 이 파일이 PNG임을 알 수 있는 시그니처부터 살펴보려고 한다.

헤더 시그니처는 89 50 4E 47 0D 0A 1A 0A 이다.

푸터 시그니처는 49 45 4E 44 AE 42 60 82 이다.
이후에는 PNG 파일 구조에 대해 자세히 분석해봐야 한다. 먼저 chunk라는 개념에 대해 알고 가야 한다. PNG 파일 구조는 시그니처와 chunk들로 이루어져 있다. 중요한 청크로는 IHDR, IDAT, IEND가 존재하고, 모두 PNG 파일에 반드시 포함되어야 한다.
1. IHDR : 이미지 헤더 정보

하늘색 범위가 IHDR이 차지하는 청크 범위이다. 먼저 크게는 빨간색 분류를 봐야한다.
| 범위 | 표현값 | + |
|---|---|---|
| 00 00 00 0D (4bytes) | Length (고정값) | |
| 49 48 44 52 (4bytes) | Chunk Type (IHDR) | |
| 00 00 01 72 00 00 01 72 08 02 00 00 00 (13 bytes) | Chunk Data | |
| 67 46 C6 5E (4 bytes) | CRC | 데이터 오류가 있는지 확인하는 값 |
Chunk Data는 여러 정보를 담고 있는데 해당 부분은 연두색을 기준으로 분류할 수 있다.
| 범위 | 표현값 | + |
|---|---|---|
| 00 00 01 72 (4 bytes) | Width | |
| 00 00 01 72 (4 bytes) | Height | 가로, 세로가 같은 값인 걸 보아하니 해당 이미지는 정사각 파일이다. |
| 08 (1 bytes) | Bit depth | 1 픽셀의 비트 양(Depth) |
| 02 (1 bytes) | Color Type | 색 표현 유형 0: 회색조 2: RGB 3: 색인 4: 투명도가 존재하는 회색조 6: 투명도가 존재하는 RGB 해당 분석에서는 2번 RGB가 나왔는데 이때 allowed bit depths는 8 혹은 16이다. 때문의 위의 값이 08인 거 같다. |
| 00 (1 bytes) | Compression method | 0 Deflate 하나 존재 |
| 00 (1 bytes) | Filter method | 0 Adaptive filtering 하나 존재 |
| 00 (1 bytes) | Interlace method | 0 No interlace, 1 Adam 7 interlace 두 개 존재 |
2. IDAT : 이미지 데이터 정보
해당 chunk는 여러 개일 수 있다.

해당 파일에서는 하나만 존재한다.

| 범위 | 표현값 | + |
|---|---|---|
| 00 00 07 24 (4 bytes) | Length | 07 24를 10진수로 바꿔보면 1828 |
| 49 44 41 54 (4 bytes) | Chunk Type (IDAT) | |
| 78~ (Length bytes) | Chunk Data | |
| 3E 88 4E AB (4 bytes) | CRC |
Chunk Data 부분만 새 파일에 복붙하고 offset 확인하면 724임을 확인할 수 있다.
3. IEND : 파일의 끝

| 범위 | 표현값 | + |
|---|---|---|
| 00 00 00 00 (4 bytes) | Length (고정값) | |
| 49 45 4E 44 (4 bytes) | Chunk Type (IDAT) | |
| AE 42 60 82 (4 bytes) | CRC | 모든 부분이 고정값이라 footer signature로 받아들인다. |
2. zip 파일 분석
드림핵 워게임이 있는 zip파일인데 이름이 너무 길어서 실험대상으로 바꿨다. 안에 파일 하나 있다.
분석하기 쉬운 시그니처부터 알아보았다.

헤더 시그니처는 50 4B 03 04 이다.

푸터 시그니처는 50 4B 05 06이라고 하는데 후에 설명할 End of Central Directory Record 때문에 뒤에 값이 더 존재한다.

zip파일에 3개의 파일이 압축되었을 때 확인할 수 있는 구조라고 한다. 내가 분석하는 파일에는 1개의 파일만 존재하므로 재구성하면 다음과 같다.
| Local File Header | File Name | File Data |
|---|---|---|
| Central Directory | File Name | |
| End of Central Directory Record |
- Local File Header
- Central Directory File Header
- End of Central Directory Record
를 분석해야 하는데 모두 헤더 시그니처가 50 4b로 시작된다.

1. Local File Header
| 범위 | 표현값 | + |
|---|---|---|
| 50 4B 03 04 (4 bytes) | Signature (고정값) | |
| 14 00 (2 bytes) | 압축해제 시 필요한 버전 | |
| 00 00 (2 bytes) | Flags | 0: encrypted file 1: compression option 2: compression option 3: data descriptor 4: enhanced deflation 5: compressed patched data 6: strong encryption 7-10: unused 11: language encoding 12: reserved 13: mask header values 14-15: reserved |
| 08 00 (2 bytes) | Compression Method | 0: no compression 1: shrunk 2: reduced with compression factor 1 3: reduced wtih compression factor 2 4: reduced with compression factor 3 5: reduced with compression factor 4 6: imploded 7: reserved 8: deflated 9: enhanced deflated A: PKWare DCL imploded B: reserved C: compressed using BZIP2 D: reserved E; LZMA F-11: reserved 12: compressed using IBM TERSE 13: IBM LZ77 z 62: PPMd version 1, Rev 1 |
| F8 26 (2 bytes) | File Modification Time | F8 26을 2진수 변환 해당 부분을 5비트(h), 6비트(m), 5비트(s)로.. 21시 1분 6초임을 알 수 있다. |
| 8E 57 (2 bytes) | File Modification Date | 8E 57을 2진수 변환 해당 부분을 7비트(y), 4비트(m), 5비트(d)로.. 연도는 계산 후에 +1980 2051(엥?) / 2 / 23 |
| 25 70 0D BE (4 bytes) | CRC | |
| 29 01 00 00 (4 bytes) | Compressed Size | |
| 21 02 00 00 (4 bytes) | Uncompressed Size | |
| 0A 00 (2 bytes) | File Name Length | |
| 1C 00 (2 bytes) | Extra Field Length |
이후에는 Extra Field 내용이 나오고, 이 공간에 데이터가 쓰인다. 해당 파일에는 주석이 없지만 header에 주석의 길이가 있다면 Extra Field 이후 File Comment가 달리게 된다.
2. Central Directory File Header
두번째 header 시그니처 50 4B 01 02 여기부터는 Central Directory File Header이다.

| 범위 | 표현값 | + |
|---|---|---|
| 50 4B 01 02 (4 bytes) | Signature (고정값) | |
| 14 00 (2 bytes) | 압축할 때 사용한 버전 | |
| 14 00 (2 bytes) | 압축해제 시 필요한 버전 | |
| 00 00 (2 bytes) | Flags | |
| 08 00 (2 bytes) | Compression Method | |
| F8 E6 (2 bytes) | File Modification Time | |
| 8E 57 (2 bytes) | File Modification Date | |
| 25 70 0D BE (4 bytes) | CRC | |
| 29 01 00 00 (4 bytes) | Compressed Size | |
| 21 02 00 00 (4 bytes) | Uncompressed Size | |
| 0A 00 (2 bytes) | File Name Length | |
| 18 00 (2 bytes) | Extra Field Length | |
| 00 00 (2 bytes) | File Comment Length | 파일 주석 길이 |
| 00 00 (2 bytes) | Disk Start Number | 파일이 있는 디스크의 시작 넘버 |
| 01 00 (2 bytes) | Internal Attribute | 0: Apparent ASCII/text file 1: Reserved 2: Control Field Records Precede Logical Records |
| 00 00 A4 81 (4 bytes) | External Attribute | |
| 00 00 00 00 (4 bytes) | Local Header의 시작 오프셋 | |
| 44 6F 63 6B 65 72 66 69 | File Name |
3. End of Central Directory Record

| 범위 | 표현값 | + |
|---|---|---|
| 50 4B 05 06 (4 bytes) | Signature (고정값) | |
| 00 00 (2 bytes) | Disk Start Number | 2번에 있는 값과 동일 |
| 00 00 (2 bytes) | Disk # w/cd | Central Directory가 시작되는 디스크 개수 |
| 01 00 (2 bytes) | Disk Entry | 디스크의 Central Directory 개수 |
| 01 00 (2 bytes) | Total Entry | Central Directory 개수 |
| 50 00 00 00 (4 bytes) | Size of Central Directory | 2번에서 살펴본 Central Header 크기 |
| 6D 01 00 00 (4 bytes) | Central Header Offset | 2번에서 살펴본 Central Header 시작 위치 |
| 00 00 (2 bytes) | Comment Length | 이 정보 다음에 ZIP File Comment가 나오는데 해당 코멘트 길이가 0이므로 없다. |