杂项-图片

图片格式 #

常见的图片格式文件头如下:

类型HexISO 8859-1
GIF47 49 46 38 39 61GIF89a
JPG/JPEGFF D8 FF
PNG89 50 4E 47‰PNG
BMP42 4DBM

修复 #

一个简单的检测是否需要修复(如CRC或宽高)的方法:在Windows下能打开的图片在Linux/MacOS下不能打开,就说明可能需要修复操作

文件头修复 #

提供的图片可能缺失头信息,参看以上文件头信息进行修复

CRC校验修复 #

当CRC被修改后,可以使用TweakPNG工具检测出PNG正确的CRC值

使用010Editor也可以检测出PNG正确的CRC值

宽高修复 #

图片可能被修改过宽高,导致flag信息被截断,PNG/JPG/BMP等格式宽高对应修改的字段如下:

PNG:

JPG:

BMP:

其中PNG可以通过未修改过的CRC爆破出正确的宽和高,爆破脚本如下:

##用于根据CRC爆破宽和高,修改相应值使图片正常显示,
##宽高错误时,linux下打不开图片,win可以
import sys
import zlib
import struct


def modify_png_dimensions(filename, new_width, new_height):
    with open(filename, 'rb') as f:
        all_b = f.read()

    new_data = bytearray(all_b)
    new_data[16:20] = struct.pack('>i', new_width)
    new_data[20:24] = struct.pack('>i', new_height)


    new_filename = f"modified_{filename}"
    with open(new_filename, 'wb') as f:
        f.write(new_data)

    return new_filename


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python test.py <filename>")
        sys.exit(1)

    filename = sys.argv[1]
    with open(filename, 'rb') as f:
        all_b = f.read()
        crc32key = int(all_b[29:33].hex(),16)
        data = bytearray(all_b[12:29])
        n = 4095               #理论上0xffffffff,但考虑到屏幕实际/cpu,0x0fff就差不多了
        for w in range(n):     #高和宽一起爆破
            width = bytearray(struct.pack('>i', w))      #q为8字节,i为4字节,h为2字节
            for h in range(n):
                height = bytearray(struct.pack('>i', h))
                for x in range(4):
                    data[x+4] = width[x]
                    data[x+8] = height[x]
                crc32result = zlib.crc32(data)
                if crc32result == crc32key:
                    print("宽为:",end="")
                    print(width)
                    print("高为:",end="")
                    print(height)

                    w = int.from_bytes(width, byteorder='big')
                    h = int.from_bytes(height, byteorder='big')

                    print("Width:", w)
                    print("Height:", h)

                    modified_filename = modify_png_dimensions(filename, w, h)
                    print(f"Modified image saved as {modified_filename}")
python3 crc_width_height.py ~/Desktop/test.png
宽为:bytearray(b'\x00\x00\x05H')
高为:bytearray(b'\x00\x00\x03\xbc')
Width: 1352
Height: 956

隐写 #

GIF隐写 #

GIF图片是动图,它是由一帧一帧的图片拼接而成

Stegsolve可以一帧一帧查看,往往答案就隐藏在其中一帧

LSB隐写 #

LSB(Least-significant bit),即为最低有效位,我们知道,图片中的图像像素一般是由RGB三原色(红绿蓝)组成,每一种颜色占用8位,取值范围为0x00~0xff,即有256种取值

LSB隐写就是修改RGB颜色分量的最低二进制位也就是最低有效位(LSB),而人类的眼睛不会注意到这前后的变化,每个像数可以携带3bit的信息

如下,也可以不仅仅包含最低1位,也可以最低2位等,人类的眼睛也不太会注意到这前后的变化

LSB隐写也是使用Stegsolve

可以看出plane 0包含了很多其他噪声,推测为LSB隐写

Stegsolve-Analyse-Data Extract 可以发现隐藏了HTML entity实体编码信息,常见的可能还会隐藏压缩包等

当然也有题目,直接将信息隐藏在各plane

EXIF #

EXIF(Exchangeable image file format)是专门为数码相机或手机拍摄的照片定义的,用于记录拍摄照片的的元信息,包括拍摄时的日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及GPS全球定位系统数据、缩略图等

简单来说,EXIF 信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部,也就是说 Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,它就好像是傻瓜相机的日期打印功能一样,只不过 EXIF 信息所记录的资讯更为详尽和完备

可以使用exiftool工具进行提取

BMP #

BMP是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,随着windows的流行,bmp位图格式被广泛应用

按照像素深度分类可以分为:1bit位图(2色)、4bit位图(16色)、8bit位图(256色)、16bit位图(65536色-高彩色)、24bit位图(1670万色-真彩色)、32bit位图(1670万色-增强型真彩色)

题型包含24bitCount修复为32bitCount,修复后才能进一步还原图片挖掘信息

32bit位图除了RGB分量,还有1个 Reserved字段可能存在隐写,可参看:https://blog.csdn.net/mochu7777777/article/details/120773359

画图/拼图 #

montage + gaps 自动拼图,比较适合对多个正方形小图进行拼接

https://blog.csdn.net/fjh1997/article/details/107585782 https://blog.csdn.net/qq_68643282/article/details/132393550

相同图片 #

盲水印 xor

steghide #

工具官网 https://steghide.sourceforge.net/

工具有以下特点:The color-respectivly sample-frequencies are not changed thus making the embedding resistant against first-order statistical tests.

使用以下命令提取,需要password

steghide extract -sf xxx.jpg -p password