一、图片隐写[Stegsolve、binwalk、010editor、WaterMark、BlindWaterMark、文件头尾、tweakpng、APNG Disassembler]

一、通用

1.Stegsolve与zsteg

解释:Stegsolve与zsteg 都可以提取基本的LSB,LSB隐写即最低有效位隐写,LSB隐写就是修改RGB颜色分量的最低二进制位也就是最低有效位,写入数据,这样做的目的是人眼最难分辨出来,但是通过工具可以很容易的检测出来

知识补充:

  1. PNG图片,png图片是一种无损压缩的图片,因为无损压缩所以可以实现LSB隐写。
  2. JPG图片,jpg图片是一种有损压缩的图片,修改的数据会在压缩中损失,不可以实现LSB隐写。
  3. BMP的图片,是没有经过压缩的。BMP图片文件大小一般较大,bmp图片也可以实现LSB隐写。

Stegsolve查看red blue green三通道最低二进制位的方法:

  1. 查看
    在这里插入图片描述
    注意:一般复杂是上图所示,有的简单的图需要认真查看通道看哪里有字出现了,来这里选择通道,比如下图(左上角有小字),还要根据出现字在行还是列选择Row还是Column,同时Bit Plane Order也要多切换
    在这里插入图片描述

  2. 导出
    在这里插入图片描述

普通情况:

  1. 选择图片在这里插入图片描述
  2. 切换不同的颜色通道在这里插入图片描述

Zsteg此工具比Stegsolve更推荐,其更强大更全面,不光解决LSB隐写,其它数据的隐藏也很好用(配合binwalk),适用于png与bmp文件

安装:gem install zsteg
使用:zsteg 1.png
尝试所有方法:zsteg -a 1.png
提取出发现隐写的文件:zsteg -e extradata:0 misc17.png > 1.txtzsteg -e 2b,b,lsb,xy misc17.png > 1.txt(看软件给的词)

2.GIF动图

解释:通过该工具能够一帧一帧的对Gif里面的内容进行查看

  1. 选择此功能对Gif图片进行一帧一帧查看
    在这里插入图片描述

  2. 在线网站:https://tu.sioe.cn/gj/fenjie/(对动图,特别是多张图片需要拼接在一起的很有效)

  3. 时间轴(每一帧间的时间间隔):
    apt install imagemagick
    identify -format "%T " n.gif

  4. APNG转GIF
    解释:APNG是一种跟GIF类似的图片也是有多帧的存在,其内容特征存在fdAT fcTL 通过tweakpng查看,在遇到APNG时有时也需要时间轴处理,此时需要使用到APNG Disassembler(使用脚本将apng格式转gif格式再用identify命令会出现问题)

    使用:APNG Disassembler是客户端软件,选择文件后就能对其进行操作,之后它会生成APNG对应帧的每一个图片,并有一个txt文件包含其时间轴,此时我们可以用python进行提取

    base_url = r'apngframe'
    l = []
    for i in range(1, 69):
        if i < 10:
            path = base_url + '0' + str(i) + '.txt'
        else:
            path = base_url + str(i) + '.txt'
        with open(path, 'r') as f:
            t = f.readline()[6:]
            x = t.split('/')[0]
            print(x, end=' ')
            l.append(x)
    print()
    # 转ascii
    for i in l:
        print(chr(int(i)), end='')
    
    
    
  5. 每张GIF图片的偏移identify -format "%X %Y\n" misc46.gif>1.txt

    用python脚本根据X Y坐标绘图

    from PIL import Image
    
    import matplotlib.pyplot as plt
    a = open('1.txt','r').read()
    a = a.split('\n')
    a.pop(-1)
    a = [i.replace('+','') for i in a]
    a = [(int((i.split()[0])),int((i.split()[1]))) for i in a]
    print(a)
    # 对于pp中的每个像素位置i,会创建一个新的大小为1x1像素的黑色图片,并将其粘贴到原始图片img的对应位置上
    img = Image.new('RGB',(400,70),(255,255,255))
    for i in a:
        new = Image.new('RGB',(1,1),(0,0,0))
        img.paste(new,i)
    plt.imshow(img)
    plt.show()
    
  6. APNG每张XY偏移

    import struct
    from PIL import Image
    from matplotlib import pyplot as plt
    
    
    def hex_to_b(hex_str):
        # 将十六进制字符串转换为字节字符串
        hex_str = hex_str.encode().hex()
        byte_str = bytes.fromhex(hex_str)
        return byte_str
    
    
    def find_char_positions(data, pattern):
        positions = []
        for i in range(len(data) - len(pattern) + 1):
            if data[i:i + len(pattern)] == pattern:
                positions.append(i)
        return positions
    
    
    baseurl = r'7.png'
    
    a = open(baseurl, 'rb').read()
    list_index = find_char_positions(a, hex_to_b('fcTL'))
    print(list_index)
    list = []
    for i in list_index:
        t = []
        d = a[i+16:i+16+4]
        result = struct.unpack('>I', d)[0]
        t.append(result)
        d = a[i+16+4:i+16+8]
        result = struct.unpack('>I', d)[0]
        t.append(result)
        list.append(t)
    print(list)
    # 对于pp中的每个像素位置i,会创建一个新的大小为1x1像素的黑色图片,并将其粘贴到原始图片img的对应位置上
    img = Image.new('RGB',(400,70),(255,255,255))
    for i in list:
        new = Image.new('RGB',(1,1),(0,0,0))
        img.paste(new,i)
    plt.imshow(img)
    plt.show()
    

