这几天做CTF比赛相关的题目,每天总结一篇与大家分享,本人对CTF也算是个初学者,通过一些学习感觉收获还是很多的。学会了一些工具软件的使用和相关知识的原理。今天继续分享图片隐写,图像隐写类题目的特点:考法多样,思路清奇,工具众多。先分享“第一板斧”的解题套路。

声明:本博文只是分享知识,如果有人利用此技巧去做违法违规的事情,本人概不负责!

图像隐写“三板斧”中的每一“板斧”均对应着若干工具:

  • 第一板斧:010 Editor、strings
  • 第二板斧:StegSolve、zsteg
  • 第三板斧:binwalk、foremost

第一板斧的目的是发现插入隐藏,主要使用工具010 Editor和Linux系统下的strings命令完成。这两个工具是同样功效,使用不分先后。推荐使用010 Editor,因为利用其自带模板解析后的结果,可以快速发现所有的前置插入隐写和追加插入隐写。前置插入隐写如下图虚线红框所示:

Screenshot 2024-08-08 at 18.37.09.png

下面来看追加插入的例子。

【例题】welc0me.jpg

【题目来源】2017央企大赛

【题目描述】找到文件中隐藏的信息

【解题思路】从文件后缀可以看出这是JPG文件,但是图片不能打开。这里提醒一下:图像能否打开和图像是否存在隐写没有必然联系。建议初学者在解决图像隐写题目时,优先采用“三板斧”方法。按照第一板斧的步骤,现在010 Editor中打开文件,打开后会弹出报错信息,这是因为图像损坏导致模板解析错误,这类报错可能暗示图像中存在追加插入隐写。如下图底部箭头所指所示: Screenshot 2024-08-08 at 18.52.02.png

观察解析结果,如下图所示,在文件末尾有字符串,利用Base64解码后得到flag{gr3at0faLLtime}。

Screenshot 2024-08-08 at 18.58.07.png

通过第一板斧可以发现所有较为明显的插入隐藏。如果在图像中没有发现插入隐藏,就需要使用第二板斧来发现替换隐藏,主要是针对LSB隐写。

