歡迎大家光臨我的個人博客,大家一起交流學習

chenjingjiu.cn本文大部分源於先知社區中M1n3所作Misc 總結 ----隱寫術之圖片隱寫一文,對其進行了相應的精簡併增加了自己的思考以作為自己的學習筆記,如有侵刪。

0x00 背景介紹

隱寫術是關於信息隱藏,即不讓計劃的接收者之外的任何人知道信息的傳遞事件(而不只是信息的內容)的一門技巧與科學,英文寫作Steganography。而密碼編碼是關於信息加密,即設想到信息可能會被接受者之外的第三方獲取而採取的一種措施,通過通信雙方預先設定的規則對信息進行加密,使第三方即使獲取到信息也無法理解其含義。所以隱寫術重點在於信息的隱藏,密碼編碼重點在於信息的加密,這兩者屬於完全不同的概念。

0x01 圖片隱寫術的分類

一、附加式的圖片隱寫

二、基於文件結構的圖片隱寫

三、基於LSB原理的圖片隱寫

四、基於DCT域的JPG圖片隱寫五、數字水印的隱寫六、圖片容差的隱寫

0x02 附加式的圖片隱寫

在附加式的圖片隱寫術中,通常用某種程序或者某種方法在載體文件中直接附加上需要被隱寫的目標,然後將載體文件直接傳輸給接受者或者發布到網站上,然後接受者者根據方法提取出被隱寫的消息,這一個過程就是附加式圖片隱寫。

在CTF賽事中,關於這種圖片隱寫的大概有兩種經典方式,一是直接附加字元串,二是圖種的形式出現。

A.附加字元串

這種方式是利用工具將隱藏信息直接寫入到圖片結束符之後,由於計算機中圖片處理程序識別到圖片結束符就不再繼續向下識別,因此後面的信息就被隱藏起來。這種方式可以利用winhex,ghex等工具進行打開,或者notepad打開也可看到最後的附加的字元,所以雖然簡單,但是隱藏效果不是很好。

windows下製作這種圖片的方式也有很多,比如剛才說到的winhex直接在文件尾寫入位元組,或利用copy /b a.jpg+b.txt c.jpg來進行製作。其中a.jpg是一張普通圖片,即將作為信息的載體,b.txt中是隱藏的信息,c.jpg是附加了隱藏信息的圖片,發送時就是發送c.jpg。

B.圖種圖種是一種採用特殊方式將圖片文件(如jpg格式)與rar文件結合起來的文件。該文件一般保存為jpg格式,可以正常顯示圖片,當有人獲取該圖片後,可以修改文件的後綴名,將圖片改為rar壓縮文件,便可得到其中的數據。剛才我們說過,因為計算機中圖片處理程序識別圖片的過程是,從圖片頭開始,以圖片頭聲明的格式所定義的編碼格式對數據流進行讀取,一直到圖片的結束符,當圖片處理程序識別到圖片的結束符後,不再繼續向下識別,所以我們在通常情況下只能看到它是隻是一張圖片。

但使用binwalk程序可以輕鬆對其進行識別並還原,binwalk程序在上一篇博客中有講解。也可以利用winhex尋找到圖片的結束符,然後在其後查找是否有zip或rar等文件的文件頭。最後也可利用轉換文件後綴對其進行讀取並解壓,具體過程在這篇博客中有用到。

0x03 基於文件結構的圖片隱寫

這裡的文件結構特指的是圖片文件的文件結構。我們這裡主要講的是PNG圖片的文件結構。

PNG,圖像文件存儲格式,其設計目的是試圖替代GIF和TIFF文件格式,同時增加一些GIF文件格式所不具備的特性。是一種點陣圖文件(bitmap file)存儲格式,讀作「ping」。PNG用來存儲灰度圖像時,灰度圖像的深度可多到16位,存儲彩色圖像時,彩色圖像的深度可多到48位,並且還可存儲多到16位的α通道數據。