3.图片隐写

3.1 基础隐写

解释:指的是一个文件里面包含其它格式文件与图片,此时可以通过binwalk将它们分开,不能完全相信binwalk,这个工具有时候分辨不出来里面混杂的音频文件,建议使用010editor查看,或配合foremost,或者用010editor进行查看

3.1.1 binwalk

解释:下面这三款工具要轮流使用直到完成任务,目前看来,binwalk一般能分析对隐写的文件,但是拆分不出来,反而foremost能够拆分出来

binwalk xxxx -e自动分离图片里面的内容

3.1.2 foremost

foremost xxx

3.1.3 dd

解释:dd需要结合binwalk显示的块数,例如下图
在这里插入图片描述

dd if=hong.mp3 of=hong1.jpeg skip=138170 bs=1


if=:输入文件,即源图片。
of=:输出文件,即提取出来的数据。
skip=N:跳过输入文件的前N个字节。
bs=1:设置块大小为1字节,配合skip可以准确定位到具体的字节。
N是你想要跳过的字节数,根据隐藏信息可能出现的位置来决定。
count=3142 选择要获取的块数
3.1.4 strings

解释:对于隐写而言,strings命令往往能看到图片里面写着的字符串,对于CTF而言,很可能就是出题人给的暗示

strings 1.png

3.1.5 exiftool

解释:能查看图片的相关信息,比如尺寸大小,时间等等,当有图片隐写时其有时也能够进行分离(例如jpg图片)

下载:apt-get install exiftool
使用:exiftool 1.jpg

3.2 工具隐写

3.2.1 四个盲水印
  1. 盲水印(单图)
    解释:我们遇到一些题可能暗藏着盲水印,需要我们来解决,
    使用文章开头提到的WaterMark软件

  2. 盲水印(多图)
    地址:https://github.com/chishaxie/BlindWaterMark
    解释:适合于多张图片最后合成一个图片的使用BlindWaterMark脚本

    安装依赖:

    pip install opencv-python
    pip install matplotlib
    

    合成

    python bwm.py encode hui.png wm.png hui_with_wm.png
    python bwm.py encode A图 B图 生成的图片路径
    
    python2版本使用bwm.py文件
    python3版本把bwm.py改为bwmforpy3.py
    

    提取

    python bwm.py decode hui.png hui_with_wm.png wm_from_hui.png
    python bwm.py decode A图 B图 生成的图片路径
    
    python2版本使用bwm.py文件
    python3版本把bwm.py改为bwmforpy3.py
    
  3. 盲水印(多图)
    地址: https://github.com/linyacool/blind-watermark
    命令: python decode.py --original ori.png --image res.png --result extract.png

  4. java盲水印
    地址:https://github.com/ww23/BlindWatermark
    命令:java -jar BlindWatermark.jar decode -c img-ec.jpg img-dc.jpg