在第二板斧中,要用到两个工具:StegSolve和zsteg,使用时先用StegSolve再用steg。StegSolve被称为“隐写神器”,很多图像隐写题目都会用到这个工具。它是一个jar文件,需要提前安装并配置好JRE才能运行。这里提供一下[JDK下载链接][https://www.oracle.com/java/technologies/downloads/]。配置好,双击StegSolve.jar就可以正常打开;如果双击后不能运行,则可以在命令行下通过JRE中的java.exe调用jar文件。如下所示:

java -jar StegSolve.jar

打开StegSolve后不能直接拖入图片,需要通过“File”菜单中的“Open”来选择文件后,才能看到图片,如下图所示:

Screenshot 2024-08-08 at 19.12.40.png

在程序下方还可以看到“<”和“>”两个按钮,多次单击“>”按钮,就能看到如下图所示的情况。在程序左上角可以看到“Red plane 7”,其含义是提取所有像素红色通道像素值的最高位组成的黑白图像(在StegSolve中,默认每个通道为8比特),“Red plane 0”代表红色通道像素值的最低位,每个通道都能构成8个不同的位平面。持续单击“>”按钮,不仅能看到Alpha、Red、Green和Blue共4个通道32个位平面,还能看到经过不同处理的其他图像。因此“<”和“>”按钮是第二板斧中的重要功能。

Screenshot 2024-08-08 at 19.22.07.png

单击上图中的“Analyse”(分析)按钮,出现如下图所示的项目,

Screenshot 2024-08-08 at 19.31.07.png

从上到下依次为:

  • File Format:文件格式及属性信息。
  • Data Extract:数据提取,主要用于提取比特并实现排列组合。
  • Stereogram Solver:立体图水平偏移控制,将图片水平偏移后再与原图叠加。
  • Frame Browser:帧浏览器,主要是对GIF之类的动图进行分解,可以查看每一帧的图像。
  • Image Combiner:拼图,图片拼接。

“Data Extract”是StegSolve中的重要功能,单击该项会打开如下图所示的界面: Screenshot 2024-08-08 at 19.43.57.png

左侧的“Bit Planes”是各通道以及可以选择的比特,“0”代表最低比特,“7”代表最高比特。右侧的“Order Settings”用于设置提取时的顺序,Exract By为按row(行)或column(列)提取像素;“Bit Order”中的MSB First指最高位是第一位,LSB First指最低位是第一位;“Bit Plane Order”用于设置RGB通道的顺序。选择好所有顺序后,单击“Preview”按钮,就能在窗口中预览提取的信息。

注意:当我们用第二板斧打开StegSolve后,应优先使用“<”和“>”两个按钮,目的是发现通过LSB隐写的图像。如果没有任何发现,再考虑使用StegSolve的其他功能。

【例题】dandelion.png

【题目来源】2016华山杯

【题目描述】找到文件中隐藏的信息

【解题思路】利用第一板斧,将文件拖入010 Editor,在文件头和文件尾都没有发现插入隐藏;再采用第二板斧,用StegSolve打开文件,单击“>”按钮,如下图所示:

Screenshot 2024-08-08 at 19.51.23.png

在蓝色通道最低位通过LSB隐写看到一个二维码。这个二位码并不是标准二维码,这时我们采用离线工具QR Research来处理。双击CQR.exe打开工具,单击鼠标按钮选择二维码区域,即可得到二维码扫描结果,再进行Base32解码,就得到flag:flag_Xd{hSh_ctf:U2s0_coo1}。如下图所示: Screenshot 2024-08-08 at 20.00.02.png

【例题】AsianCheetah.png

【题目来源】2016 Sharif CTF

【题目描述】找到文件中隐藏的信息

【解题思路】先用第一板斧,通过010 Editor没有发现插入隐藏;再用第二板斧,在StegSolve中多次单击“>”按钮,也没有任何收获。因此,本题需要用到StegSolve中的Data Extract功能,选择蓝色通道最低位、LSB First、row,因为只有蓝色通道,故RGB顺序随意,设置如下图所示: Screenshot 2024-08-08 at 19.43.57.png

在预览窗口看到flag:SharifCTF{e8e12db2fc654f3b50f3da4901ab986e}。这个题目本质上也是LSB隐写,和上个例题区别是,上个例题隐写了一个二维码,通过“>”按钮可以看到;本题隐写了一个字符串,需要在Data Extract中才能看到。但是,这里有一个小问题,我们如何知道应该从蓝色通道最低位提取信息,而不是从其他位获取信息?如果没有其他工具配合,我们只能手工多次尝试,没有其他更好的方法了吗?但有了zsteg工具,提取数据时就不需要反复进行人工尝试了。

zsteg工具可以检测PNG和BMP图片里的隐写数据,功能非常强大,但需要在Linux系统中通过命令行运行。打开Linux终端,输入“gem install zsteg”命令就可以完成其安装。使用方法如下图所示,在命令“zsteg”后加入文件的相对路径或绝对路径,就得到结果。zsteg还会把重要字符串自动表红色并识别提取出的文件的类型。在下图中flag字符串前有“b1,b,lsb,xy”,其含义如下:b1表示最低位(b8表示最高位,这与StegSolve略有不同),b表示蓝色通道,lsb表示最低位是第一位,xy表示按行提取,与上图中设置完全一样。

Screenshot 2024-08-08 at 20.27.51.png

【例题】easyimg.zip

【题目描述】找到文件中隐藏的信息

【解题思路】对文件进行解压后,我们得到一个easy.bmp文件,用画图软件打开图片报错提示,猜测可能文件受损,需要修复。如下图所示:

Screenshot 2024-08-08 at 20.37.03.png

在010 Editor中打开该文件,如下图所示: Screenshot 2024-08-08 at 20.39.31.png

打开bmp模板,报错提示。也证明了不是bmp文件或者文件受损。bmp文件的文件头是“42 4D”,由此我们推测easy.bmp文件缺少了文件头,“BM”,接下来在文件头插入2个字节,如下图所示: Screenshot 2024-08-08 at 20.44.57.png

修改完之后,可以重新运行一下bmp模板,如上图所示,模板执行成功。说明修改成功,将修改后的文件另存为新文件easy_new.bmp。利用第一板斧,在文件easy_new.bmp中没有任何发现,利用StegSolve也没有发现LSB隐写的图像,因此考虑使用zsteg,结果如下图所示,并没有发现flag。

Screenshot 2024-08-08 at 20.55.51.png

这里介绍一个关于zsteg重要的使用技巧:在命令中添加“-a”选项,可以尝试提取信息所有的排列组合。一些题目要通过添加“-a”选项才能找到flag。如下图所示,得到flag'flag{44544427-2a95-4936-bcc1-47c95268ca4c}。

Screenshot 2024-08-08 at 20.59.04.png

【例题】try1try.png

【题目来源】原创

【题目描述】找到文件中隐藏的信息

【解题思路】在010 Editor中打开图片,没有发现明显的插入隐藏信息,在StegSolve中也没有明显的发现,于是使用zsteg工具,检测结果如下图所示:

Screenshot 2024-08-08 at 21.23.14.png 可以发现在RGB通道的最低位以LSB的方式隐写了一个RAR文件。接下来,通过命令“zsteg -E b1,rgb,lsb,xy try1try.png > ex.rar”把RAR文件提取出来。其中,“- E”表示提取,“b1,rgb,lsb,xy”是上一步操作得到的LSB隐写信息,“>ex.rar”表示利用输出重定向将提取出的信息保存为ex.rar,否则提取出的RAR文件会打印在终端上。

Screenshot 2024-08-08 at 21.25.06.png

从StegSolve打开图片看到的“WEAK P@SS”信息,如下图所示:

Screenshot 2024-08-08 at 21.16.40.png

猜测提取RAR使用弱口令,使用ARCHPR爆破RAR4文件的密码,利用字典或者6位纯数字爆破后发现解压密码是654321,解压后得到aaa.txt,打开文件即可得到flag{ZstegV587!}。

注意:在第二板斧中,StegSolve和zsteg使用有先后顺序,应先使用StegSolve中的">"按钮查看是否存在LSB隐写图像,如果没有任何发现,再利用zsteg检测是否有LSB隐写字符串或文件。zsteg的提取结果可以在StegSolve中利用Data Extract按同样设置进行验证。

【例题】taowa.zip

【题目来源】2018网鼎杯

【题目描述】找到文件中flag

【解题思路】解压后发现每一层文件夹中都一个PNG文件和一个子文件夹,针对每张图片使用三板斧的前两板斧(一种快捷操作是对每张图片依次使用strings和zsteg命令,strings命令对应第一板斧【010 Editor】,zsteg命令对应第二板斧),最终在对6.png使用zsteg提取时可以找到flag{03a253f5-8e93-4533-bcfc-af90883009,如下图所示:

Screenshot 2024-08-08 at 21.45.24.png

【例题】3333.png

【题目描述】找到文件中的flag

【解题思路】根据三板斧解题套路,使用第一板斧和第二板斧都没有发现隐写内容,因此,对文件使用binwalk,检测结果如下图所示:

Screenshot 2024-08-08 at 21.51.09.png

在0x29偏移处检测到一个zlib压缩文件,但是这个检测结果并不准确,其实是一个误报。对于所有PNG图片使用binwalk检测,都能在0x29偏移处发现一个zlib压缩包。这里使用AsianCheetah.png对比说明。

Screenshot 2024-08-08 at 21.56.30.png

之所以所有PNG都能检测出zlib文件,是因为PNG格式中IDAT块的特征和zlib文件特征一致,所以利用binwalk检测PNG文件时经常能看到这个误报。误报并不意味着binwalk不能使用,对于这两个图片都使用binwalk -e命令提取,发现都生成了新文件夹,查看文件夹中的内容,如下图所示:

Screenshot 2024-08-08 at 22.05.13.png

提取命令如果报错,请加上参数“--root-as=root”。根据上图红箭头所指可以发现,3333.png的IDAT块中插入了其他信息,因为不为0字节。对从3333.png中提取出的29文件使用file命令,结果是"data",说明并没有识别出是什么文件。这里一个重要思路:凡是不认识或无法识别的文件均可以使用binwalk检测。检测结果如如下图所示: Screenshot 2024-08-08 at 22.16.55.png

29文件中还有一个zlib文件,继续提取,从下图中可以看到最终提取结果, Screenshot 2024-08-08 at 22.20.08.png “504b0304”是ZIP文件的开头,需要进行HEX解码并保存成压缩文件。如下图所示:

Screenshot 2024-08-08 at 22.35.09.png

压缩包解压需要密码,但并不是伪加密,爆破也没有找到密码,用解压软件打开压缩包或者用binwalk再次打开,可以发现压缩包中的注释: Screenshot 2024-08-08 at 22.30.29.png

上面红框内的字符就是密码,解压后用记事本打开获取flag{PnG_zLiB_dEc0mPrEsS}。