
每天都會在攻防世界刷兩三道題這個習(xí)慣保持了挺長一段時間?!懊咳蘸脦拙殹边@個系列我打算堅持寫下去記錄自己踩過的坑和整理過的思路。第2篇想聊聊Misc方向重點拆一道關(guān)鍵詞里帶message的圖片題。說實話Misc題在很多新手眼里像開盲盒不知道從哪里下手。但做得多了會發(fā)現(xiàn)它其實有非常清晰的套路文件識別、隱寫檢測、編碼解碼、上下文推理每一步都有對應(yīng)的工具和判斷邏輯。今天就把這道題的完整推理過程連同我做題時的思考、卡殼和復(fù)盤原原本本寫下來。不論你是剛開始接觸CTF還是已經(jīng)在刷平臺題庫有一陣子這篇都值得花幾分鐘看完。文章結(jié)尾還有我最近踩過的幾個坑看完至少能幫你少走半天彎路。1. 刷題前的選題思路1.1 為什么今天選了Misc方向同一個平臺的題庫里有Web、逆向、Pwn、Crypto、Misc好幾個大類。我給自己定的節(jié)奏是每天至少覆蓋兩個方向其中一定保留一道Misc。Misc這個方向挺吃虧因為看起來“沒有技術(shù)含量”。Web題考注入和繞過逆向和Pwn考底層功底Crypto考數(shù)學(xué)和算法思維Misc給人的第一印象就像是在“找東西”。但我的體感正好相反Misc恰恰是對綜合能力要求最雜的方向你要會看文件頭要懂編碼要熟悉常見隱寫算法還得有一點腦洞和聯(lián)想能力。圖片、壓縮包、流量、音頻、日志都可能成為載體沒有固定的知識邊界。今天選它會有一個好處題目來源不算偏門題型經(jīng)典不需要接觸復(fù)雜的漏洞利用鏈也可以把思考重心放在信息提取的思路上。把Misc練順手了對做Web也有幫助——很多Web題目里藏的提示文件、備份文件、編碼后的參數(shù)本質(zhì)上就是在考察你從冗余信息中定位關(guān)鍵線索的能力。1.2 刷題環(huán)境準(zhǔn)備我刷題用的就是平時工作的那臺電腦沒有做額外的虛擬機配置。不過有幾個小工具是每次做題前都會提前確認(rèn)的不然等題目讀到一半發(fā)現(xiàn)工具鏈缺了節(jié)奏很容易斷。file命令查看文件真實類型這個最常用。binwalk用于檢測文件里是否嵌入了其他文件。strings直接抓取文件中的可打印字符。xxd或010 Editor看hex內(nèi)容適合手工分析文件頭。StegSolve圖片通道分析必備。zsteg檢測PNG和BMP的LSB隱寫速度很快。Python環(huán)境處理編碼轉(zhuǎn)換、寫簡單腳本時會用到。這些工具我在之前的練習(xí)里都裝好了Windows和Linux兩邊都有對應(yīng)版本。我的習(xí)慣是拿到題先扔Linux跑完一輪基礎(chǔ)命令沒結(jié)果再切到Windows的圖形化工具做像素級分析。兩條路互補比單一環(huán)境穩(wěn)得多。提示如果你用的發(fā)行版沒有預(yù)裝binwalk不要只試apt install binwalk有些舊版本自帶庫不全分離時容易報錯。我一般直接拉取最新release或從源碼編譯雖然多點時間但后面不會因為版本問題翻車。2. 一道帶message關(guān)鍵詞的圖片題完整解題過程2.1 第一步文件識別與基礎(chǔ)信息收集這道題拿到手是個圖片附件文件名里沒帶什么有用的版本號大小看著也很正常。文件名本身可以記一下但別太當(dāng)真CTF出題人為了制造干擾是會用文件名誤導(dǎo)你的真正拿主意還得看文件內(nèi)容。我先把圖片丟進(jìn)Linux環(huán)境用file命令看它的真實類型。file message.png message.png: PNG image data, 800 x 600, 8-bit/color RGBA, non-interlaced底確實是PNG尺寸800x600RGBA色彩空間。這組信息本身就值得多看一眼PNG是CTF題的高頻載具因為它是無損壓縮可以逐像素提取數(shù)據(jù)也方便在通道里藏信息。接下來跑一輪最基礎(chǔ)的信息收集把圖片不太老實的地方暴露出來。exiftool message.pngEXIF信息里沒看到什么異常的注釋字段只有常規(guī)的創(chuàng)建時間。不過這并不能說明它是干凈的很多出題人不會把提示寫在EXIF里尤其是當(dāng)題目關(guān)鍵詞本身就叫message的時候信息大概率是藏在圖像內(nèi)容里的而不是寫在元數(shù)據(jù)表面。再跑一下strings把所有可打印字符拉出來篩選一遍。strings message.png | head -50輸出結(jié)果里除了PNG標(biāo)準(zhǔn)塊IHDR、IDAT、IEND之外沒有出現(xiàn)類似flag或base64長串的內(nèi)容。到這里常規(guī)的信息收集算是做完進(jìn)入第二步。2.2 第二步分離隱藏數(shù)據(jù)的標(biāo)準(zhǔn)姿勢題目名加了message這個詞我心里立刻有一個預(yù)設(shè)方向這個message要么是被直接拼在圖片數(shù)據(jù)里要么是通過某種隱寫算法編碼到像素中。先處理第一種可能——文件拼接。在CTF里經(jīng)常有這種情況出題人把一個文本文件直接接到圖片文件后面收尾的IEND塊后面其實還有大量數(shù)據(jù)。Windows下雙擊圖片看著還是正常的因為圖片查看器到IEND就停止解析了后面的數(shù)據(jù)不會被顯示出來但文件體積會明顯偏大。我用binwalk做了一次快速掃描binwalk message.png這個輸出會列出文件里可能的嵌入數(shù)據(jù)塊。跑完以后發(fā)現(xiàn)DECIMAL列下出現(xiàn)了不止一個條目除了開頭PNG自身的圖像數(shù)據(jù)外在文件偏移量尾部還存在一段可疑數(shù)據(jù)塊。這正是“圖片內(nèi)還有額外文件”的典型信號。順手再用foremost做一次基于文件簽名提取的嘗試foremost message.png -o extracted如果嵌入部分是一個完整獨立的文件格式foremost通常會直接把它撈出來。不過這道題沒有走到這一步因為后面分析發(fā)現(xiàn)信息并不是以文件形式嵌入的foremost撈不出完整結(jié)構(gòu)很正常。binwalk的結(jié)論出來以后需要確認(rèn)一下偏移量位置。把圖片拖進(jìn)010 Editor定位到PNG文件尾部的IEND標(biāo)記然后看它后面的字節(jié)內(nèi)容。這也是一個很關(guān)鍵的習(xí)慣不依賴工具的一句話結(jié)論自己親眼看到多出來的那一段數(shù)據(jù)長什么樣。2.3 第三步從碎片內(nèi)容拼出message010 Editor里翻到IEND后面發(fā)現(xiàn)確實還有一串肉眼可讀的ASCII字符不是亂碼也不是二進(jìn)制碎片而是有明確含義的文本片段。內(nèi)容大致是一段經(jīng)過編碼的字符串從上下文推斷應(yīng)該是用base64處理過的。到這里做一次常規(guī)還原echo base64字符串 | base64 -d解出來以后是一串人話但并不是最終結(jié)果而是繼續(xù)指向下一個線索。它把信息的藏身之處引向了圖像的像素通道也就是經(jīng)典的LSB隱寫思路。所謂LSB隱寫指的是把信息逐位拆開替換掉圖像每個像素最低位的數(shù)值。因為最低一位的變化對人眼來說幾乎不可見所以成品圖和原圖看起來沒什么區(qū)別實際卻可以塞下一整段文本。對RGBA格式的PNG圖每個像素有R、G、B、A四個通道每個通道都能用最低位承載1比特數(shù)據(jù)。既然是LSB隱寫直接用zsteg掃一遍是比較快的驗證方法zsteg message.pngzsteg會嘗試按常見順序和方向把藏在最低位的比特串提取出來。跑了沒兩秒它就在某一組通道組合下輸出了一段可讀內(nèi)容正是題目要的那個message。拿到內(nèi)容之后我用在線網(wǎng)站復(fù)核了一遍解密結(jié)果確認(rèn)不是zsteg的誤報這才落筆提交。復(fù)盤這道題真實思路并不復(fù)雜先用文件識別確定載體類型再用binwalk和編輯器確認(rèn)圖片末尾是否有附加數(shù)據(jù)發(fā)現(xiàn)附加數(shù)據(jù)是base64編碼的提示順著提示轉(zhuǎn)入像素隱寫分析最后用zsteg拿到真正的message。熟練以后整套流程十分鐘內(nèi)可以完成但第一次接觸的人很容易卡在第二步binwalk掃出了內(nèi)容卻沒有耐心去讀附加數(shù)據(jù)的含義急著去做各種花哨的工具操作結(jié)果繞遠(yuǎn)了。3. 順手復(fù)習(xí)的信息隱藏知識點3.1 隱寫題的常見藏法做完這道題我把最近在攻防世界上碰到過的同類題型整理了一下。信息隱藏類題目看著花樣多常見套路其實就那么幾類按頻率排個序隱藏方式典型特征快速檢測手段文件拼接文件尾部有明顯附加字節(jié)binwalk / 010 Editor看IEND后EXIF字段元數(shù)據(jù)里出現(xiàn)超長注釋exiftool 翻字段LSB隱寫圖片通道低位有規(guī)律變化zsteg / StegSolveDCT域隱寫常見于JPEG通道數(shù)據(jù)被改動專用腳本檢測調(diào)色板隱寫色塊數(shù)量異常像素索引替換StegSolve逐個通道看動態(tài)圖分離GIF多幀藏文本或二維碼convert逐幀導(dǎo)出文件拼接是最不需要技巧但最容易漏掉的一種。很多題目只是把一個壓縮包或者文本文件默默地續(xù)在圖片后面制作者甚至不會對附加內(nèi)容做任何處理。判斷的核心就是binwalk掃描加上文件體積對比如果一張看起來平平無奇的圖片體積卻有幾十MB或者IEND塊后面還跟著看得懂的字符基本可以直接進(jìn)下一步。LSB隱寫則要麻煩一點難點在于排列順序。同樣是12個像素紅色通道最低位在前、還是綠色通道最低位在前、或者按RGBA一輪輪排都會得到完全不同的比特流。zsteg的價值就在于此它會把各種常見排列方式全試一遍然后找到能輸出可讀文本的那一組。相比之下手工遍歷通道的話效率就太低StegSolve看通道分布可以輔助判斷但提取數(shù)據(jù)還是腳本工具更靠譜。EXIF隱藏是最適合新手入門的類型因為不需要對圖像做任何數(shù)學(xué)處理只在文件頭元數(shù)據(jù)區(qū)域的注釋字段里寫內(nèi)容就行。很多題目直接把提示或flag放在“作者”“注釋”“軟件”這類字段里用exiftool一把抓出來。但這種題目越來越少了現(xiàn)在多數(shù)出題人會把EXIF當(dāng)誤導(dǎo)里面寫一句“繼續(xù)努力吧”之類的廢話真實線索在別處。3.2 從圖片題延伸到Web題的一個小案例隱寫題的思維方式其實可以遷移到很多Web題里。攻防世界里的Web題有一個特點很多關(guān)卡把關(guān)鍵信息藏在響應(yīng)包的某個角落里而不是直接顯示在頁面上。我拿最近練的一道題舉例。題目頁面上有個輸入框提交參數(shù)后返回了一個很普通的字符串。單看頁面沒有報錯沒有異常響應(yīng)一般新手到這里就停了。但當(dāng)時我把請求丟進(jìn)Burp Suite看完整響應(yīng)頭發(fā)現(xiàn)一處自定義頭字段里帶了一段url編碼的字符串。解出來以后是一份備份文件的路徑順著路徑下載下來又發(fā)現(xiàn)備份文件里殘留了一段注釋注釋里寫著一個過濾邏輯和繞過條件的線索。這就是典型的“信息在意外位置”思路。圖片題的message藏在像素最低位、Web題的線索藏在響應(yīng)headers里本質(zhì)上都在考察你有沒有把有待檢視的范圍擴(kuò)到界面之外。如果你只盯著頁面主流程等于在做Misc時只雙擊圖片看能不能預(yù)覽出隱藏文字那肯定找不到。這也解釋了為什么我練Misc對做Web幫助很大。不是知識點直接復(fù)用而是養(yǎng)成了一套行為習(xí)慣永遠(yuǎn)考慮到載體本身之外還有沒有別的東西對任何異常數(shù)據(jù)都保持敏感。4. 刷題過程中的坑與經(jīng)驗4.1 常見卡點做Misc題最??ㄗ〉奈恢貌皇遣粫霉ぞ叨撬悸讽樞虿粚?。說幾個我這段時間踩過、也在別人解題記錄里反復(fù)看到的坑。第一個坑是直接用StegSolve對圖片做一堆通道分析而不先跑一遍binwalk和strings。這樣做的問題在于你把最省時間的可能性放在后面處理了。如果只是文件拼接或EXIF藏字StegSolve分析再多通道也得不到任何東西浪費十幾分鐘后又繞回原點。穩(wěn)妥的順序是先低成本粗掃再做像素級細(xì)看。第二個坑是忽略文本內(nèi)容的上下文。我有一次掃描一張圖片尾部有一段用base64編碼的字符串解出來是/secret_flag.txt。我當(dāng)時下意識覺得這只是一個文件路徑提示就沒當(dāng)回事結(jié)果題目真正的入口是從這個路徑也可以訪問到的隱藏頁面。很多線索不會直接寫成“flag在這”它只是一個路徑、一個文件名、一段殘缺的對話需要你去聯(lián)想它指向哪里。第三個坑是平臺環(huán)境本身的干擾。攻防世界這類平臺偶爾會出現(xiàn)網(wǎng)絡(luò)抖動代碼提交后長時間無響應(yīng)或者某道題目的容器需要稍等片刻才能啟動別急著懷疑自己思路錯了。另外有些題目下載附件的文件名會被瀏覽器自動加了后綴做題前先核對一下下載下來的文件真實類型。第四個坑和編碼相關(guān)。提取出的字符串有時候不是標(biāo)準(zhǔn)的base64可能帶了個別字符被替換、或者尾部補了多余的回車換行。直接用命令行在線解碼容易因為格式問題報錯先看一眼字符串長度是不是4的倍數(shù)不是的話先檢查提取過程有沒有多讀或者漏讀。我把這些整理成一個簡單的問題速查表方便快速對照現(xiàn)象排查方向常用解法binwalk掃描無異常但文件尾有肉眼可見字符IEND塊后存在附加文本用編輯器直接讀尾部提取編碼串解碼圖片看上去沒有任何異常但體積明顯偏大大概率是文件拼接或嵌入了壓縮包binwalk -e嘗試遞歸分離zsteg提取結(jié)果全是亂碼提取通道或方向不對切換zsteg的通道參數(shù)或換StegSolve雙向查看解碼base64報錯字符串里混了換行或者字符被替換先過濾非base64字符再補全填充提取出的文本很怪像英文但字母錯位可能做過凱撒移位或其他簡單替換先用在線工具試常見移位再考慮其他古典密碼4.2 刷題習(xí)慣建議每天保持做題這件事重要的不是一天做十道二十道而是穩(wěn)定地練。我現(xiàn)在給自己定的目標(biāo)是每天至少兩道一道保持手感的熟練題一道稍微超出當(dāng)前能力的題。超出能力的那道如果是Misc會先自己死磕40分鐘不碰題解40分鐘沒進(jìn)展再去看別人的WriteUp。看WriteUp也有技巧別從頭到尾當(dāng)小說看先看對方的思路轉(zhuǎn)折點在哪。比如今天這道題轉(zhuǎn)折點就在“尾部附加數(shù)據(jù)是一段編碼提示”這個轉(zhuǎn)折之后的操作全是常規(guī)流程??搭}解時把這種轉(zhuǎn)折記進(jìn)自己的知識樹里下次碰到類似情況就有印象要先解碼再往下走了。另外我建議做一道題就在本地建一個文件夾把題目附件、自己跑過的命令、中間輸出和最終flag都留下來。這不是為了給誰看主要方便事后復(fù)盤同一道題隔兩周再做一遍看自己還會不會卡在同樣的地方。如果還卡說明那個知識點沒有真正變成自己的需要針對性地多找兩道同類題補練。注意刷題平臺賬號里的做題記錄只能看到提交時間看不到中途失敗的過程所以本地記錄反而成了最寶貴的資料。我回看我最早幾天的記錄發(fā)現(xiàn)自己當(dāng)時很多時間花在無意義的工具亂試上而現(xiàn)在再看同樣的題能直接判斷該先跑哪個命令。經(jīng)驗就是這樣一點點堆出來的。寫在最后攻防世界的題目做得越多越能感受到一個道理大部分題不是考冷門知識而是考你有沒有把基礎(chǔ)功夫做扎實。文件識別、編碼解碼、信息定位、工具調(diào)用每一步單獨拿出來都不難難的是在有限時間里把這些動作串成一條有效的路徑。今天這道以message為線索的圖片題走的正是一條很典型的路線從文件尾部發(fā)現(xiàn)附加數(shù)據(jù)解碼提示后轉(zhuǎn)入像素隱寫再用工具提取最終信息。我個人在實際做題中的體會是拿到任何一道Misc題不要急著開工具先花三十秒把題目文件從頭到尾的邏輯捋一遍。想象一下如果你是出題人會把message放在哪一層。這種“換位思考”的習(xí)慣幫了我很大忙也讓刷題不再只是機械地跑工具。希望這篇記錄能給你一點參考。下一篇我打算整理攻防世界上那些“看似是Misc其實是Web”的混淆題型這個分類陷阱我自己踩過好幾次到時候把判斷依據(jù)和繞過順序都寫出來。