對於一個正常的PNG圖片來講,其文件頭總是由固定的位元組來表示的,其16進位表示為 89 50 4E 47 0D 0A 1A 0A,這一部分稱作PNG文件頭。標準的PNG文件結構應包括:1.PNG文件標識

2.PNG數據塊PNG圖片有兩種數據塊的,一種是關鍵數據塊,另一種是輔助數據塊。正常的關鍵數據塊,定義了4種標準數據塊,分別是長度,數據塊類型碼,數據塊數據,循環冗餘檢測即CRC,每個PNG文件都必須包含它們。

我們這裡重點先了解一下,PNG圖片文件頭數據塊以及PNG圖片IDAT塊,這次的隱寫也是以這兩個地方為基礎的。

PNG圖片文件頭數據塊即IHDR(Image HeaDeR),這是PNG圖片的第一個數據塊,一張PNG圖片僅有一個IHDR數據塊,它包含了圖片的寬,高,圖像深度,顏色類型,壓縮方法等等信息。(即定義圖片數據流的讀取規則)

PNG圖片IDAT(Image DATa)數據塊它存儲實際的數據,在數據流中可包含多個連續順序的圖像數據塊。這是一個可以存在多個數據塊類型的數據塊。它的作用就是存儲著圖像真正的數據。因為它是可以存在多個的,所以即使我們寫入一個多餘的IDAT也不會明顯影響肉眼對圖片的觀察。高度被修改引起的隱寫

剛才我們瞭解到,IHDR中定義了圖片的高度和寬度,可以通過修改高度值或寬度值對部分信息進行隱藏。

如果圖片原本是800(寬)*600(高),然後圖片的高度從600變成500,這樣下面800×100區域的信息就無法從圖片中顯示出來,我們可見的只有上方800*500的區域,這樣就達成了圖片隱寫的目的。同理可知圖片的寬度也可以進行類似的修改以達到隱藏信息的目的。

為了還原圖片,可以利用winhex或者010Editor等編輯器打開圖片。但我們推薦後者,因為它提供了不同文件的模板,通過載入png模板,我們可以直觀的知道哪裡是PNG的長度欄位或寬度欄位,它提供了hex字元串到欄位名的映射,更便於我們進行修改。在修改文件後,需要利用CRC Calculator對CRC校驗碼進行重新計算賦值,以防圖片被修改後,自身的CRC校驗報錯,導致圖片不能正常打開。

圖片中加入IDAT塊以實現隱寫

剛才我們提到過一個圖片的IDAT塊是可以存在多個的,這也導致我們可以利用添加IDAT塊的方式來實現信息的隱寫。

利用PNGcheck軟體可以驗證PNG文件的完整性,利用pngcheck -v a.jpg可以對圖片的文件結構進行檢測。

文件結構中可能會存在size=0的IDAT塊,這說明相應的塊是無法用肉眼看到的,也即隱藏的內容。可以通過腳本對隱藏內容進行提取。現在我還沒有刷到類似的題,刷到了會補鏈接和代碼。

0x04 基於LSB原理的圖片隱寫

LSB,最低有效位,英文是Least Significant Bit 。我們知道圖像像素一般是由RGB三原色(即紅綠藍)組成的,每一種顏色佔用8位,0x00~0xFF,即一共有256種顏色,一共包含了256的3次方的顏色,顏色太多,而人的肉眼能區分的只有其中一小部分,這導致了當我們修改RGB顏色分量中最低的二進位位的時候,我們的肉眼是區分不出來的。

簡單的LSB隱寫這種隱寫僅對於某一通道值進行改寫。將要隱寫的信息圖片直接覆蓋該通道的相應值,即可實現信息的隱寫。這種方式利用Stegsolve軟體變換圖層即可實現還原,相比而言隱祕性較低。

