图片格式 #
常见的图片格式文件头如下:
类型 | Hex | ISO 8859-1 |
---|---|---|
GIF | 47 49 46 38 39 61 | GIF89a |
JPG/JPEG | FF D8 FF | |
PNG | 89 50 4E 47 | ‰PNG |
BMP | 42 4D | BM |
修复 #
一个简单的检测是否需要修复(如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