前言
随着许多恶意软件作者开始把PE文件嵌入到图像中,这已经引起了安全研究人员的注意,几个月前卡巴斯基就发表了一篇使用PNG分发恶意软件的有效载荷的研究文章。让人遗憾的是,虽然这些图像的分辨率仅有63x48像素,但大小却达到了1.3 MB。
实际上,这种做法并不是很隐蔽,不过别着急,因为我们找到了更好的办法。
将文件编码到PNG图片中
首先,我们不妨先来了解一下PNG文件本身。与JPEG不同,PNG是无损的,即使在压缩的情况下也是如此,这就意味着以这种格式创建一个图像时,除非改变了其分辨率或颜色调色板,否则的话它会保留已生成的所有数据。与GIF不同,PNG文件是通过Alpha通道来处理透明效果的,而不是颜色替换。
我们能够PNG文件的压缩和alpha通道特性,将数据嵌入到PNG图像文件中去。对于PNG图像的每个像素来说,都是由三个8位值来表示颜色,同时,通过另一个8位值(称为“alpha通道”)来表示透明程度。这意味着每个像素可以表示为R,G,B和A,其中A的取值范围为0-255。
这里是一个示例图像(源自维基百科):
该图片的像素是800x600,具有8位色彩和alpha通道,这意味着该图片中可以保存480,000像素或468 KB的数据。下面,让我们使用Pillow库和Python在这个图片中嵌入数据。
下面是用来嵌入数据的Python脚本:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |  from PIL import Image     from sys import argv     from base64 import b64encode     i = argv[1]     o = argv[2]     with open(argv[3], 'rb') as f:         text = f.read()     img_in = Image.open(i)     img_pad = img_in.size[0] * img_in.size[1]     text = b64encode(text)     if len(text) < img_pad:         text = text + '\x00'*(img_pad - len(text))     else:         print('File is too large to embed into the image.')         quit()     text = [text[i:i+img_in.size[1]] for i in range(0, len(text), img_in.size[1])]     img_size = img_in.size     img_mode = img_in.mode     img_o = Image.new(img_mode, img_size)     for ih, tblock in zip(xrange(img_in.size[0]), text):         for iv, an in zip(xrange(img_in.size[1]), [ord(x) for x in tblock]):             x, y, z, a = img_in.getpixel((ih, iv))             pixels = (x, y, z, an)             img_o.putpixel((ih, iv), pixels)     img_o.save(o) | 



发表评论