有一點難度的LSB隱寫最簡單的隱寫我們只需要通過工具Stegsolve切換到不同通道,可以直接看到隱寫內容了,那麼更複雜一點就不是這麼直接了,而是隻能通過工具來查看LSB的隱寫痕跡,再通過工具或者腳本的方式提取隱寫信息。

今年阿里春招的第一題就是類似的題目,問的是圖片和視頻的隱寫方式。當時還沒有接觸過LSB的我寫出了如下的回答:操作圖片中的某些像素點,通過調整該像素點的RGB值,或其中的某一個值,達到隱藏信息的作用。可以將要嵌入的信息進行編碼,變換為01字串,然後順序加到每一個像素點的RGB值上去。因為RGB閾值是0-255,若是當前像素點的RGB中某一個值已經是255,則將該值減一,保證不會超出其閾值,又不容易被發現。傳輸時同時傳送兩張圖片,一張是原來的圖片,一張是嵌入信息後的圖片。兩方商量好加解密的規則,傳送後,對兩張圖片中每一個像素的RGB信息作差取絕對值,還原01字串。對於RGB值的輕微改動一般無法用肉眼發現,可以保障該方法的隱祕性。(當時直接保存下來的,沒有進行任何的修改)

現在看來這種方式有點像一種LSB,也有點像後面要提到的容差隱寫,只不過當時不知道其名詞而已。這種方式的解密,可以利用工具將每個LSB的值導出為一個流,然後轉換為字元串進行讀取。這種方式的隱蔽性相對來講較高,一般難以發現。

0x05 基於DCT域的JPG圖片隱寫

JPEG圖像格式使用離散餘弦變換(Discrete Cosine Transform,DCT)函數來壓縮圖像,而這個圖像壓縮方法的核心是:通過識別每個8×8像素塊中相鄰像素的重複像素來減少顯示圖像所需的位數,並使用近似估演算法降低其冗餘度。因此,我們可以把DCT看作一個用於執行壓縮的近似計算方法。因為丟失了部分數據,所以DCT是一種有損壓縮(Loss Compression)技術,但一般不會影響圖像的視覺效果。(有點CNN的影子)在這個隱寫家族中,常見的隱寫方法有JSteg、JPHide、Outguess、F5等等

Stegdetect實現JPEG圖像Jphide隱寫演算法工具有多個,比如由Neils Provos開發通過統計分析技術評估JPEG文件的DCT頻率係數的隱寫工具Stegdetect,它可以檢測到通過JSteg、JPHide、OutGuess、Invisible Secrets、F5、appendX和Camouflage等這些隱寫工具隱藏的信息,並且還具有基於字典暴力破解密碼方法提取通過Jphide、outguess和jsteg-shell方式嵌入的隱藏信息。

JPHS

一款JPEG圖像的信息隱藏軟體JPHS,它是由Allan Latham開發設計實現在Windows和Linux系統平臺針對有損壓縮JPEG文件進行信息加密隱藏和探測提取的工具。軟體裡面主要包含了兩個程序JPHIDE和JPSEEK, JPHIDE程序主要是實現將信息文件加密隱藏到JPEG圖像功能,而JPSEEK程序主要實現從用JPHIDE程序加密隱藏得到的JPEG圖像探測提取信息文件,Windows版本的JPHS裏的JPHSWIN程序具有圖形化操作界面且具備JPHIDE和JPSEEK的功能。

OutguessOutgusee演算法是Niels Provos針對Jsteg演算法的缺陷提出的一種方法:

1.嵌入過程不修改ECT係數值為0,1的DCT係數,利用為隨機數發生器產生間隔以決定下一個要嵌入的DCT係數的位置

2.糾正過程消除對效應的出現對應的,也有針對該演算法的隱寫工具,名字也叫Outguess。

對於這種隱寫方法的還原,首先利用Stegdetect對圖片進行檢測,判斷該圖片利用的是何種隱寫方式。然後針對不同的隱寫方式,選擇對應的工具進行信息的還原。比如利用JPHS還原jphide隱寫,利用Outguess還原outguess隱寫等等。