3.2.2 隐写信息提取
  1. blind_watermark
    解释:可能提取出来文本,文件,压缩包,图片等等
    地址:https://github.com/guofei9987/blind_watermark

    import threading
    from blind_watermark import WaterMark
    # 提取文字
    
    wm_shape = int(input('请输入该题的wm_shape,在此为数字(不知道的话只能爆破解很慢):'))
    bwm1 = WaterMark(password_img=1, password_wm=1)
    try:
        wm_extract = bwm1.extract(r'./img/embedded.png', wm_shape=wm_shape, mode='str')
        print(wm_extract)
    except:
        print('尝试求解失败')
        pass
    
    from blind_watermark import WaterMark
    # 提取图片
    bwm1 = WaterMark(password_wm=1, password_img=1)
    # notice that wm_shape is necessary
    print('请注意需要知道wm_shape的值,否则出来的图片没有任何用')
    bwm1.extract(filename='33.png', wm_shape=(350, 350), out_wm_name='extracted.png')
    
  2. HideInfo
    地址:https://github.com/guofei9987/HideInfo
    支持格式:图片、音频、文本
    原理:其基于特定算法,能够将图片直接转为RGB存储,也能LSB隐写(非传统),也能往音频和文本里面嵌入内容,且内容无法加密

3.2.3 隐写信息加密提取
  1. cloacked-pixel
    原理:基于LSB的,且必须要加密的一种技术(加密的有效载荷将具有高熵并且将类似于随机数据。这就是为什么LSB位置中0和1的频率应该相同-0.5的原因)
    支持格式:图片类型
    解出内容格式:一般为文件
    地址:https://github.com/livz/cloacked-pixel
    命令:(python2) lsb.py extract <stego_file> <out_file> <password>
  2. stegpy
    原理:基于LSB的一种将编码信息隐写在图像和音频文件中的程序。
    解出内容格式:一般为字符
    支持格式:WAV、WebP、GIF、BMP、PNG
    安装:pip install stegpy
    命令:stegpy 0.png -p # -p不要带密码,因为后面会提示你输入密码,如果没有加密可以不输入-p
  3. OurSecret.exe 使用该软件
    在这里插入图片描述
3.2.4 LSB隐写
  1. 基本的LSB隐写:https://github.com/librauee/Steganalysis
    原理:基于最低有效位,循环把原图的RGB三色道的二进制最后一位进行替换要隐藏的内容二进制第n项,该隐写可以直接通过Stegsolve去通过查看RGB 0通道数据提取出来

  2. 变种LSB隐写:https://github.com/guofei9987/HideInfo
    原理:基于最低有有效位,但其使用位运算来隐写内容,Stegsolve去通过查看RGB 0通道数据不能提取出来
    隐写:hide_in_img.file_encode(filename='output_block.jpg', img_filename='279cebca7eb64cb5d7662c98061fdaeea1d4a8e5.png', img_filename_new='藏物于图.png')
    提取: text_encode = hide_in_img.file_decode('藏物于图-解出的文件.jpg', img_filename='藏物于图.png')

4.图片高宽隐藏

4.1 高度篡改

解释:因为图片给的高度或宽度很小,当更改图片高时,隐藏的内容就能看到了

