-5

我偶然发现了一个具有 12 个块的分割 IDAT 结构(最后一个 LSB 略小)(.PNG)的隐写图像。在谈到我的问题的真正要点之前,我将详细说明问题的结构,因为我需要澄清一些事情,所以请不要将其标记为离题,因为它不是。我只需要解释脚本背后的概念,以便我可以解决问题本身。它肯定将数据嵌入到自身中。数据似乎已通过更改增强的 LSB被隐藏除最后一个最低有效位外,消除每个像素的高级位的值。所以所有字节都将是 0 或 1,因为 256 值范围上的 0 或 1 不会给出任何可见的颜色。基本上,0 保持在 0,1 变为最大值,即 255。我一直在以多种不同的方式分析这张图片,但除了三种颜色中的任何一种完全没有一个值之外,没有看到任何奇怪的地方值 (RGB) 和 1/3 颜色值中另一个值的高度存在。然而,研究这些和替换字节并没有给我任何东西,我不知道这条途径是否值得追求。

因此,我正在研究用PythonPHPC/C++开发一个脚本,它可以逆转该过程并“恢复”增强的 LSB。

我已将其转换为24 位 .BMP并从卡方隐写分析中追踪红色曲线,可以确定文件中存在隐写数据。

在此处输入图像描述 在此处输入图像描述

首先,有一点多于 8 个垂直区域。这意味着隐藏的数据略多于 8kB。一个像素可用于隐藏三位(每个 RGB 色调的 LSB 中的一位)。所以我们可以隐藏 (98x225)x3 位。要获得千字节数,我们除以 8 再除以 1024:((98x225)x3)/(8x1024)。嗯,应该是 8.1 KB 左右。但这里不是这样。

文件的.JPG扩展名的APPOAPP1标记的分析也给出了一些尴尬的输出:

Start Offset: 0x00000000
*** Marker: SOI (xFFD8) ***
  OFFSET: 0x00000000

*** Marker: APP0 (xFFE0) ***
  OFFSET: 0x00000002
  length     = 16
  identifier = [JFIF]
  version    = [1.1]
  density    = 96 x 96 DPI (dots per inch)
  thumbnail  = 0 x 0

*** Marker: APP1 (xFFE1) ***
  OFFSET: 0x00000014
  length          = 58
  Identifier      = [Exif]
  Identifier TIFF = x[4D 4D 00 2A 00 00 00 08 ]
  Endian          = Motorola (big)
  TAG Mark x002A  = x[002A]

  EXIF IFD0 @ Absolute x[00000026]
    Dir Length = x[0003]
    [IFD0.x5110                          ] = 
    [IFD0.x5111                          ] = 0
    [IFD0.x5112                          ] = 0
    Offset to Next IFD = [00000000]

*** Marker: DQT (xFFDB) ***
  Define a Quantization Table.
  OFFSET: 0x00000050
  Table length = 67
  ----
  Precision=8 bits
  Destination ID=0 (Luminance)
    DQT, Row #0:   2   1   1   2   3   5   6   7 
    DQT, Row #1:   1   1   2   2   3   7   7   7 
    DQT, Row #2:   2   2   2   3   5   7   8   7 
    DQT, Row #3:   2   2   3   3   6  10  10   7 
    DQT, Row #4:   2   3   4   7   8  13  12   9 
    DQT, Row #5:   3   4   7   8  10  12  14  11 
    DQT, Row #6:   6   8   9  10  12  15  14  12 
    DQT, Row #7:   9  11  11  12  13  12  12  12 
    Approx quality factor = 94.02 (scaling=11.97 variance=1.37)

我几乎确信没有应用加密算法,因此隐藏后没有密钥实现。我的想法是编写一个脚本来改变 LSB 值并返回原始值。我已经在几个结构分析、统计攻击、BPCS、

图像的直方图显示了一种带有异常尖峰的特定颜色。我已经尽我所能尝试查看任何隐藏的数据,但无济于事。这些是 RGB 值的直方图,如下所示:

在此处输入图像描述

然后是多个IDAT块。但是,我通过在每个像素位置定义随机颜色值来组合一个类似的图像,我也总结了其中的几个。到目前为止,我在它们里面也发现了很少的东西。更有趣的是颜色值在图像中重复的方式。似乎,重复使用颜色的频率可以提供一些线索。但是,我还没有完全理解这种关系,如果存在的话。此外,只有单列和单行像素在其 Alpha 通道上不具有 255 的完整值。我什至解释了XYARGB图像中每个像素的值都为 ASCII,但最终没有什么太清晰的内容。即使是 LSB 平均值的绿色曲线也无法告诉我们任何信息。没有明显的中断。以下是其他几个直方图,它们显示了 RGB 中蓝色值的奇怪曲线:

在此处输入图像描述

但是卡方分析的输出红色曲线显示出一些差异。它可以看到我们看不到的东西。统计检测比我们的眼睛更敏感,我想这是我的最后一点。但是,红色曲线中也存在某种延迟。即使没有隐藏数据,它也会以最大值开始并保持一段时间。这接近于误报。它看起来像图像中的 LSB,非常接近随机,并且该算法需要大量人口(请记住,分析是在增加的像素人口上完成的)才能达到可以确定它们实际上不是随机的阈值毕竟,红色曲线开始下降。隐藏数据也会出现同样的延迟。您隐藏了 1 或 2 kb,但在此数据量之后,红色曲线不会立即下降。它稍等片刻,分别在 1.3 kb 和 2.6 kb 左右。以下是十六进制编辑器中数据类型的表示:

byte = 166
signed byte = -90
word = 40,358
signed word = -25,178
double word = 3,444,481,446
signed double word = -850,485,850
quad = 3,226,549,723,063,033,254
signed quad = 3,226,549,723,063,033,254
float = -216652384.
double = 5.51490063721e-093
word motorola = 42,653
double word motorola = 2,795,327,181
quad motorola = 12,005,838,827,773,085,484

这是另一个光谱来确认蓝色 (RGB) 值的行为。

在此处输入图像描述

请注意,我需要通过所有这些来澄清我所追求的情况和编程问题。这本身就使我的问题不是题外话,所以如果它没有被标记为这样,我会很高兴。谢谢你。

4

1 回答 1

0

如果图像应用了 LSB 增强,我想不出办法将其恢复到原始状态,因为不知道 RGB 的原始值。根据它们的最低有效位,它们被设置为 255 或 0。我在这里看到的另一个选项是,如果这是某种包含量子隐写术的协议。

Matlab 和一些隐写分析技术可能是您问题的关键。

这是用于一些统计分析的Java 卡方类:

private long[] pov = new long[256];
and three methods as

public double[] getExpected() {
        double[] result = new double[pov.length / 2];
        for (int i = 0; i < result.length; i++) {
            double avg = (pov[2 * i] + pov[2 * i + 1]) / 2;
            result[i] = avg;
        }
        return result;
}
public void incPov(int i) {
        pov[i]++;
}
public long[] getPov() {
        long[] result = new long[pov.length / 2];
        for (int i = 0; i < result.length; i++) {
            result[i] = pov[2 * i + 1];
        }
        return result;

或尝试使用一些按位移位操作:

int pRGB = image.getRGB(x, y);
int alpha = (pRGB >> 24) & 0xFF;
int blue = (pRGB >> 16) & 0xFF;
int green = (pRGB >> 8) & 0xFF;
int red = pRGB & 0xFF;
于 2013-09-22T17:19:08.350 回答