0x06 數字水印隱寫

數字水印(digital watermark)技術,是指在數字化的數據內容中嵌入不明顯的記號。特徵是被嵌入的記號通常是不可見或不可察的,但是可以通過計算操作檢測或者提取。

盲水印與傅裏葉變換

盲水印,是指人感知不到的水印,包括看不到或聽不見(沒錯,數字盲水印也能夠用於音頻)。其主要應用於音像作品、數字圖書等,目的是,在不破壞原始作品的情況下,實現版權的防護與追蹤。

對圖像進行傅裏葉變換,起始是一個二維離散傅裏葉變換,圖像的頻率是指圖像灰度變換的強烈程度,將二維圖像由空間域變為頻域後,圖像上的每個點的值都變成了複數,也就是所謂的復頻域,通過複數的實部和虛部,可以計算出幅值和相位,計算幅值即對複數取模值,將取模值後的矩陣顯示出來,即為其頻譜圖。但是問題來了,複數取模後,數字有可能變的很大,遠大於255,如果數據超過255,則在顯示圖像的時候會都當做255來處理,圖像就成了全白色。因此,一般會對模值再取對數,在在0~255的範圍內進行歸一化,這樣纔能夠準確的反映到圖像上,發現數據之間的差別,區分高頻和低頻分量,這也是進行傅裏葉變換的意義。具體盲水印的提取等遇到了再回來補。

0x07 容差比較的隱寫

容差,指的是在選取顏色時所設置的選取範圍,容差越大,選取的範圍也越大,其數值是在0-255之間。

在隱寫術方面,可以根據容差進行信息的隱藏。若是有兩張圖片,則對兩張圖片的每一個像素點進行對比,設置一個容差的閾值α,超出這個閾值的像素點RGB值設置為(255,255,255),若是沒超過閾值,則設置該像素點的RGB值為(0,0,0)。因此,通過調整不同的α值,可以使對比生成的圖片呈現不同的畫面。比如兩張圖完全一樣,設置閾值α為任何值,最後得到的對比圖都只會是全黑。若兩張圖每一個像素點都不同,閾值α設置為1,則對比圖將是全白。如果將隱藏信息附加到某些像素點上,這時調整閾值α即可看到隱藏信息。

如果是一張圖片,則根據每一像素點周圍像素的值進行判斷,同樣設置一個閾值,若當前像素點超過周圍像素點的均值,或者其它的某種規則,則將該像素點RGB值置為(255,255,255),反之則不進行處理,或者設置為全0.這樣也可以獲得隱藏的信息。

其實這種隱寫方式也有點像我在阿里筆試中提到的隱寫方式,那就是需要兩張圖片的對比獲取其差值,然後再通過差值得到隱藏信息。只不過這個是通過圖片的形式獲得了信息,而我所想的是通過對比獲得01bit流,然後bit流根據雙方協定的規則進行還原再得到隱藏信息。我所構想的這種方式可以實現多種隱寫術的嵌套應用,比如01位元組流還原後是一個jpg格式的文件,這個文件就又可以進行圖片隱寫術。也可以通過編碼規則的不同實現最底層的數據加密,當然這些在實際中也不一定有多少應用場景吧,有這個功夫直接加密就好了,何必用這麼複雜的隱寫術呢。

0x08 總結

本文總結了目前較為流行的幾種圖片隱寫方法,對它們進行了分類並闡述了相關原理。具體實例我遇到過的都給了博客鏈接,沒有遇到的以後會再補。通過這一篇博文的撰寫得到了很多收穫,印證了我想到的隱寫術是確實存在的,這對於我的信心也是一個鼓舞。未來還是要多看,多學,才能在實踐中更加遊刃有餘。

路漫漫其修遠兮,吾將上下而求索
推薦閱讀:
相關文章