辨别PNG图片高度是否变化:通过StegsolveFile Format对比最开头的CRC,如果CRC与计算出来的有出入可能就是高度修改了或者使用pngcheck工具查看CRCapt install pngcheck

改变GIF高度注意:GIF每一帧都有一个单独的高度,所以需要Ctrl-F

改变图片高度:使用010editor工具,先打开Variables,如下图1;调整高度如下图2
在这里插入图片描述
在这里插入图片描述

4.2 宽度篡改

解释:当高度修改时,可能只是有信息展示不全,但是当宽度篡改时,图片可能如下那样,完全无法还原原图内容,想恢复宽度,可以使用爆破来产生所有宽度的图片,下面给出一个求PNG的爆破脚本(PNG可以使用恢复高度的方法,但是要注意,可能CRC也被改过,导致破解不出来)

在这里插入图片描述

def go(filepath, start, end):
    bp = open(filepath, "rb").read()
    os.makedirs('output')
    print('正在创建目录:output')
    print("正在爆破")
    for i in range(start, end):
        png_name = 'output/' + str(i) + '.png'  # 我是建立一个文件夹,可以不写前面的文件夹路径。
        png = open(png_name, "wb")
        data = bp[:16] + struct.pack('>i', i) + bp[20:]
        png.write(data)
        png.close()
    print("爆破完成,全部输出在output文件夹内")

5.图片模糊

解释:给的图片特别模糊看不清里面的内容,可以通过SmartDeblur进行调整对比度来看尝试让图片清晰一点

6.识别码

解释:有二维码、条形码等等,可能普通的扫码器扫描不出来,可以在在线网址上进行扫码https://online-barcode-reader.inliteresearch.com/

7.双图结合

解释:当题目中给出双图时,可能要用到Stegsolve的Image Combiner功能,先打开一张图再点击Image Combiner然后切换打开新图的色道有时候会出现二维码
在这里插入图片描述

8.文件修复

解释:文件能发现明显的头标志,但是不完整,需要修复,或者填充

9.1 PNG

9.1.1 PNG结构分析

解释:正常的PNG文件由多个Chunk组成,其中一定存在的是开头ChunkIHDR与结尾ChunkIEND,其它还是辅助块(pHYs、tEXt等等)(可能存在可能不存在)和数据块(IDAT)(可能存在多个)构成,其中每个Chunk组成结构如下示例表格

字段大小描述
Length4当前Chunk块的长度
Chunk Type4数据块类型,例如IHDR、pHYs、IDAT、IEND等等
Chunk DataLength数据块的数据
CRC4当前Chunk块的 循环冗余码

分析图片:

# png开头
89 50 4E 47 0D 0A 1A 0A 
# 第一块(IHDR)
00 00 00 0D(Lenth) 49 48 44 52(ASCII:IHDR)
00 00 00 32 00 00 00 32 08 02 00 00 00(Chunk Data)91 5D 1F E6(CRC)
# 第二块(IDAT)
00 00 00 4D(Lenth) 49 44 41 54 78(ASCII:IDAT) 
9C ED CE 31 01 C0 20 10 00 B1 07 FF 9E 5B 03 2C 
99 60 B8 28 C8 9A F9 E6 3D FB 76 E0 AC 96 A8 25 
6A 89 5A A2 96 A8 25 6A 89 5A A2 96 A8 25 6A 89 
5A A2 96 A8 25 6A 89 5A A2 96 A8 25 6A 89 5A A2 
96 A8 25 6A 89 5A E2 07 3F AC 01 63(Chunk Data) 
F7 09 5E 5B(CRC)
# 第三块(IEND)
00 00 00 00(Lenth) 49 45 4E 44(ASCII:IEND) AE 42 60 82(CRC)
9.1.2 PNG注意事项

