图片隐写术
图片隐写的常见隐写方法
- 细微的颜色差别
- GIF图多帧隐藏
- 颜色通道隐藏
- 不同帧图信息隐藏
- 不同帧对比隐写
- Exif信息隐藏
- 图片修复
- 图片头修
- 图片尾修复
- CRC校验修复
- 长、宽、高度修复
- 最低有效位LSB隐写
- 图片加密
- Stegdetect
- outguess
- Jphide
- F5
1.Firework
- 使用winhex打开文件时会看到文件头部中包含firework的标识,通过firework可以找到隐藏图片。
- 使用场景:查看隐写的图片文件
2.Exif
- Exijf按照PEG的规格在PEG中插入一些图像/数字相机的信息数据以及缩略图像可以通过与PEG兼容的互联网浏览器/图片浏览器/图像处理等一些软件来查看Exift格式的图像文件就跟浏览通常的PEG图像文件一样,图片右键属性,查看exif或 查看详细信息,在相关选项卡中查找flag信息。
3.Stegsolve
- 当两张jpg图片外观、大小、像素都基本相同时,可以考虑进行结合分析,即将两个文件的像素RGB值进行XOR、ADD、SUB等操作,看能否得到有用的信息,StegSolve可以方便的进行这些操作。
- 使用场景:两张图片信息基本相同
4.LSB(最低有效位Least Significant Bit)
- LSB替换隐写基本思想是用嵌入的秘密信息取代载体图像的最低比特位,原来的的7个高位平面与替代秘密信息的最低位平面组合成含隐藏信息的新图形。 1.像素三原色(RGB) 2.通过修改像素中最低位的1bit来达到隐藏的效果 3.工具: stegsolve、 zsteg、 wbstego4、 python脚本
zsteg工具
detect stegano-hidden data in PNG & BMР
Installation
root@kali:/# gem install zsteg
检测LSB隐写
zsteg xxx.png
wbstego4工具
- 解密通过lsb加密的图片
- python脚本来处理 将以下脚本放在kali中运行,将目标文件放在脚本同目录下,将脚本中的文件名修改为文件名,运行python即可
题目复现
题目:[LSB]
题目来源:polarctf-misc-[LSB]
解题:
题目给了一张图片,根据题目"LSB",将图片设置为lsb最低有效位
得到flag
5.TweakPNG
- TweakPNG是一款简单易用的PNG图像浏览工具,它允许查看和修改一些PNG图像文件的元信息存储。
- 使用场景:文件头正常却无法打开文件,利用TweakPNG修改CRC
- 例: 1.当PNG文件头正常但无法打开文件,可能是CRC校验出错,可以尝试通过TweakPNG打开PNG,会弹出校验错误的提示,这里显示CRC是fe1a5ab6,正确的是b0a7a9f1。打开winhex搜索fe1a5ab6将其改为b0a7a9f1。
文件头正常却无法打开文件,利用TweakPNG 修改CRC....
- 有时CRC没有错误,但是图片的高度或者宽度发生了错误,需要通过CRC计算出正确的高度或者宽度。
- 可以用下面的py脚本,需要改文件位置和TweakPNG得到的CRC实际值,用计算出高度,利用01Editor修改宽高
6.Bftools
bftools用于解密图片信息。
使用场景:
在windows的cmd下,对加密过的图片文件进行解密
格式:Bftools .exe decode braincopter 要解密的图片名称 -output 输出文件名 Bftools.exe run 上一步输出的文件
7.SilentEye
silenteye是一款可以将文字或者文件隐藏到图片的解密工具。
使用场景: windows 下打开silentEye工具,对加密的图片进行解密
例:
1.使用silentEye程序打开目标图片,点击image一>decode,点击decode,可以查看隐藏文件,点击保存即可
2.如果需要密码,勾选encrypteddata,输入密码和确认密码,点击decode再解密
8.JPG图像加密
(1)Stegdetect工具探测加密方式
Stegdetect程序主要用于分析PEG文件。因此用stegdetect 可以检测到通过Steg、JPHide. OutGuess、 Invisible Secrets、F5、appendX和Camouflage等这些隐写工具隐藏的信息。
格式:
stegdetect xxx.jpg stegdetect -s 敏感度 xx.jpg exi
(2)Jphide
- Jphide是基于最低有效位LSB的JPEG格式图像隐写算法
- 例: Stegdetect提示jphide加密时,可以用Jphs.工具进行解密,打开jphswin.exe, 使用open jpeg打开图片,点击seek,输入密码和确认密码,在弹出文件框中选择要保存的解密文件位置即可,结果保存成txt文件。
(3)Outguess
outguess 一般用于解密文件信息。
使用场景:
Stegdetect识别出来或者题目提示是outguess加密的图片该工具需编译使用:./configure && make && make install 格式: outguess -r 要解密的文件名输出结果文件名
(4)F5
F5一般用于解密文件信息。
使用场景:
Stegdetect识别出来是F5加密的图片或题目提示是F5加密的图片 进入F5-steganography_F5目录,将图片文件拷贝至该目录下,从CMD进入该目录
格式: Java Exrtact 要解密的文件名 -p 密码
9.二维码处理
- 1.使用二维码扫描工具CQR.exe打开图片, 找到内容字段
- 2.如果二维码某个定位角被覆盖了,该工具有时候也可以自动识别,如果识别失败,需要使用PS或画图工具将另外几个角的定位符移动到相应的位置,补全二维码 。
- 3.如果某个二维码的定位点中间是白色,可能被反色了,使用画图工具把颜色反色回来再扫描即可。
10.图片与像素转换
题目复现
题目:[0和255]
- 题目来源:Polarctf-misc-[0和255]
- 解题:
靶场给了一个python文件image_list.py
和一个像素列表文件image_list.txt
分析image_list.py
源码
# -*- coding = utf-8 -*-
# @software:PyCharm
from PIL import Image
image = Image.open('flag.png') #flag.png分辨率为33*33
width = image.width
height = image.height
image_list = []
for x in range(height):
scanline_list = []
for y in range(width):
pixel = image.getpixel((y, x)) # 自左到右、自上而下一个一个的像素点读取
scanline_list.append(pixel) # 存储第x行像素点
image_list.append(scanline_list) # 一行一行的存储像素点
print(image_list)
写脚本复原图片即可
import ast
from PIL import Image
def image_list_to_image(image_list, width, height):
# 创建新的空白图像
image = Image.new('RGB', (width, height)) # 创建一个指定大小的RGB模式空白图像
# 遍历image_list,并将像素设置到图像中
for y in range(height):
for x in range(width):
pixel = image_list[y][x] # 获取当前像素值
image.putpixel((x, y), pixel) # 设置像素值到图像中
return image
width = 33
height = 33
with open('素材/image_list.txt', 'r') as file:
content = file.read()
image_list = ast.literal_eval(content) # 把文件内容转成对应的列表
image = image_list_to_image(image_list, width, height)
image.show() # 展示图片
image.save('flag.png')
恢复得到一个二维码,扫码得到字符串,然后计算其md5值即为flag
题目:[01]
- 题目来源:Polarctf-misc-[01]
- 解题:
靶场给了一个加密的zip文件flag.zip
和01二进制数据流hint.txt
查看hint.txt
,猜测为图片像素
脚本恢复
from PIL import Image
MAX = 25 # 每行每列数
# 二维码大小
pic = Image.new("RGB", (MAX, MAX))
str = "1111111011111001001111111100000100000000110100000110111010001000101010111011011101010011110001011101101110100111001010101110110000010001110010010000011111111010101010101111111000000000011000100000000000101110110111010100010011110100111100111010101001011000110001000011011101100001001000010101111000100001001111110100110001001000100011000010111010101010011110000101111010110110101010001010010100000010100100101110011111111100100000000110111001000100011111111001100010101011011100000101111100110001100010111010110010101111110001011101000001110010111010101110101100100011111010110000010011010010011100101111111000010001000011011"
i = 0
for y in range(0, MAX):
for x in range(0, MAX):
if (str[i] == "0"):
pic.putpixel([x, y], (255, 255, 255)) # 将0转换为RGB(255,255,255),即白色
else:
pic.putpixel([x, y], (0, 0, 0)) # 将1转换为RGB(0,0,0),即黑色
i = i + 1
# pic.show()
pic.save("flag.png")
# 本题上边颜色替换无强制要求,尽可能选择差异较大的两种颜色即可
运行后得到二维码,扫码得到压缩包密码,打开压缩包得到数据为兽言兽语编码,在线解码得到flag
[url](兽音译者在线编码解码 - 兽音翻译咆哮体加密解密)