最近遇到一个CTF题目,上面就一张图片是什么?啥都看不出来。今天来看一下CTF图片隐写题目,在图片里面隐藏一些不为人知的Flag呢?
本次实验的地址为:《CTF Stegano练习之隐写6》。
首先来看题目。在实验主机上的C:\Stegano\6目录下提供了pic1.jpg以及pic2.jpg两个文件,请对这两个文件进行分析,找到一个由两个英文单词组成的字符串Flag。
这两张图看起来都感觉都差不多全是黑白像素点,怎么去找Flag呢?
这里有一个神器StegSolve,使用StegSolve提取Flag打开桌面上的StegSolve,然后选择菜单项“File”、“Open”打开pic1.jpg,然后选择菜单项“Analyse”、“Image Combiner”选择pic2.jpg文件,默认的XOR操作就可以看到Flag了,如图所示:
经过简单的分析,我们发现两个图片的尺寸都是300*300,而且文件大小都是71.6KB,所以就不可能存在某一个文件中隐藏了额外的数据的情况了。
那么我们可以对两个文件进行结合分析,即将两个文件的像素RGB值进行XOR、ADD、SUB等操作,看看是否能看到有用的信息。而StegSolve可以十分方便的实现这些操作。
但是使用工具也有一点不好,就是工作的扩展性几乎为零,不能进行批量的自动化处理,而对于自己编写的脚本,自然可以十分方便的进行扩展,可以根据实际需求进行各种定制,并进行批量的自动化处理等。
对于这类题目强烈推荐使用Python的PIL库,脚本“C:\Stegano\6\xorImg.py”的源代码如下:
#!/usr/bin/env python # -- coding:utf-8 -- from PIL import Image def loadImage(filename): img = Image.open(filename) width, height = img.size img = img.convert("RGB") pixel = img.load() return width, height, pixel def combineImage(file1, file2, file3): w1, h1, p1 = loadImage(file1) w2, h2, p2 = loadImage(file2) width = min(w1, w2) height = min(h1, h2) img = Image.new("RGB", (width, height)) pix = img.load() for y in xrange(0, height): for x in xrange(0, width): r1, g1, b1 = p1[x, y] r2, g2, b2 = p2[x, y] pix[x, y] = r1^r2, g1^g2, b1^b2 img.save(file3) if name== "main": combineImage("pic1.jpg", "pic2.jpg", "pic3.jpg")
双击运行这个python脚本,就可以得到处理结果pic3.jpg,打开该图片就可以看到Flag字符串了,为AZADI TOWER。
脚本的代码比较简单,大致就是使用loadImage函数得到图片的长度、宽度、像素矩阵,然后在函数combineImage中对两个矩阵的像素点进行异或运算,并保存到第三张图片中。注意当两张图片的尺寸不一样的时候,我们进行了额外的处理,即只取最小的长度和宽度。
但是你这里只有XOR脚本,没有其他的。
下面继续来写一个通用的脚本,我们可以对该脚本进行修改,增加其可扩展的灵活性,通过定义一个运算函数实现通用的处理功能,比如我们可以定义xor、or、and三个操作的函数,就可以得到三个不同的处理结果了。脚本“C:\Stegano\6\combineImg.py”的源代码如下:
#!/usr/bin/env python # -- coding:utf-8 -- from PIL import Image def xorFun(x, y): return x^y def orFun(x, y): return x|y def andFun(x, y): return x&y def loadImage(filename): img = Image.open(filename) width, height = img.size img = img.convert("RGB") pixel = img.load() return width, height, pixel def combineImage(file1, file2, file3, func): w1, h1, p1 = loadImage(file1) w2, h2, p2 = loadImage(file2) width = min(w1, w2) height = min(h1, h2) img = Image.new("RGB", (width, height)) pix = img.load() for y in xrange(0, height): for x in xrange(0, width): r1, g1, b1 = p1[x, y] r2, g2, b2 = p2[x, y] pix[x, y] = func(r1,r2), func(g1,g2), func(b1,b2) img.save(file3) if name== "main": combineImage("pic1.jpg", "pic2.jpg", "xor.jpg", xorFun) combineImage("pic1.jpg", "pic2.jpg", "or.jpg", orFun) combineImage("pic1.jpg", "pic2.jpg", "and.jpg", andFun)
这个题目不仅仅要会代码,重要的是从题目中找出隐写信息。因为题目有一定难度,才导致CTF比赛这么有竞争力。