太常見太常見,圖像文件有多種複雜的格式,可以用於各種涉及到元數據、信息丟失和無損壓縮、校驗、隱寫或可視化數據編碼的分析解密,都是 Misc 中的一個很重要的出題方向。
圖片隱寫術的基礎知識——元數據隱寫
元數據(Metadata),又稱中介數據、中繼數據,為描述數據的數據(Data about data),主要是描述數據屬性(property)的信息,用來支持如指示存儲位置、歷史數據、資源查找、文件記錄等功能。
元數據中隱藏信息在比賽中是最基本的一種手法,通常用來隱藏一些關鍵的 Hint 信息或者一些重要的比如password 等信息。
這類元數據可以 右鍵 -> 屬性 查看
介紹兩個命令
strings:列印可列印的字符,通常可以發現隱藏在壓縮包中的注釋內容或者是解壓需要的密碼等。
inentify:用於獲取一個或多個圖像文件的格式和特徵,用來提取一些特定的數據。
PNG圖片
文件格式:對於PNG文件來說,其文件頭總是由固定的字節來描述的,剩餘的部分由3個以上的PNG數據塊(Chunk)按照特定的順序組成。
文件頭:89 50 4E 47 0D 0A 1A 0A + 數據塊 + 數據塊 + 數據塊…..
數據塊(Chunk)
PNG 定義了兩種類型的數據塊,一種是稱為關鍵數據塊(critical chunk),這是標準的數據塊,另一種叫做輔助數據塊(ancillarychunks),這是可選的數據塊。關鍵數據塊定義了 4 個標準數據塊,每個 PNG 文件都必須包含它們,PNG 讀寫軟體也都必須要支持這些數據塊。
對於每個數據塊都有著統一的數據結構,每個數據塊由 4 個部分組成
IHDR(文件頭數據塊)
文件頭數據塊 IHDR(HeaderChunk):它包含有 PNG 文件中存儲的圖像數據的基本信息,由 13 字節組成,並要作為第一個數據塊出現在 PNG 數據流中,而且一個 PNG 數據流中只能有一個文件頭數據塊,其中我們只關注前8位元組的內容
經常會去更改一張圖片的高度或者寬度使得一張圖片顯示不完整從而達到隱藏信息的目的。
Kali中不可以打開,提示文件頭錯誤,而Windows自帶的圖片查看器可以打開,就提醒了我們IHDR被人篡改過。
說到這裡我們來看一個題:藍盾的一個題(Bluedon.zip)
偽加密解密後解壓出一張圖片
用winhex打開看一下,注意這個位置
發現寬是500像素,但是高是436像素,將其進行修改,修改高同為500像素
得出flag。
IDAT(圖像數據塊)
IDAT:存儲實際的數據,在數據流中可包含多個連續順序的圖像數據塊。
儲存圖像像數數據。
在數據流中可包含多個連續順序的圖像數據塊。
採用 LZ77 算法的派生算法進行壓縮。
可以用 zlib 解壓縮。
* IDAT塊只有當上一個塊充滿時,才會繼續下一個新塊。*
也可以使用Stegsolve -> Format Analysis有詳細介紹
看一個題:sctf-misc400(sctf.png)
用pngcheck去查看此png圖片
正常的塊的 length 是在 65524 的時候就滿了,而倒數第二個 IDAT 塊長度是 45027,最後一個長度是 138,很明顯最後一個 IDAT 塊是有問題的,因為它本應該並如倒數第二個塊
這是倒數第二個塊的開始部分(可以從上圖中得知其開始數據)
這是最後一個塊
最後一個塊沒有併入倒數第二個塊,那應該是最後一個塊有問題
49 44 41 54為數據塊頭部開始信息,D9 CF A5 A8為crc32校驗位,前邊得知IDATA採用 LZ77 算法的派生算法進行壓縮並可以用 zlib 解壓縮。利用python zlib解壓多餘的IDATA內容塊,需注意要剔除開始頭部信息、數據塊類型以及末尾的CRC校驗值,所以最後所得的數據為:
789C5D91011280400802BF04FFFF5C75294B5537738A21A27D1E49CFD17DB3937A92E7E603880A6D485100901FB0410153350DE83112EA2D51C54CE2E585B15A2FC78E8872F51C6FC1881882F93D372DEF78E665B0C36C529622A0A45588138833A170A2071DDCD18219DB8C0D465D8B6989719645ED9C11C36AE3ABDAEFCFC0ACF023E77C17C7897667
import zlibimport binasciiIDAT = "789...667".decode('hex')result = binascii.hexlify(zlib.decompress(IDAT))print result
31313131313131303030313030303031313031313131313131313030303030313031313130303130313130313030303030313130313131303130313030303030303030303130313131303131303131313031303031303030303030303031303131313031313031313130313031313130313130313030313031313130313130303030303130313031303131303131303130303030303131313131313131303130313031303130313031313131313131303030303030303031303131313031313130303030303030303131303130303131303030303031303130303131313031313031313131303130313031303031303030303131313030303030303030303030313031303030303030303031303031303031313031303030313030313131303031313131303131313030313131313030303031313130313131313130303031313030313031303030313130303131313030303031303130313030303131303130303031313131303130313130303030303130313030303130313130303030303131303131313031313030313030303031313130303131313030313030303031303131313131313130313030303030303030313130313031303031303030313131313031313131313131303131313030303031313031303131303131313030303030313030303031313030313130303031313131303130313131303130303031313031303031313131313030303031303131313031303131303030313131303130303131313030313031313130313030313030313131303131303131303030313130303030303130313130303031313031303030313130303031313131313131303131303130313130313131303131303131
30 和 31是hex 的 0和 1的編碼,再解一次hex得到一串01字符串
1111111000100001101111111100000101110010110100000110111010100000000010111011011101001000000001011101101110101110110100101110110000010101011011010000011111111010101010101111111000000001011101110000000011010011000001010011101101111010101001000011100000000000101000000001001001101000100111001111011100111100001110111110001100101000110011100001010100011010001111010110000010100010110000011011101100100001110011100100001011111110100000000110101001000111101111111011100001101011011100000100001100110001111010111010001101001111100001011101011000111010011100101110100100111011011000110000010110001101000110001111111011010110111011011
長度為625,7和8都無法整除,也就是說沒法直接轉換為ASCII碼。
ASCII 知識補充
計算機內部,所有信息最終都表示為一個二進位的字符串,每一個二進位位有0和1兩種狀態,因此8個二進位位有256種狀態,被稱為一個字節(byte)。
一個字節一共可以用來表示256種不同的狀態,每一個狀態對應一個符號,也就是256個符號,從00000000到11111111。ASCII一共規定了128個字符的編碼,比如空格「Space」是32(00100000)。這128個符號(包括32個不可列印的控制符號),只佔用了一個字節的後7位,最前面一位統一規定為0.
這也就可以理解為什麼從7和8判斷不可以轉成ASCII碼。
625 = 25*25,是正方形的形狀,利用python的PIL庫將畫圖
#!/usr/bin/env pythonimport ImageMAX = 25pic = Image.new("RGB",(MAX, MAX))str = "1111111000100001101111111100000101110010110100000110111010100000000010111011011101001000000001011101101110101110110100101110110000010101011011010000011111111010101010101111111000000001011101110000000011010011000001010011101101111010101001000011100000000000101000000001001001101000100111001111011100111100001110111110001100101000110011100001010100011010001111010110000010100010110000011011101100100001110011100100001011111110100000000110101001000111101111111011100001101011011100000100001100110001111010111010001101001111100001011101011000111010011100101110100100111011011000110000010110001101000110001111111011010110111011011"i=0for y in range (0,MAX): for x in range (0,MAX): if(str[i] == '1'): pic.putpixel([x,y],(0, 0, 0)) else: pic.putpixel([x,y],(255,255,255)) i = i+1pic.show()pic.save("flag.png")
發現是個二維碼,畫出來後0代表白色,1代表黑色,需要旋轉或者反色才可以掃描出來,然後得到flag.
另一種方法:
binwalk查看
後面是Zlib壓縮的數據,寫個腳本解壓一下:
from PIL import Imagefrom zlib import * data = open('400b.PNG','rb').read()[0x15AFFB:]data = decompress(data) img = Image.new('1', (25,25))d = img.load() for n,i in enumerate(data):d[(n%25,n/25)] = int(i)*255 f = open('2.png','wb')img.save(f)
得到一個二維碼,但是不能訪問:
PS變相之後就可以了 微信掃一掃,SCTF{(121.518549,25.040854)}
IEND
圖像結束數據 IEND(image trailer chunk):它用來標記 PNG 文件或者數據流已經結束,並且必須要放在文件的尾部。
00 00 00 00 49 45 4E 44 AE 42 60 82
END 數據塊的長度總是 00 00 00 00 ,數據標識總是 IEND 49 45 4E 44,因此,CRC 碼也總是 AE 42 60 82。
其餘的輔助數據塊:
背景顏色數據塊 bKGD(background color)
基色和白色度數據塊 cHRM(primary chromaticities and white point),所謂白色度是指當 R=G=B=最大值 時在顯示器上產生的白色度
圖像 γ 數據塊 gAMA(image gamma)
圖像直方圖數據塊 hIST(image histogram)
物理像素尺寸數據塊 pHYs(physical pixel dimensions)
樣本有效位數據塊 sBIT(significant bits)
文本信息數據塊 tEXt(textual data)
圖像最後修改時間數據塊 tIME (image last-modification time)
圖像透明數據塊 tRNS (transparency)
壓縮文本數據塊 zTXt (compressed textual data)
利用LSB來進行隱寫
LSB全稱LeastSignificant Bit,也就是最低有效位。
PNG文件中的圖像像數一般是由RGB三原色組成,每一種顏色佔用8位,取值範圍為0×00~0xFF,即256種顏色,一共包含了256的三次方的顏色,即16777216(1千677W)種顏色。人類的眼睛可以區分約1000萬種不同的顏色,這就意味著人類的眼睛無法區分餘下的顏色大約有6777216(677W)種。
LSB隱寫就是修改RGB顏色分量的最低二進位位(LSB),每個顏色都會有8bit,LSB隱寫就是修改了像數中的最低的1Bit,而人類的眼睛不會注意到這前後的區別,每個像數可以攜帶3Bit的信息,這樣就把信息隱藏起來了。
譬如把』A』隱藏起來,如下圖,可以把A轉成十六進位的0×61,再轉成二進位的01100001,再修改紅色通道的最低位為這些二進位串。
如果是要尋找這種 LSB 隱藏痕跡的話,可以使用工具 Stegsolve來輔助我們進行分析。
通過下方的按鈕可以觀察每個通道的信息,例如查看 R 通道的最低位第 8 位平面的信息。
例題:lsb.png
打開為普通圖片一張
使用stegsolve瀏覽通道獲得二維碼
掃描得到flag
如果隱寫使用了ascii的時候,可以使用Stegsolve—Analyse—DataExtrack來查看ascii碼。
例題:HCTF 2016 MISC(flag.php)
Analyse -> Data Extract,發現是zip格式的
提取之後保存為ZIP格式,但是打不開
利用winrar的修復功能進行修復
解壓後提取是一個1,使用file查看為ELF文件
給他一個X,運行後得到flag
JPG圖片
文件結構
JPEG 是有損壓縮格式,將像素信息用JPEG 保存成文件再讀取出來,其中某些像素值會有少許變化。在保存時有個質量參數可在 0 至 100 之間選擇,參數越大圖片就越保真,但圖片的體積也就越大。一般情況下選擇 70 或 80 就足夠了。
JPG 基本數據結構為兩大類型:「段」和經過壓縮編碼的圖像數據。
有些段沒有長度描述也沒有內容,只有段標識和段類型。文件頭和文件尾均屬於這種段。
段與段之間無論有多少FF都是合法的,這些FF被稱為[填充字節],必須被忽略掉。
0xFFD8和0xFFD9為JPG文件的開始結束的標誌。
隱寫軟體
Stegdetect(https://github.com/redNixon/stegdetect)
通過統計分析技術評估 JPEG 文件的DCT 頻率係數的隱寫工具, 可以檢測到通過 JSteg、JPHide、OutGuess、InvisibleSecrets、F5、appendX 和 Camouflage 等這些隱寫工具隱藏的信息,並且還具有基於字典暴力破解密碼方法提取通過 Jphide、outguess 和jsteg-shell 方式嵌入的隱藏信息。
JPHS(http://linux01.gwdg.de/~alatham/stego.html)
JPEG 圖像的信息隱藏軟體 JPHS,它是由 Allan Latham 開發設計實現在 Windows 和 Linux 系統平臺針對有損壓縮 JPEG 文件進行信息加密隱藏和探測提取的工具。軟體裡面主要包含了兩個程序 JPHIDE和 JPSEEK。JPHIDE程序主要是實現將信息文件加密隱藏到 JPEG 圖像功能,而JPSEEK 程序主要實現從用 JPHIDE 程序加密隱藏得到的 JPEG 圖像探測提取信息文件,Windows 版本的 JPHS 裡的 JPHSWIN 程序具有圖形化操作界面且具備 JPHIDE 和 JPSEEK 的功能。
GIF圖片
空間軸
由於GIF的動態特性,由一幀幀的圖片構成,所以每一幀的圖片,多幀圖片間的結合,都成了隱藏信息的一種載體。
對於要分離的GIF文件,可以使用convert命令將其每一幀分割開來,也可以使用GIF分離工具。
時間軸
GIF文件每一幀間的時間間隔也可以作為信息隱藏的載體。
Stegsolve也可以一幀一幀的觀察圖片(Stegsolve -> Analyse -> Frame Brower)
來看個題:FBCTF (安哥拉_一步一步)
打開後是一個gif圖片,用分幀工具分開後沒啥信息,用PS打開後拖動時間軸看到flag
圖種
概念:在普通圖片中存儲了別的文件(如壓縮包信息等等),比較典型的不就是圖馬嗎?
copy /b xxx.jpg + xx.zip output.jpg
直接用十六進位編輯器打開查看查看相關字符串,或者用binwalk查看是否有其他文件的存在。
雙圖
例題:ISG2014-MISC(final.png)
使用binwalk查看是否有壓縮包等其他文件
使用foremost將裡邊包含的信息分離出來,分離出兩張和原圖看似一樣的圖片,使用diff查看兩張文件不同,使用compare將不同的地方進行輸出
分別保存為1.png,2.png
利用python的image包對其進行元素點對比,並8bit一組提取
from PIL import Imageimport random img1 = Image.open('1.png')im1 = img1.load() img2 = Image.open('2.png')im2 = img2.load() a = 0i = 0s = '' for x in range(img1.size[0]): fory in range(img1.size[1]): if(im1[x,y]!= im2[x,y]): printim1[x,y],im2[x,y] ifi==8: s= s + chr(a) a= 0 i= 0 a= im2[x,y][0] + a*2 i= i + 1s = s + '}'print s
與音頻相關的 CTF 題目主要使用了隱寫的策略,主要分為 MP3 隱寫,波形隱寫,頻譜隱寫,LSB隱寫等等。
常見手段
通過 binwalk 以及 strings 可以發現的信息不再詳述。
MP3隱寫
MP3隱寫主要是使用 Mp3Stego 工具進行隱寫,其基本介紹及使用方法如下:
MP3Stego willhide information in MP3 files during the compression process. The data is firstcompressed, encrypted and then hidden in the MP3 bit stream.
encode –E hidden_text.txt –P pass svega.wav svega_stego.mp3
decode –X –P pass svega_stego.mp3
這裡所使用的源文件需要使用RIFF文件
RIFF文件
RIFF全稱為資源互換文件格式(ResourcesInterchange FileFormat),RIFF文件是windows環境下大部分多媒體文件遵循的一種文件結構,RIFF文件所包含的數據類型由該文件的擴展名來標識,能以RIFF文件存儲的數據包括如下:
音頻視頻交錯格式數據(.AVI)
波形格式數據(.WAV)
位圖格式數據(.RDI)
MIDI格式數據(.RMI)
調色板格式(.PAL)
多媒體電影(.RMN)
動畫光標(.ANI)
其它RIFF文件(.BND)
例題:1.mp3
利用mp3stego進行解密,發現需要密碼
記得前邊說過的嗎?使用strings可以發現一些隱藏的密碼、文件等,
發現裡邊有flag.txt,好吧,沒有明顯的密碼,但是放到kali下,mp3的圖標變成了一張圖片
emmmmmmm..用foremost對其進行分離
葫蘆小金剛 英文為:GourdSmallDiamond
decode -X -P GourdSmallDiamond 1.mp3
剛才foremost提取出來的還有一個壓縮包,用密碼進行解壓得到flag
波形隱寫
原理:通常來說,波形方向的題,在觀察到異常後,使用相關軟體(Audacity, Adobe Audition 等)觀察波形規律,將波形進一步轉化為01 字符串等,從而提取轉化出最終的 flag。
看題:ISCC Misc 普通DISCO
解壓出個wav文件,使用audacity打開後,放大音頻波形拉到最開始部分
以高的為1,低的為0得到flag的二進位
110011011011001100001110011111110111010111011000010101110101010110011011101011101110110111011110011111101
長度為105位,可以除以7但是不能除以8,根據前邊ASCII碼的知識,在每7位前邊補0
011001100110110001100001011001110111101101010111001100000101011100101010011001100111010101101110011011100111100101111101
將其轉換為16進位後,在將十六進位轉換為字符串得出flag
例題2:musci111.zip
解壓後出現兩個文件:pic.jpg和musci.zip,壓縮包有密碼
圖片的密文格式為盲文,解密為kmdonowg,解壓後使用audacity分析
長短用-.表示,然後用摩絲解碼工具進行解碼即可得到flag.
頻譜隱寫
音頻中的頻譜隱寫是將字符串隱藏在頻譜中,此類音頻通常會有一個較明顯的特徵,聽起來是一段雜音或者比較刺耳。
例題:FBCTF 巴基斯坦_聽音樂
用audacity打開後,將其更改為頻譜圖
得到flag
LSB音頻隱寫
類似於圖片隱寫中的 LSB 隱寫,音頻中也有對應的 LSB 隱寫。主要可以使用Slienteye,其介紹如下:
SilentEye是跨平臺的應用程式,便於使用隱寫術,在這種情況下將消息隱藏到圖片或聲音中。 SilentEye的界面簡潔,並且通過使用插件系統,可以輕鬆集成新的隱寫算法和加密過程。
例題:小蘋果
使用工具silenteye打開後,點擊decode即可
直接聽..
直接聽就是直接聽..
看例題,全國大學生信息安全賽(永不消逝的電波)
慢慢聽就是了,注意點信號(.)是滴,長信號(-)是噠
…. .-.. . .. -.-. .. -.-. – … – .– — — -.-. ..-. . — -.-. -. .—-
解密得到:HLEICICTSTWOOCFEMCN1
根據裡邊字符判斷應該有hello welcome
柵欄密碼解密
Flag{HIWELCOMETOCISCNCTF1}
六、視頻隱寫這個見的倒是略少,準備一份工具到時候如果簡單看或者聽或其他已經會的方法還分析不出來就直接丟工具把
工具見下方網盤。
七、取證大部分的 CTF 比賽中,取證及隱寫兩者密不可分,兩者所需要的知識也相輔相成,所以這裡也將對兩者一起介紹。
任何要求檢查一個靜態數據文件從而獲取隱藏信息的都可以被認為是隱寫取證題(除非單純地是密碼學的知識),一些低分的隱寫取證又常常與古典密碼學結合在一起,而高分的題目則通常用與一些較為複雜的現代密碼學知識結合在一起,很好地體現了 Misc 題的特點。
前置技能1、了解常見的編碼
2、能夠對文件中出現的一些編碼進行解碼,並且對一些特殊的編碼(Base64、十六進位、二進位等)有一定的敏感度,對其進行轉換並得到最終的 flag。
3、能夠利用腳本語言(Python 等)去操作二進位數據
4、熟知常見文件的文件格式,尤其是各類 文件頭、協議、結構等
5、靈活運用常見的工具
常用工具1、EasyRecovery
2、MedAnalyze
3、FTK
4、Elcomsoft Forensic Disk Decryptor
5、Volatility (http://www.freebuf.com/articles/system/26763.html)
磁碟常見的磁碟分區格式有以下幾種:
1、Windows:FAT12 -> FAT16 -> FAT32 -> NTFS
2、linux:EXT2 -> EXT3 -> EXT4
VMDKVMDK 文件本質上是物理硬碟的虛擬版,也會存在跟物理硬碟的分區和扇區中類似的填充區域,我們可以利用這些填充區域來把我們需要隱藏的數據隱藏到裡面去,這樣可以避免隱藏的文件增加了 VMDK 文件的大小(如直接附加到文件後端),也可以避免由於 VMDK 文件大小的改變所帶來的可能導致的虛擬機錯誤。而且 VMDK 文件一般比較大,適合用於隱藏大文件。
內存1、解析析Windows / linux / Mac OS X內存結構
2、分析進程,內存數據
3、根據題目提示尋找線索和思路,提取分析指定進程的特定內存數據。
例題:
http://www.freebuf.com/column/152545.html
http://www.freebuf.com/articles/rookie/145262.html
我的取證水平目前處於菜鳥級選手,還是看看別人家的分析吧~~
說一個比較經典有趣的 hundouluo
通關後即可得到flag
比賽的時候真的3條命打通關??
輸入金手指:
直接通關 00AA-01-03
金身:00B0-01-FF
無限命:0032-01-20
附上一條:FC NES修改教程
題目二:藍盾2017移動安全賽 (就在眼前)
打開後發現一個word文件,裡邊有一堆十六進位字符
flag=E5=80=BC=E5=B0=B1=E5=9C=A8=E6=AD=A4=E6=96=87=E6=A1=A3=E4=B8=AD=EF=BC=8C=E5=B9=B6=E4=B8=94=E4=BD=BF=E7=94=A8=E4=BA=86=E6=96=87=E6=9C=AC=E9=9A=90=E8=97=8F=E6=8A=8A=E8=87=AA=E5=B7=B1=E9=9A=90=E8=97=8F=E8=B5=B7=E6=9D=A5=E4=BA=86=E3=80=82=0A=E6=98=BE=E7=A4=BA=E5=87=BA=E9=9A=90=E8=97=8F=E6=96=87=E6=9C=AC=E5=8D=B3=E5=8F=AF
在選項中去掉隱藏文字
得到flag,這種題以前做過了,直接進行選項的修改。還有一種是把所有的文字換個顏色也就出來了。所以知道套路之後也就不用再一步一步去解碼了。
文章差不多就到這了,裡邊還有好多東西沒有補充完全,CTF中雜項的知識點以及各種奇怪的腦洞遠不是一篇文章可以說的完的,也還是在不斷補充姿勢不斷學習的過程中充實自己提升自己。
以前我也是個小白(其實現在也不咋滴..)在準備CTF的時候遇到相關的問題也曾多次看這些前輩所發表的文章來學習知識。雖然說常見的基礎套路翻過來翻過去也就那麼多,但是對於初入門CTF的同學還是帶著很多盲目。
所以今天發表這篇文章,以自己在學習路途中所發現的和所學習到的知識。希望能夠對初入CTF的同學有所幫助,在學習路途中儘量少走彎路,從而可以更快的提升自己,也可以在比賽中更加從容,更加自信。
最後祝大家學業有成,工作順利。
連結:https://pan.baidu.com/s/1NkW0i-wbT7s1XmUAT5IuKw 密碼:2obq
參考文章:http://bobao.360.cn/learning/detail/243.html
https://www.anquanke.com/post/id/86211
https://ctf-wiki.github.io
http://blog.sina.com.cn/s/blog_9cd8465f0102v6ok.html
https://wenku.baidu.com/view/17fb9833ccbff121dd368371.html
推薦實驗
wireshark之文件還原——(點擊閱讀原文操作實驗)
實驗簡介:
本實驗主要介紹了wireshark文件還原技術,通過本實驗的學習,你能夠了解wireshark的使用方法,能夠通過分析還原網絡數據發送現場,並將發送的信息通過wireshark和winhex還原成原文件。