IDAT的长度:PNG图片里面的数据库IDAT的长度有一定的规律,若有多个IDAT,其前几个长度一般是相同且大于最后一块的长度(如果前几个不相同很有可能是人为修改过,人为修改不一定会改变图片内容),最后一个IDAT长度往往是小于前面的IDAT,在这样可能会遇到插入错误IDAT的CTF题目,删除错误IDAT即可,建议使用tweakpng进行删除

IDAT的数据内容:在有多个IDAT的情况下,往往可以看到第一个IDAT后面紧跟着78 9C(49 44 41 54 78 9C),这代表着IDAT的内容将会被Zlib压缩(78 9C就是Zlib的头),剩下的IDAT后面跟着的也是被Zlib压缩的数据,但是注意一个PNG文件里面只有一个Zlib头,除第一个外的IDAT虽然内容也是被Zlib压缩的,但是其并不是一个新的Zlib压缩包,而是第一个Zlib压缩包余下的内容,这意味在题目中binwalk出两个Zlib往往有一个是有问题的

9.1.3 PNG开头块详解
1、开头的0~7八个字节为png的文件头:89 50 4E 47 0D 0A 1A 0A (固定格式)
2、8~11四个字节:00 00 00 0D 表示头部数据块的长度为13(固定格式)
3、12~15四个字节:49 48 44 52 表示文件头数据块的标示(固定格式)
4、16~19四个字节:00 00 03 84表示图片的宽(不固定)
5、20~23四个字节:00 00 00 96表示图片的高(不固定)
6、24~28五个字节:08 02 00 00 00表示Bit depth(图像深度)、ColorType(颜色类型)、 Compression method(压缩方法)、 Filter method(滤波器方法)、Interlace method(隔行扫描方法)这五个字节不固定,均为可变数据
7、29~32四个字节:76 EC 1E 40为图片的crc校验值由从第12个字节到第28个字节的十七位字节进行crc计算得到

9.2 JPG/JPEG

FF D8 FF + E0/E1 + Data size(2 bytes) + Data(n bytes)

E0表示:JFIF(老设备使用较多)
E1表示:Exif(存储信息更多比如设备时间等等)

10.图片内容异或加减等等

解释:当前10种方案,都不能解决问题时,图片里面只有一群陌生的十六进制,往往有可能是数据被进行了运算,我们可以通过010editor来轻松的解决这些问题

举例:
在这里插入图片描述
具体操作指南:

  1. 点击tools随便打开一个功能
    在这里插入图片描述
  2. 然后虽然都是英文但是下面都有数学公式如下图,特别注明的是下面的X[i]表示的是当前文件遍历每一个16进制的值
    在这里插入图片描述
  3. 注意取反,Negate是取反的函数,意思就是比如0x77+0x89=0x100,此时如果源文件为0x77取反后结果为0x89
    在这里插入图片描述

二、具体类别

补充

1.文件头尾

