前言
随着许多恶意软件作者开始把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)
|
发表评论