为了理解如何在图像文件中嵌入秘密数据,首先需要理解JPEG文件结构是如何构建的。
让我们举一个图片的例子,扔进十六进制编辑器(如HxD):
我只会解释这个hexdump解释相关的部分。这里只有几个重要的字节来实现我们在这篇博客文章中试图做的事情。
FF xx 字节表示JPEG结构中的标记,标记用于各种事情,如元数据、缩略图的生成、JPEG文件的开始、JPEG文件的结束等等。
FF D8 => 这是表示JPEG数据流开始的标记
FF D9=> 表示JPEG数据流的结束
FF DA=> 这个标记有点复杂,但是在很高的级别上,这个标记表示JPEG中“图片”的实际开始。
因此,这4个字节中的每一个都会出现在任何现有的JPEG文件中,如果您想要解析JPEG图像,并且需要找出它们的开始和结束位置,那么这是非常有用的信息。
标记始终遵循相同的惯例(FF D8标记除外):
FF => 开始的标志
xx => 任何十六进制值(1字节)来“标识”标记。
xx xx => 表示标记大小的2字节数据空间。
重要:这个总大小本身也必须包括这2个字节!(例如:如果您需要32字节的大小,您实际上需要分配34字节!)
DATA => 所有的数据字节
注意:有一些值已经被保留。要查看完整的列表,请访问https://www.disktuna.com/list-jpeg-markers/
FF E2 – FF EF => 不用于解码JPEG图像的应用程序标记通常用于元数据。
FF FE => 这是一个“注释”标记,JPEG解码器也会忽略它。
这些标记正是我们插入数据的方式,并且仍然有一个有效的图像
在开始之前,您必须知道,如果在另一个标记中开始重写数据,就会破坏映像。我一般建议不要重写任何东西,除了你知道自己在做什么,最简单的方法就是插入有效载荷。这样做的缺点是,您的图像大小会因为插入而变得更大。
对于这个场景,AES-256解密密钥是一个非常好的用例,AES-256是一种强大的加密算法,隐藏密钥不会像隐藏整个有效负载那样使图像膨胀。
AES-256密钥需要32个字母的字符(1个字符等于1个字节 => 32字节= 256位。
我选择以下密钥:ThisIsAsuperSecretDecryptionKey! 正好是32位,不相信吗?也许你会相信powershell:
现在求出这个键的十六进制值:
现在我们有了正确长度的键和该键的十六进制值,我们可以构造我们的标记:
FF => 开始的标志
铁=> 表示我们在做一个“评论”。
00 22 => 表示标记大小的2字节数据空间(34十六进制为00 22)
54686973497341537570657253656372657444656372797074696 f6e4b657921 => (十六进制值ThisIsAsuperSecretDecryptionKey!)
我们可以在任何其他标记开始(用FF标记)之前插入(同样不要覆盖)该标记,然后在FF DA标记(图像的实际开始)之前。
对比这2张图:
我觉得它们看起来很像,但是现在呢?
另一种安全的方法是将有效载荷附加在图像标记符(FF D9)的末尾,这是大多数“隐写术”程序的工作方式。你甚至可以通过添加垃圾数据来伪装你的有效载荷,这样你的有效载荷就不仅仅是在hexdump的最后。现在剩下要做的是编写一个程序,图像中寻找你的解密钥匙hexdump。
检测这是非常困难的,你需要检查所有图片下载在你的组织中,我的建议是如果你开始看到指标的妥协,你会看到一个下载一个图像,hexdump的形象,开始观察标记(FF字节)特别是在FF DA和FF D9之后标记。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。