文件文件头hex文件头ascii文件尾备注
PNG89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52‰PNGIHDR49 45 4E 44(IEND)此结尾并非最后几个(可能是倒数几个)
GIF47 49 46 38G I F 800 3B
WEBP52 49 46 46 XX XX XX XX 57 45 42 50RIFFWEBP00 00
BMP(16位深度)42 4D 28 07 06 00 00 00 00 00 36 00 00 00BM(无固定结尾
BMP(24位深度)42 4D A0 0A 09 00 00 00 00 00 36 00 00 00BM无固定结尾
BMP(32位深度)42 4D 18 0E 0C 00 00 00 00 00 36 00 00 00BM无固定结尾
JPG/JPEG(JFIF)FF D8 FF E0ÿ Ø ÿ à J F I FFF D9
JPG/JPEG(Exif)FF D8 FF E1ÿ Ø ÿ à J F I FFF D9
TIF/TIFF49 20 49无固定结尾
TIF/TIFF(Intel)49 49 2AII*无固定结尾
TIF/TIFF(big endian)4D 4D 00 2AMM无固定结尾
TIF/TIFF(Motorola)4D 4D 2AMM无固定结尾
TIF/TIFF(BigTIFF files)4D 4D 00 2BMM无固定结尾
Python 3.0(pyc)3B 0C 0D 0A暂无无固定结尾
Python 3.1(pyc)4F 0C 0D 0A暂无无固定结尾
Python 3.2(pyc)6C 0C 0D 0A暂无无固定结尾
Python 3.3(pyc)9E 0C 0D 0A暂无无固定结尾
Python 3.4(pyc)EE 0C 0D 0A暂无无固定结尾
Python 3.5(pyc)17 0D 0D 0A暂无无固定结尾
Python 3.6(pyc)33 0D 0D 0A暂无无固定结尾
Python 3.7(pyc)42 0D 0D 0A暂无无固定结尾
Python 3.8(pyc)55 0D 0D 0A暂无无固定结尾
Python 3.9(pyc)61 0D 0D 0A暂无无固定结尾
Python 3.10(pyc)6F 0D 0D 0A暂无无固定结尾
ZIP50 4B 03 04P K 50 4B
RAR452 61 72 21 1A 07 00R a r !C4 3D HEAD_TYPE
RAR552 61 72 21 1A 07 01 00R a r !1D 77 56 51 HEAD_SIZE HEAD_TYPE
7Z37 7A BC AF 27 1C7 z ¼ ¯ ’
Wav52 49 46 46 XX XX XX XX 57 41 56 45 66 6D 74 20RIFF ™WAVE无固定结尾
img(软盘)EB 4E 90ëN无固定结尾编辑虚拟机添加软盘即可打开

2.压缩文件特征

解释:用010editor打开压缩文件,如果看到里面出现文件名或其它文本数据,很有可能其就是压缩文件,一般可以尝试ziprar两种

工具配置

1.Stegsolve

工具地址:http://www.caesum.com/handbook/Stegsolve.jar
解释:该工具需要安装jar包后才能配合使用,下面同时会给出快速打开工具的代码,需要两个文件,启动的时候启动vbs文件

start.bat

java -jar Stegsolve.jar

start.vbs

set ws=createobject("wscript.shell")
ws.Run """start.bat""",0

2.binwalk

  1. 下载:https://github.com/ReFirmLabs/binwalk/archive/refs/tags/v2.3.2.zip

  2. setup:python setup.py install

  3. 便捷化配置:自己写一个快速启动binwalk的py然后打包成exe然后放置于python下面的Scripts目录就能直接在cmdbinwalk xxxx执行命令

    import subprocess
    import sys
    
    # 获取命令行参数(除了脚本名称之外的部分)
    args = sys.argv[1:]
    
    # 指定 Python 解释器和 binwalk 脚本的路径
    python_path = "python"
    binwalk_script = "D:\\python\\Scripts\\binwalk"
    
    # 使用 args 中包含的参数构造命令
    command = [python_path, binwalk_script] + args
    
    # 调用 subprocess.call 来执行命令
    subprocess.call(command)
    
    pyinstaller --onefile binwalk.py
    

3. 010editor

下载:https://www.sweetscape.com/010editor/

复制16进制到左边:Ctrl+Shift+V
复制文本到右边边:Ctrl+V
插入内容:光标放至要插入内容处,然后在软件最上方一栏选择Edit然后选择插入选择Hex与大小即可
对代码进行异或操作等等:
在这里插入图片描述

4.WaterMark

解释:一款普通破解盲水印的工具(适合单图片),下载非官网,请注意
https://pan.quark.cn/s/ab1aaa012cd0#/list/share

5.BlindWaterMark

解释:一款普通破解盲水印的工具(适合多图片)
https://github.com/chishaxie/BlindWaterMark

6.tweakpng

https://entropymine.com/jason/tweakpng/

7.APNG Disassembler

https://sourceforge.net/projects/apngdis/

  • 27
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值