常见文件格式

文件头文件尾总结

文件格式 文件头 文件尾
JPEG (jpg) FF D8 FF E1 FF D9
PNG (png) 89 50 4E 47 0D 0A 1A 0A(\x89PNG) 00 00 00 00 49 45 4E 44 AE 42 60 82(\x00IEND)
GIF (gif) 47 49 46 38(GIF8) 00 3B
TIFF (tif) 49 49 2A 00(II*\x00)  
Windows Bitmap (bmp) 42 4D(BM)  
ZIP Archive (zip) 50 4B 03 04(PK\x03\x04)  
RAR Archive (rar) 52 61 72 21 1a 07 00(Rar!)  
zlib 78 9C(x\x9c)  
gzip 1F 8B 08  
bzip 42 5A 68  
pcap d4 c3 b2 a1 02 20 04 20  
lzma 6C 00  
Windows Update Binary Delta Compression file [four bytes CRC32, optional] 50 41 33 30(PA30)  
Lua bytecode (luac) 1B 4C 74 61 5*(\x1bLuaQ|R|S)  
Lua JIT bytecode (luac) 1B 4C 4A(\x1bLJ)  
Win executable file (exe) 4D 5A(MZ)  
Linux executable file (elf) 7F 45 4C 46(\x7fELF)  
MPEG Audio Layer 3 (mp3) 49 44 33(ID3) 或 FF FB  
Wave (wav) 57 41 56 45(WAVE)  
AVI (avi) 41 56 49 20(AVI )  
Real Audio (ram) 2E 72 61 FD(.ra\xfd)  
Real Media (rm) 2E 52 4D 46(.RMF)  
MPEG (mpg) 00 00 01 [BA | B3]  
Quicktime (mov) 6D 6F 6F 76(moov)  
Windows Media (asf) 30 26 B2 75 8E 66 CF 11(0&\xb2u\x8ef\xcf\x11)  
MIDI (mid) 4D 54 68 64(MThd)  
CAD (dwg) 41 43 31 30(AC10)  
Adobe Photoshop (psd) 38 42 50 53(8BPS)  
Rich Text Format (rtf) 7B 5C 72 74 66({\rtf)  
XML (xml) 3C 3F 78 6D 6C(<?xml)  
HTML (html) 3C 68 74 6D 6C 3E(<html>)  
Email [thorough only] (eml) 44 65 6C 69 76 65 72 79 2D 64 61 74 65 3A(Delivery-date:)  
Outlook Express (dbx) CF AD 12 FE C5 FD 74 6F  
Outlook (pst) 21 42 44 4E(!BDN)  
MS Word/Excel (xls.or.doc) D0 CF 11 E0  
MS Access (mdb) 53 74 61 6E 64 61 72 64 20 4A(Standard J)  
WordPerfect (wpd) FF 57 50 43(\xffWPC)  
Adobe Acrobat (pdf) 25 50 44 46 2D 31 2E(%PDF-1.)  
Quicken (qdf) AC 9E BD 8F  
Windows Password (pwl) E3 82 85 96  
RSA Private binary(pem) 30 82 02 5C (后接0x025C=604byte)  
KeePass 1.x KDB 03 D9 A2 9A 65 FB 4B B5  
KeePass 2.x KDBX 03 D9 A2 9A 67 FB 4B B5  
VMWare Virtual Machine Disk Format (vmdk) 4B 44 4D 56 (KDMV)  

Windows Update Binary Delta Compression file

1
python3 D:\ctf\snippet\ctf\misc\delta_patch.py -i tcp0.png -o tcp0.dll tcp0.patch1 [tcp0.patch2]

PNG文件格式

  • 文件头 89 50 4E 47 0D 0A 1A 0A + 数据块 + 数据块 + 数据块 …

  • 每个数据块由4部分组成:

名称 字节数 说明
Length(长度) 4 字节 指定数据块中数据域的长度,其长度不超过(2^31-1)字节
Chunk Type Code(数据块类型码) 4 字节 数据块类型码由 ASCII 字母(A - Z 和 a - z)组成
Chunk Data(数据块数据) 可变长度 存储按照 Chunk Type Code 指定的数据
CRC(循环冗余检测) 4 字节 存储用来检测是否有错误的循环冗余码

CRC(Cyclic Redundancy Check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行CRC32计算得到的。某IHDR头数据块00 00 00 0d 49 48 44 52 00 00 00 1e 00 00 00 05 01 03 00 00 00 68 ef ce b9,Length=0x0d,ChunkTypeCode=49 48 44 52即IHDR,ChunkData是长度为0x0d的数据:00 00 00 1e 00 00 00 05 01 03 00 00 00,将ChunkTypeCode和ChunkData计算得到CRC=68 ef ce b9

1
hex(zlib.crc32('494844520000001e000000050103000000'.decode('hex')) & 0xffffffff) #'0x68efceb9L'
  • 关键数据块(critical chunk)有3种:IHDR(头数据块)、IDAT(图像数据块)、IEND(结束数据块)

    IDAT采用LZ77算法的派生算法进行压缩,在数据流中可包含多个连续顺序的图像数据块,只有当上一个块充满时,才会继续一个新的块(sample:简单的png隐写,dasctf-2021-03)。可以用zlib.decompress进行解压缩。

ELF文件格式

所有变量定义在:/usr/include/elf.h

ELF header

描述了ELF文件的概要信息,利用这个数据结构可以索引到 ELF 文件的全部信息。Elf32_Ehdr和Elf64_Ehdr结构相同,但是由于e_entry,e_phoff,e_shoff三个地址类型从4字节扩展到8字节,因此sizeof(Elf32_Ehdr)=52sizeof(Elf64_Ehdr)=64少12个字节。此处以Elf64_Ehdr为例:

00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0300 3e00 0100 0000 f0b1 0700 0000 0000  ..>.............
00000020: 4000 0000 0000 0000 9858 1900 0000 0000  @........X......
00000030: 0000 0000 4000 3800 0600 4000 1a00 1700  ....@.8...@.....
  • 0x00-0x0f:16个字节为ELF标识,其中前4个字节固定为:\x7fELF;第5字节01表示32位文件,02表示64位文件;第6字节01表示little endian,02表示big endian;第7字节表示当前ELF头版本号,当前为01。
  • 0x10-0x1f:
    • 0300,文件类型(Object file type),02表示可执行文件,03表示共享目标文件
    • 3e00,机器架构(Architecture),#define EM_X86_64 62(0x3e)
    • 0100 0000,当前ELF版本号(Object file version),当前为01
    • f0b1 0700 0000 0000,程序入口处虚拟地址(Entry point virtual address)
  • 0x20-0x2f:
    • 4000 0000 0000 0000,程序头部表(Program Header Table)距离文件开头的偏移量
    • 9858 1900 0000 0000,程序节头表(Section Header Table)距离文件开头的偏移量
  • 0x30-0x3f:
    • 0000 0000,处理器相关的标志(Processor-specific flags)
    • 4000,ELF头长度(ELF header size),sizeof(Elf64_Ehdr)=64=0x40
    • 3800,程序头部表表项长度(Program header table entry size),sizeof(Elf32_Phdr)=32=0x20 sizeof(Elf64_Phdr)=56=0x38
    • 0600,程序头部表表项个数(Program header table entry count)
    • 4000,程序节头表表项长度(Section header table entry size),sizeof(Elf32_Shdr)=40=0x28 sizeof(Elf64_Phdr)=64=0x40
    • 1a00,程序节头表表项个数(Section header table entry count)
    • 1700,节头表中与节名字符串表相关的表项的索引值(Section header string table index)
程序头部表(Program Header Table)

描述了一个段或者其它系统在准备程序执行时所需要的信息,只有可执行文件和共享目标文件有该字段,根据程序头部表(Program Header Table)偏移量0x40找到头部表,表项长度为0x38,个数为0x06,此处以第二个表项(0x40+0x38=0x78开始)为例

00000070: 0000 2000 0000 0000 0100 0000 0600 0000  .. .............
00000080: 30be 0700 0000 0000 30be 2700 0000 0000  0.......0.'.....
00000090: 30be 2700 0000 0000 31f5 0a00 0000 0000  0.'.....1.......
000000a0: 38f5 0a00 0000 0000 0000 2000 0000 0000  8......... .....
  • 0x78-0x7f:
    • 0100 0000段类型(Segment type),01表示可加载段(包含init_array/fini_array/jcr/dynamic/got/got.plt/data节),02表示动态链接信息,04表示附加信息
    • 0600 0000段标志(Segment flags),位操作,01表示可执行,02表示可写,04表示可读
  • 0x80-0x8f:
    • 30be 0700 0000 0000该段距离文件开头的偏移量(Segment file offset)
    • 30be 2700 0000 0000该段的虚拟地址(Segment virtual address)
  • 0x90-0x9f:
    • 30be 2700 0000 0000该段的物理地址(Segment physical address)
    • 31f5 0a00 0000 0000文件中该段的大小(Segment size in file)
  • 0xa0-0xaf:
    • 38f5 0a00 0000 0000内存中该段的大小(Segment size in memory)
    • 0000 2000 0000 0000段在文件和内存中的对齐方式(Segment alignment),Segment file offset和Segment virtual address模Segment alignment相等
程序节头表(Section Header Table)

通过readelf -S读到的节头信息,节头表一般在ELF文件尾部。根据程序节头表(Section Header Table)偏移量0x195898找到节头表,表项长度为0x40,个数为0x1a,此处以第21项data节(0x195898+0x40*20=0x195d98开始)为例

00195d90: 0800 0000 0000 0000 c200 0000 0100 0000  ................
00195da0: 0300 0000 0000 0000 20c0 2700 0000 0000  ........ .'.....
00195db0: 20c0 0700 0000 0000 41f3 0a00 0000 0000   .......A.......
00195dc0: 0000 0000 0000 0000 2000 0000 0000 0000  ........ .......
00195dd0: 0000 0000 0000 0000 c800 0000 0800 0000  ................
  • 0x195d98-0x195d9f:
    • c200 0000节名(Section name),在字符串表节区的索引
    • 0100 0000根据节的内容和语义进行分类(Section type),01表示程序数据,02表示符号表,03表示字符串表,06表示动态链接信息
  • 0x195da0-0x195daf:
    • 0300 0000 0000 0000节标志(Section flags),位操作,01表示运行时可以被写,02表示运行时占用内存,04表示可执行
    • 20c0 2700 0000 0000节运行时虚拟地址(Section virtual addr at execution)
  • 0x195db0-0x195dbf:
    • 20c0 0700 0000 0000节距离文件开头的偏移量(Section file offset)
    • 41f3 0a00 0000 0000节的大小(Section size in bytes)
  • 0x195dc0-0x195dcf:
    • 0000 0000节头表索引链接(Link to another section)
    • 0000 0000节附加信息(Additional section information)
    • 2000 0000 0000 0000节对齐(Section alignment),一般为0或2的倍数
  • 0x195dd0-0x195dd8:
    • 0000 0000 0000 0000如果节为表格式,如符号表,该值为每一项的大小(Entry size if section holds table),否则为0
例:elfrand(高校运维赛eis-2018)

flag前后随机定义若干十六进制字符变量,编译为PIC形式的共享目标文件。每次根据发送的偏移量返回共享目标文件偏移量处8个字节的值。

000d1a80: 4549 537b 6e65 6564 5f74 6f5f 6b6e 6f77  EIS{need_to_know
000d1a90: 5f31 3233 5f62 6566 6f72 655f 6861 636b  _123_before_hack
000d1aa0: 696e 675f 6c6f 6c7d 0000 0000 0000 0000  ing_lol}........
000d1ab0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000d1ac0: 3263 3364 6562 6636 6666 6362 6331 3637  2c3debf6ffcbc167
000d1ad0: 6566 3433 3034 3466 6162 3163 6430 6433  ef43044fab1cd0d3
  1. 首先根据节头表偏移0x28,得到0x195898,常量值存储的data节是节头表的0x20个item,根据0x195898 + 0x40*20 = 0x195d98得到data节头表位置
  2. 根据data节偏移0x18(0x195d98+0x18),得到data节开始位置0x7c020,根据data节偏移0x20(0x195d98+0x20),得到data节大小0xaf341(如果交互次数受限,也可以直接通过程序头部表偏移0x80和0x98得到可加载段的开始位置和大小,再根据其他节大小固定,推算data节的开始位置和大小,可以少一次交互
  3. 由于flag前后的变量值长度均为0x40+1,根据对齐方式0x20,每项长度实际为0x60,而flag长度不足0x40,因此根据对齐方式0x20时,只会占据0x40。因此,从data节头开始,以二分方式,查找0x60的倍数+0x20,如果遇到十六进制字符,表示flag在后半段,如果遇到0x00,表示flag在前半段,直至遇到非十六进制字符ing_lol}

MP3文件格式

ID3V2_TAG+音频数据MPEG_FRAME…+ID3V1_TAG

ID3V2_TAG
  • ID3V2_HEADER,长度10个字节
    • 49 44 33标识:ID3
    • 03版本号:V2.3记录3
    • 00副版本号记录0
    • 00标志,只使用高三位,其他位为0
    • ` 00 04 33 13长度,每个字节使用低7位,最高位不使用恒为0,计算时将最高位去掉,得到28bit:(00 & 0x7f)0x200000+(04 & 0x7f)0x4000+(33 & 0x7f)*0x80+(13 & 0x7f)=0x11993,由于HEADER为10个字节,因此音频数据从0x11993+0xa=0x1199d`开始
  • ID3V2_FRAME,头长度10个字节
    • 54 41 4C 42标识:TALB=专辑(其他还有:TIT2=标题,TPE1=作者)
    • 00 00 00 1B当前ID3V2_FRAME帧长度
    • 00 00标志
    • 0x1b长度的帧数据
MPEG_FRAME,头长度4个字节
  • FF FB前12位同步标志,恒为0xfff,0xB=0b1011,第13位Mpeg版本:0表示MPEG2,1表示MPEG1;第14,15位层标识:01表示Layer3,10表示Layer2,11表示Layer1;第16位校验位:0表示校验,1表示不校验
  • 90前4位比特率:0x9=0b1001表示128kbps;第5,6位采样频率:00对于MPEG1表示44.1kHZ;第7位帧长调节:0表示无需调整,1表示调整;第8位保留位,可用于隐写
  • 00第1,2位声道模式:00表示立体声;第3,4位扩充模式,仅当声道模式为01时使用;第5位版权:0表示不合法,1表示合法;第6位原版标志:0表示非原版,1表示原版;第7,8位强调方式:用于声音降噪压缩后再补偿的分类,很少用到
  • 接下来是帧长度的数据,帧长度=采样数/8*比特率/采样频率+填充,对于Layer3,采样数MPEG1为1152,MPEG2为576,因此:帧长度为:1152/8*128k/44.1k+0=417=0x1a1,因此帧长度可能为0x1a1(无填充)或0x1a2(有填充)
ID3V1_TAG,长度128个字节
字节 长度 说明
1-3 3 标识:TAG
4-33 30 Title
34-63 30 Artist
64-93 30 Album
94-97 4 Year
98-125 28 Comment
126 1 全零
127 1 Track
128 1 音乐类别,共147种

ZIP文件格式

ZIPFILERECORD,文件数据区
偏移 长度 说明
0 4 feSignature:文件数据区标识50 4B 03 04(PK\x03\x04)
4 2 frVersion:解压时最低版本
6 2 frFlags:全局加密标志,00表示无加密,其余值表示加密
8 2 frCompression:压缩方法,一般是:COMP_DEFLATE(8)
ZIPDIRENTRY,文件目录区
偏移 长度 说明
0 4 deSignature:文件目录区标识50 4B 01 02(PK\x01\x02)
4 2 deVersionMadeBy:压缩时的版本
6 2 deVersionToExtract:解压时最低版本
8 2 deFlags:通用位标记,00表示无加密,其余值表示加密
10 2 deCompression:压缩方法,一般是:COMP_DEFLATE(8),与frCompression相同

RAR文件格式

Marker block (MARK_HEAD)标志块

固定为0x526172211a0700

Archive header (MAIN_HEAD)归档头部块
  长度 说明
HEAD_CRC 2 CRC
HEAD_TYPE 1 0x73(115):ARCHIVE
HEAD_FLAGS 2 0x0080(BLOCK_HEADERS_ENCRYPTED):加密位
File header (File in archive)文件块(被归档的文件)
  长度 说明
HEAD_CRC 2 CRC
HEAD_TYPE 1 0x74(116):FILE_OR_DIR
HEAD_FLAGS 2 0x04(PASSWORD_ENCRYPTED):加密位