解開隱寫術之謎

0x01 什麼是隱寫術


隱寫術是將想要隱藏的消息嵌入到載體中,而達到信息保密的效果。隱寫術的使用可以追溯到古埃及時代又或者中國的元朝。而現代隱寫術通過使用電腦以及不同的隱寫軟件將信息隱藏在不同種類的文件當中。

另外,使用隱寫術也可以為加密的信息提供多一層的保護。也就是說,我們可以將加密後的信息用一些非常普通的文件,如圖片,音頻,視頻,文檔等等,經過一系列的特殊處理將其隱藏起來。

一個完整的隱寫系統包含了4個要素:

  • 被嵌入信息:隱藏在普通文件背後的秘密信息。
  • 普通文件:用於隱藏訊息的文件。
  • 隱寫鑰匙:用於加密和解密信息的鑰匙。
  • 隱寫軟件:負責將需隱藏信息和普通文件整合在一起的軟件。

0x02 現代隱寫術的方法

  • 注入
  • 最低有效位Least Significant bit(LSB)
  • File generation
  • Transform-Domain technique
  • Spread spectrum encoding
  • perceptual masking
  • Statistical method
  • Distortion technique

注入

最低有效位(LSB)

最低有效位(Least Significant Bit)代表着二進制數中的最小的單位,可以用來指示數字很小的變化。也就是說,LSB是一個二進制數字中的第0位(即最低位),具有權值為$2^0$,可以用它來檢測數的奇偶性。在大端序(Big Endian)中,LSB指最右邊的位。

舉個例子,在圖像隱寫術裡面,所謂的LSB隱寫就是去修改RGB的顏色分量中的最低位。也就是去修改像數最低的1位元。當然人類的眼睛是無法分辨得出當中的變化,唯有通過一些軟件去檢驗,才能得知圖片裡面是隱藏了信息。

文件生成

領域轉換技巧

擴頻編碼

感知掩蔽

統計學方式

失真技術

0x03 元數據Metadata

元數據,又稱中介數據、中繼數據,為描述數據的數據(data about data),主要是描述數據屬性(property)的信息,用來支持如指示存儲位置、歷史數據、資源查找、文件記錄等功能。

元數據中隱藏信息在比賽中是最基本的一種手法,通常用來隱藏一些關鍵的Hint信息或者是一些重要的如password等信息。

Strings指令

這類元數據你可以右鍵–>屬性去查看,也可以通過strings去查看,一般來說,一些隱藏的信息(奇怪的字元串)常常出現在頭部或者尾部。

用法:Strings指令

例子
Breakin-ctf-2017:Mysterious-GIF

要分析這個Gif,我們可以用strings這指令來查看裡面的所有字符串。

結果我們發現到異常的部分如下:

1
2
3
4
5
6
GIF89a
!!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~
4d494945767749424144414e42676b71686b6947397730424151454641415343424b6b776767536c41674541416f4942415144644d4e624c3571565769435172
NETSCAPE2.0
ImageMagick
...

identify指令

這裡的16進制其實是藏在GIF的元數據區裡面。

接下來就是提取,你可以選擇python,但是利用identify指令顯得更加便捷。

1
2
3
4
5
6
root in ~/Desktop/tmp λ identify -format "%s %c \n" Question.gif
0 4d494945767749424144414e42676b71686b6947397730424151454641415343424b6b776767536c41674541416f4942415144644d4e624c3571565769435172
1 5832773639712f377933536849507565707478664177525162524f72653330633655772f6f4b3877655a547834346d30414c6f75685634364b63514a6b687271
...
24 484b7735432b667741586c4649746d30396145565458772b787a4c4a623253723667415450574d35715661756278667362356d58482f77443969434c684a536f
25 724b3052485a6b745062457335797444737142486435504646773d3d

用法:identify指令

而想知道這題的完整做法的人,可以看此Writeup

exiftool

Exiftool是一個專門用來讀寫和編輯文件元數據的cmd工具。此工具也支援了非常多的元數據種類,包括了EXIF, GPS, IPTC, XMP, JFIF, GeoTIFF, ICC Profile, Photoshop IRB, FlashPix, AFCP and ID3。當然也可辨認出某些元數據是來自什麼樣的數碼相機如Canon, Casio, DJI, FLIR, FujiFilm, GE, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Motorola, Nikon, Nintendo, Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Phase One, Reconyx, Ricoh, Samsung, Sanyo, Sigma/Foveon and Sony。

例子:只需輸入exiftool.exe 文件名,你就可以取得文件的Metadata了。

更多exiftool使用方法和功能可以到以下的鏈接裡面的Documentation學習。

binwalk

0x04 圖片隱寫術

GIF

文件結構

一个GIF文件的結構可分為

  • 文件頭(File Header)
  • GIF文件署名(Signature)
  • 版本號(Version)
  • GIF數據流(GIF Data Stream)
  • 控制標識符
  • 圖象塊(Image Block)
  • 其他的一些擴展塊
  • 文件終結器(Trailer)

下表顯示了一個GIF文件的組成結構:

中間的那個大塊可以被重複任意次。

文件頭

GIF署名(Signature)和版本號(Version)

GIF署名用來確認一個文件是否是GIF格式的文件,這一部分由三個字元組成:”GIF”;文件版本號也是由三個位元組組成,通常是”87a”或”89a”。

邏輯屏幕標識符(Logical Screen Descriptor)

Logical Screen Descriptor(邏輯屏幕描述符)緊跟在header後面。這個塊告訴decoder(解碼器)圖片需要占用的空間。它的大小固定為7個位元組,以canvas width(畫布寬度)和canvas height(畫布高度)開始。

全局顏色列表(Global Color Table)

GIF格式可以擁有global color table,或用於針對每個子圖片集,提供local color table。每個color table由一個RGB(就像通常我們見到的(255,0,0)紅色 那種)列表組成。

圖象標識符(Image Descriptor)

一個GIF文件一般包含多個圖片。之前的圖片渲染模式一般是將多個圖片繪製到一個大的(virtual canvas)虛擬畫布上,而現在一般將這些圖片集用於實現動畫。

每個image都以一個image descriptor block(圖象描述塊)作為開頭,這個塊固定為10位元組。

圖象數據(Image Data)

終於到了圖片數據實際存儲的地方。Image Data是由一系列的輸出編碼(output codes)構成,它們告訴decoder(解碼器)需要繪製在畫布上的每個顏色信息。這些編碼以位元組碼的形式組織在這個塊中。

文件終結器(Trailer)

該塊為一個單欄位塊,用來指示該數據流的結束。取固定值0x3b。

想完整了解的可看GIF格式圖片詳細解釋

分離GIF圖片

因為GIF是由多幅圖片組合而成,因此要分離GIF成PNG/JPG,我們可以在Linux裡面用convert gif名 圖片名指令來對GIF做出分離的動作。

CTF例題1 WDCTF-2017:3-2

而想知道這題的完整做法的人,可以看此Writeup

CTF例題2

利用GIF文件的時間間隔來當成是信息隱藏的載體。

PNG

PNG全稱為Protable Network Graphic,屬於無損壓縮位圖圖形格式(lossless data compression)。PNG的出現是為了改善以及替代GIF成為適合在網絡傳輸的圖片格式。此外PNG也具有以下的特色:

  • 最高支持24位真彩色圖像(24 bit RGB or 32 Bit RGBA)
  • 8位灰度圖像(無論是否為Alpha通道)。
  • 支持256色调色板計算,來生成體積容量較小的文件。
  • 支持Alpha通道和一般通道的透明/半透明特性。
  • 支持圖像亮度的Gamma校准信息。
  • 支持存储附加文本信息,以保留圖像名稱、作者、版權、創造時間、注釋等信息。
  • 漸近顯示和流式讀寫,適合在網絡傳輸中快速顯示預覽效果後再展示全貌。
  • 使用CRC防止文件出錯。
  • 最新的PNG標準還可以允许在一个文件內存储多幅圖像。

文件結構

首先PNG文件是由一個8字節的PNG文件標識(file signature)域和3個以上的後續數據塊(Chunk)組成。

文件頭89 50 4E 47 0D 0A 1A 0A + 數據塊 + 數據塊 + 數據塊…。

文件頭

十六進制 含義
89 用於檢測傳輸系統是否支持8位的字符編碼(8 bit data),用以減少將文本文件被錯誤的識別成PNG文件的機會,反之亦然。
50 4E 47 PNG每個字母對應的ASCII,讓用戶可以使用文本編輯器查看時,識別出是PNG文件。
0D 0A DOS風格的換行符(CRLF)。用於DOS-Unix數據的換行符轉換。
1A 在DOS命令行下,用於阻止文件顯示的文件結束符。
0A Unix風格的換行符(LF)。用於Unix-DOS換行符的轉換。

數據塊CHUNK

PNG定義了兩種類型的數據塊,一種是稱為關鍵數據塊(critical chunk),這是標準的數據塊,

另一種叫做輔助數據塊(ancillary chunks),這是可選的數據塊。關鍵數據塊定義了4個標準數據塊,每個PNG文件都必須包含它們,PNG讀寫軟件也都必須要支持這些數據塊。

而這些數據塊都由4個部分組成。
|名稱|字節數|說明|
|—–|——|——|
|Length (長度)|4字節|指定数据块中数据域的长度,其长度不超过(231-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域中的數據進行計算得到的。

IHDR

文件頭數據塊IHDR(header chunk)包含了儲存的圖像數據基本信息,由13字節組成,而且必須出現在PNG的第一段數據塊內,也只能有一個IHDR。

需要注意的是前8個字節的內容。
|域名稱|字節數|說明|
|—–|——|——|
|Width|4 bytes|圖像寬度,單位是像素|
|Height|4 bytes|圖像高度,單位是像素|

更關於PNG資料可看:

0x05 音頻

音頻分析三大走向:頻譜,波形,LSB

https://www.hackpwn.me/archives/272

0x06 視頻

0x07 文檔:Word / PDF

0x08 流量包:附件,協議,字符串拆分

0x09 交換數據流

0x10 HTML

0x11 Vmdk

0x12 Python字節碼

0x13 參考工具

1.Outguess
2.http://www.cnblogs.com/pcat/p/6716502.html

0x14 參考資料

1.隐写术个人总结
2.隐写术总结
3.圖片分析
4.世安杯-LSB隐写-png
5.PNG 文檔格式
6.CTF中隐写术一些基础【一】

0%