MISC笔记02——图片隐写和压缩包


笔记参考

https://blog.csdn.net/qq_45894840/article/details/128346180

https://secgxx.com/ctf/wiki/ctf-misc-archive/

省流前言

本笔记主要是针对图片类隐写和压缩包类题目进行深入研究总结,包括部分题目的复现,部分内容可能与前一章相似,同时也会包含更多的详细内容

图片隐写

前言

图片隐写是MISC方向中最为常见的题型之一,其主要涉及的内容有:文件数据篡改、图片拼接……

而它主要的一些出题方向如下:

  • 图片头文件及类型判断
  • PNG图片隐写
  • JPG图片隐写
  • GIF图片隐写
  • BMP图片隐写
  • 文件提取
  • LSB隐写
  • 盲水印
  • exif隐写

前置知识补充

文件类型文件头特征值
JPEGFFD8FFimage-20241202150612891
PNG89504E47.PNG...
GIF47494638GIF89a
TIFF49492A00
Windows Bitmap424DBM
WEBP

……随时补充

泛用思路

  • 查看图片的详细信息(右键属性)
  • 用winhex或010分析文件头尾
  • 分析图片的exif信息
  • binwalk或者foremost
  • 图片分离或拼接

PNG

PNG文件的文件头由一个8字节的PNG文件标识域和3个以上的后续数据块,如IHDR、IDAT、IEND等组成

其标识如下:

89 50 4E 47 0D 0A 1A 0A   +数据块+数据块+数据块
89:用于检测传输系统是否支持8位的字符编码,用以减少将文本文件被错误的识别成PNG文件的机会,反之亦然
50 4E 47:PNG每个字母对应的ASCII,让用户可以使用文本编辑器查看时,识别出是PNG文件
0D 0A:DOS风格的换行符,用于DOS-Unix数据的换行符转换
1A:在DOS命令行下,用于阻止文件显示的文件结束符
0A:Unix风格的换行符,用于Unix-DOS换行符的转换

可能遇到的隐写情况为:

  • 文件格式修改(把PNG文件的后缀改成其他的文件)
  • 文件格式倒转(文件的Hex值倒转排列,写脚本复原)
  • 文件头缺失(用工具补齐)
  • 修改图片宽高

PNG文件中,每个数据块都由四个部分组成,分别为:

长度(Length):指定数据块中数据区域的长度,长度不可超过(2^31-1)个字节
数据块类型码(Chunk Type Code):数据块类型码由ASCII字母(A-Z和a-z)组成的"数据块符号"
数据块数据(Chunk Data):存储数据块类型码指定的数据
循环冗余检测(CRC):存储用来检测是否文件传输有误的循环冗余码

修改对应的宽高位的数据即可

image-20241203181824352

  • CRC值爆破**(比较复杂,后续深入了解)**

在遇到图片隐写题目时,原有的图片可能会被修改其宽高,从而导致图片里面的内容无法正常展示,我们可以通过CRC爆破判断他的宽高值是否被修改

通过010或者kali中的pngcheck可以检查图片的CRC32值是否校验错误,确定错误后,即可对其进行修改

简单的宽高隐写,可以通过直接修改宽高值后,显示flag;如果没有办法直接显示,则需要撰写脚本进行爆破,这里贴一个网上大佬写的爆破脚本,可以同时爆破出图片的宽高

import struct
import zlib

def hexStr2bytes(s):
    b = b""
    for i in range(0,len(s),2):
        temp = s[i:i+2]
        b +=struct.pack("B",int(temp,16))
    return b

str1="49484452"
str2="0806000000"
bytes1=hexStr2bytes(str1)
bytes2=hexStr2bytes(str2)
wid,hei = 1918,864

crc32 = "0x7dc73f7f"    #填写正确的crc值,可以用pngcheck查看

for w in range(wid,wid+2000):
    for h in range(hei,hei+2000):
        width = hex(w)[2:].rjust(8,'0')
        height = hex(h)[2:].rjust(8,'0')
        bytes_temp=hexStr2bytes(width+height)
        if eval(hex(zlib.crc32(bytes1+bytes_temp+bytes2))) == eval(crc32):
            print(hex(w),hex(h))

得到宽高后,用010进行修改,然后再进一步分析即可。

  • 文件提取(用binwalk、foremost等工具提取)

JPG

  • JPEG 是有损压缩格式,将像素信息用 JPEG 保存成文件再读取出来,其中某些像素值会有少许变化。在保存时有个质量参数可在 0 至 100 之间选择,参数越大图片就越保真,但图片的体积也就越大。一般情况下选择 70 或 80 就足够了
  • JPEG 没有透明度信息

JPEG文件的文件头标识如下:

FF D8 FF

另外其文件尾标识为:

FF D9

可能遇到的隐写情况为:

  • 修改图片宽高

修改对应的宽高位的数据即可

image-20241203182058198

BMP隐写

BMP 文件格式能够存储单色和彩色的二维数字图像,具有各种颜色深度,并且可以选择使用数据压缩、alpha 通道和颜色配置文件

其文件头标识如下:

42 4D

BMP文件头标识的后四位表示的是BMP的图片大小,示例如下

8E 26 2C 00

由于个人计算机都是以小端序,所以数据要从右往左写

所以其大小实则应为

0x002c268e == 2893454(Byte) == 2.75M

可能遇到的隐写情况为:

  • 修改图片宽高

在这里插入图片描述

EXIF信息

拍摄图片时,exif会记录数码照片的属性信息和拍摄数据,可以通过查看图片属性中的详细信息看到部分exif信息

在kali中可以使用exiftool查看更详细的exif数据

exiftool xxx.jpg

可能遇到的题型:

  • OSINT(社工,查看图片经纬度)

GIF隐写

GIF的文件头标识如下:

47 49 46 38 39 61

可能遇到的题型如下:

  • GIF帧分离+拼接

这类题型需要用到imagemagick工具

sudo apt install imagemagick

对于得到的gif,对它进行帧分离操作

convert xxx.gif xxx.png		#逐帧分割图片

最后将得到的图片集群拼成一张图片

montage xxx*.png -tile x1 -geometry +0+0 xxx.png	#合并图片
  • GIF图像特征

有些gif图每帧间存在规律,可能每一帧的时间间隔隐藏了信息

可以用identify工具识别他的间隔

identify -format "%T" xxx.gif

最后将得到的值进行处理

  • 逐帧查看

使用stegsolve工具进行逐帧分析

在这里插入图片描述

盲水印

显然这就是一种肉眼不可见的水印

需要使用bwm工具进行解析

bwm decode xxx.png xxx_with_wm.png yyy.png

LSB隐写

简单来说就是人眼无法区分所有的颜色,通过修改LSB(最低有效位),在改变少量数据达到隐藏信息的情况下,让人眼无法察觉到前后的变化,已达到隐写的目的,如下图所示。

在这里插入图片描述

针对这类隐写,可能遇到以下类型:

  • 工具分析(利用stegsolve)

  • 数据隐藏(利用kali的lsb工具)

示例如下

lsb extract secret.png flag.txt  7his_1s_p4s5w0rd
//extract:提取,后面为需要提取信息的图片和输出的文件名,以及key值

字符串提取

有些题目会往图片里添加一些字符串,可以直接使用kali的strings工具提取

strings xxx.jpg

压缩包

前言

压缩包也是CTF中十分常见的考点,几乎什么题目里面都可以涉及到压缩包的处理

而它的主要出题方向是:

  • 伪加密
  • 明文攻击
  • CRC爆破
  • 暴力破解
  • ……

前置知识补充

  • 压缩包的密码可以是中英文字符、数字和符号,没有思路时可以直接纯数字/字母暴力爆破一下

ZIP结构

文件格式

ZIP文件主要由三个部分构成,分别是:

压缩文件源数据区 + 压缩源文件目录区 + 压缩源文件目录结束标志
压缩源文件数据区核心目录目录结束
local file header + file data + data descriptorcentral directoryend of central directory record

注:以下表格内除了专门标注出固定值的,其他内容的HEX数据会根据压缩包的不同而不同

压缩源文件数据区
HEX 数据描述010Editor 模板数据
50 4B 03 04local file header,即zip 文件头标记,固定值,记录了该压缩文件的信息,解码得到的文本为 PK 开头char frSignature[4]
14 00解压文件所需 pkware 版本ushort frVersion
00 00全局方式位标记(有无加密),头文件标记后 2bytesushort frFlags
08 00压缩方式enum COMPTYPE frCompression
C7 4D最后修改文件时间DOSTIME frFileTime
BF 54最后修改文件日期DOSDATE frFileDate
74 04 44 4ACRC-32 校验uint frCrc
5F A4 05 00压缩后尺寸
74 BF 05 00未压缩尺寸
11 00文件名长度
1D 00扩展记录长度

image-20241130115330754

压缩源文件目录区
HEX 数据描述010Editor 模板数据
50 4B 01 02目录中文件文件头标记,固定值char deSignature[4]
14 00压缩使用的 pkware 版本ushort deVersionMadeBy
14 00解压文件所需 pkware 版本ushort deVersionToExtract
00 00全局方式位标记(有无加密),目录文件标记后 4bytesushort frFlags
08 00压缩方式enum COMPTYPE frCompression
C7 4D最后修改文件时间DOSTIME frFileTime
BF 54最后修改文件日期DOSDATE frFileDate
74 04 44 4ACRC-32 校验uint frCrc
5F A4 05 00压缩后尺寸
74 BF 05 00未压缩尺寸
11 00文件名长度
41 00扩展字段长度
00 00文件注释长度
00 00磁盘开始号
00 00内部文件属性
20 00 00 00外部文件属性
00 00 00 00局部头部偏移量

image-20241130115629091

压缩源文件目录结束标志
HEX数据描述010Editor模板数据
50 4B 05 06目录结束标记,**固定值,**用于标记压缩的目录数据的结束。每个压缩文件必须有且只有一个结束标志char elSignature[4]
00 00当前磁盘编号ushort elDiskNumber
00 00目录区开始磁盘编号ushort elStartDiskNumber
16 00本磁盘上纪录总数
16 00目录区中纪录总数
97 0D 00 00目录区尺寸大小
91 DE B0 01目录区对第一张磁盘的偏移量
00 00ZIP 文件注释长度

image-20241130121302377

RAR结构

文件格式

RAR 文件主要由标记块,压缩文件头块,文件头块,结尾块组成。

其每一块大致分为以下几个字段:

名称大小描述
HEAD_CRC2全部块或块部分的CRC
HEAD_TYPE1块类型
HEAD_FLAGS2阻止标志
HEAD_SIZE2块大小
ADD_SIZE4可选字段 - 添加块大小
文件头标识
HEX 数据描述010Editor 模板数据
52 61 72 21 1A 07 00rar 文件头标记,文本为 Rar!

image-20241130122539996

Main block
HEX 数据描述010Editor 模板数据
25 CB 7C FD全部块的 CRC32 值uint32 HEAD_CRC
0C块大小struct uleb128 HeadSize
01块类型struct uleb128 HeadType
05阻止标志struct uleb128 HeadFlags

image-20241130133641690

文件头(File Header)
HEX 数据描述010Editor 模板数据
5C 8B D2 90单独块的 CRC32 值uint32 HEAD_CRC
3D块大小struct uleb128 HeadSize
02块类型struct uleb128 HeadType
03阻止标志struct uleb128 HeadFlag

image-20241130133915594

结尾块(Terminator)
HEX 数据描述010Editor 模板数据
1D 77 56 51固定的 CRC32 值uint32 HEAD_CRC
03块大小struct uleb128 HeadSize
05块类型struct uleb128 HeadType
04 00阻止标志struct uleb128 HeadFlag

image-20241130133950651

7z结构

文件格式

7z格式的压缩包对应的文件头为:

37 7A BC AF 27 1C

爆破

爆破,顾名思义就是在得不到任何已知条件或者已知条件非常有限的情况下,暴力估测我们所需要的密码是多少(就是遍历所有可能),适合密码较为容易或者知道密码范围/格式,包括字典爆破、掩码攻击等

压缩包密码爆破中常常用到的工具有:

  • ARCHPR
  • fcrackzip
  • hashcat
  • Ziprello

暴力破解

以ARCHPR进行爆破为例

作为最普通的密码攻击手段,ARCHPR允许在范围选项卡中,选择暴力破解的字符集:

其中ARCHPR中的所有特殊符号如下

!@#$%^&*()_+-=<>,./?[]{}~:;`'|"\

此外,我们还可以自定义字符集:通过勾选用户定义,然后点击右边的”自定义字符集”选项

image-20241130151942880

如你所见,在给定的字符集中,只囊括了ASCII可打印字符,如果 .zip 的密码是中文的话,那就必须选择”自定义字符集”,并且勾选转换为OEM编码;否则密码会”Not Found”

  • 在长度选项卡中,设置密码长度:
  • 在范围选项卡的右边,可以看到:开始于、结束于

还需要知道,ARCHPR在暴力破解密码的时候,采用了特定的破解顺序:

  • 大小字母 A - Z
  • 空格
  • 小写字母 a - z
  • 数字 0 - 9
  • 特殊字符 !@#$ …
    也就是说,暴力破解密码的顺序大致为:
"AAA" -> "AAB" -> "AAC" -> ... -> "AAZ" -> "AA " -> "AAa" -> "AAb" -> ... -> "AAz" -> "AA0" -> "AA1" -> ... -> "AA9" -> "AA!" -> "AA@"

上图的”开始于”有2个作用:

当你知道密码长度为5,并且第一个字符为 k,你可以在”开始于”设置kAAAA,那么ARCHPR将跳过AAAAAkAAAA的前一个的暴力破解,节省时间
如果破解密码的时间太长,ARCHPR会每隔5分钟自动保存密码(在自动保存选项卡中可以选择),如果某次暴力破解被迫中断,那么可以通过查看最后一次保存的密码,并设置”开始于”,直接从上次爆破的地方继续开始爆破
“结束于”的作用类似

容易遇到的问题

  • 在尝试用ARCHPR进行暴力破解时,可能会显示

image-20241203183026788

这是因为zip的压缩算法是有版本的,ARCHPR不支持较高版本的ZIP,这时候可以选择更换爆破工具,如fcrackzip

掩码攻击

同样以ARCHPR为例

掩码攻击属于局部暴力破解,本质上就是我们知道了密码的一部分后,我们可以通过使用?代替不知道的部分,针对性的进行爆破,从而大大减少爆破时间

要注意的是,掩码攻击是固定长度的

如果密码本身含有?,可以再高级选项中修改掩码符号

image-20241130153237257

字典爆破

字典爆破比暴力破解而言更为的迅速智能,其本质就是准备了大量的常用密码,利用这些常用密码去进行遍历爆破,因此一份好的字典是非常重要的

Github上有许多开源的现成爆破字典:
https://github.com/rootphantomer/Blasting_dictionary

在ARCHPR中,字典爆破提供了三个特别选项:

  • 智能变化

简单来说就是,以password这个密码为例,他会将其进行各种程度的变化,大小写变换之类的

  • 尝试所有可能得大小s写组合

与智能变化类似,以password为例,ARCHPR会逐渐将每一个字母转换为大写,只到变成PASSWORD

  • 转换为OEM编码

当字典元素不只有包含拉丁字母时,这个选项才会生效

image-20241130155554405

注释

往往在压缩包的注释中,也可能藏有一些提示信息或是隐藏信息,比如隐藏了摩斯电码,对注释进行反色或是利用tab和空格制造摩斯电码等

伪加密

ZIP

原理

在上文 ZIP 结构中的 压缩源文件数据区压缩源文件目录区 中,我们强调了一个叫做全局方式位标记 (General purpose bit flag)2 字节,不同比特位有着不同的含义。

Bit 0: If set, indicates that the file is encrypted.				#设置后表示该文件已加密

(For Method 6 - Imploding)
Bit 1: If the compression method used was type 6,					#
     Imploding, then this bit, if set, indicates
     an 8K sliding dictionary was used.  If clear,
     then a 4K sliding dictionary was used.
...
Bit 6: Strong encryption.  If this bit is set, you should			 #
     set the version needed to extract value to at least
     50 and you must also set bit 0.  If AES encryption
     is used, the version needed to extract value must
     be at least 51.
...

通常全局方式位标记为 2 bytes 长度,第一字节数字为偶数表示无加密,例如:00,02,04 等;为奇数表示有加密,例如 01,03,09 等。

是否加密全局方式位标记数据解释
无加密源文件数据区和源文件目录区中均为00 00
伪加密源文件数据区应为09 00,源文件目录区应为00 00或者01 00
真加密源文件数据区应为09 00,源文件目录区应为09 00

修改伪加密的方法:

  • 16 进制下修改通用位标记,改为00 00
  • binwalk -e 无视伪加密,直接分离文件
  • Mac OS 及部分 Linux(如 Kali )系统中,可以直接打开伪加密的 ZIP 压缩包
  • 直接使用检测伪加密的小工具 ZipCenOp.jar修复
java -jar ZipCenOp.jar r screct.zip

注意:ZipCenOp.zip 对正常加密的 .zip 压缩包会直接修改所有加密位为偶数,虽然会让ZIP压缩软件显示”未加密”,但往往 .zip 文件也损坏了,得到”CRC校验错误”的结果
  • 有时候用 WinRar 的修复功能(此方法有时有奇效,不仅针对伪加密)

RAR

原理

没搞懂

明文攻击

明文攻击,顾名思义,需要我们有一部分已知信息去对未知的内容进行爆破,而其中又分为

  • 已知所有明文(或三段密钥)
  • 已知部分明文
原理
  • .zip 传统加密算法本质上是伪随机数流明文进行异或,产生这个伪随机流需要用到3个32 bits的key;找到这3个key,就能解开加密的文件
  • 压缩软件用这3个key加密压缩包中的所有文件,当我们得到已加密压缩包中的任意一个文件,如果我们用同样的压缩方法进行无密码的压缩,得到的无密码 .zip 和有密码的 .zip 进行比较,分析两个文件的不同点,就能得到3个key了
  • 用相同的压缩方法将该明文压缩成 .zip在拥有2个 .zip 文件后,由于新的 .zip 和原本的 .zip 用同样的压缩方法放置入了至少1个相同的文件,那么就能够根据新的 .zip 爆破出压缩密码
  • 明文需大于12 bytes
工具

明文攻击中常用的工具如下

  • ARCHPR
  • bkcrack

CRC32爆破

原理

CRC 本身是「冗余校验码」的意思,CRC32 则表示会产生一个 32 bit ( 8 位十六进制数)的校验值。由于 CRC32 产生校验值时源数据块的每一个 bit (位)都参与了计算,所以数据块中即使只有一位发生了变化,也会得到不同的 CRC32 值。

CRC32 校验码出现在很多文件中比如 png 文件,同样 zip 中也有 CRC32 校验码。值得注意的是 zip 中的 CRC32 是未加密文件的校验值。

这也就导致了基于 CRC32 的攻击手法。

  • 小文件(一般比赛中大多为 4 字节左右)
  • 加密的密码很长

我们不去爆破压缩包的密码,而是直接去爆破源文件的内容(一般都是可见的字符串),从而获取想要的信息。

通常来说需要搓一些脚本来进行CRC32爆破,也可以用一些现成的脚本,如:

https://github.com/theonlypwner/crc32

例题复现

例题复现主要是对培训或者平时遇到的一些题目进行分析和复现,并进行相应的记录和知识点总结

图片类

ctfshow - misc入门 - misc2

解题过程

附件得到一个txt文本,打开发现显然是个PNG图片,修改后缀为png即可得到flag

image-20241202155038866

image-20241202155115008

复现

将图片后缀改成txt即可

ctfshow - 菜狗杯 - 损坏的压缩包

解题过程

得到的压缩包打开发现显示如下,丢去winhex看看,发现其实是个PNG图片,改一下后缀即可得到flag

image-20241202155507436

image-20241202155750722

image-20241202155814157

复现

将flag图片的后缀改成zip即可

ctfshow - misc入门 - misc10

解题过程

得到一张图片,简单分析发现啥也没有,试着用binwalk分析分离一下,可以发现有两个2zlib文件,

image-20241126171244428

image-20241126171353951

简单看看他们的内容,可以在第一个文件里发现flag

image-20241126171420449

复现

ctfshow - misc入门 - misc8

解题过程

下载附件,得到图片,然后老样子:详细信息,winhex分析,但是都没有找到明显的信息。想到题目里面给了提示:flag在图片文件中图片文件中,因此猜测是不是图片里藏了别的文件

image-20241125210853557

用binwalk对其进行分析,发现有两张png图片

image-20241125210923403

用foremost分离文件,得到两张png图片,其中一张即为flag

image-20241125204553341

复现

ctfshow - misc入门 - misc18

解题过程

打开图片后,发现啥也没有

image-20241202161544769

简单看看图片的属性,便可发现flag别切割成了多个部分,放在多个属性中(也可以用exiftool查看)

image-20241202161639382

整合后即可得到完整的flag

复现

直接修改图片属性里的详细信息即可

ctfshow - misc入门 -misc5

解题过程

得到一张图片,打开啥也没有,属性也没有什么信息,丢去winhex里分析一下

image-20241202163050737

然后可以在数据末尾发现flag

image-20241202163137322

复现

将图片丢进winhex里进行处理,然后将flag插入图片的数据末尾即可

ctfshow-misc入门-misc11

解题过程

打开图片发现啥也没有,属性,winhex中也不能看到明显的信息,用tweakpng打开发现存在两个IDAT块,删掉第一个后保存即可得到flag

image-20241202164321735

image-20241202164337002

复现

用tweakpng在flag图片的基础上,插入一个隐藏图片的IDAT块即可;或者用winhex或010插入数据应该也可以

ctfshow - misc入门 - misc25

解题过程

打开图片没有任何信息,属性也没有信息,用winhex进行分析

image-20241202170405720

尝试修改图片高度,保存后发现flag(有些图片修改后可能无法正常显示,此时需要CRC32爆破)

image-20241202170457651

image-20241202170542107

复现

用winhex或者010修改flag图片的高度即可

ctfshow-misc入门-misc50

解题过程

打开图片 发现啥信息都没有,不过图片长得很怪,很多噪点(不知道是不是某种特征) ,丢给stegsolve分析一下,

image-20241202170924395

翻页后可以发现flag

image-20241202171059829

image-20241202171131627

image-20241202171107972

或者丢去aperisolve直接梭哈

image-20241202171154539

复现

好像是用python写隐写脚本,没研究的太明白

ctfshow - misc入门 - misc53

解题过程

得到一张图片,看不到任何信息,属性也没有内容,winhex也找不到任何有效信息

image-20241202190848185

丢到stegsolve中查看,翻页发现也没有任何的信息,尝试修改颜色通道信息后,可得到flag

image-20241202191812040

复现

应该也是通过写脚本实现

攻防世界 - misc - misc_pic_again

解题过程

得到一张图片,没有任何明显的信息,丢给stegsolve处理,修改颜色通道,可以发现藏有一个压缩包,保存后解压

image-20241202193004237

解压后得到一个文件,在文件中可以找到flag

image-20241202193039002

复现

写脚本

ctfshow - misc入门 - misc37

解题过程

得到一张gif图,查看后可以发现里面隐约藏了内容,直接分离gif里的每一帧,拼凑起来就可以得到flag

image-20241202193350205

复现

用flag做一张gif图就好了

攻防世界 - misc - a_good_idea

解题过程

得到一张图片,用binwalk分离可以得到两张图片

image-20241202195841944

用stegsolve合并两张图片,先todo再to,然后可以发现藏有一个二维码

image-20241202195914466

扫码后得到flag

image-20241202195930967

复现

用copy将图片和一个zip合并,zip里放两张图片,至于两张图片怎么弄不知道

压缩包类

攻防世界 - misc - János-the-Ripper

解题过程

解压得到一个misc100文件,丢进winhex可以发现是个zip,修改后缀后,发现解压需要密码

image-20241202200402513

直接用ARCHPR爆破,得到密码后解压即可得到flag

image-20241202200330800

复现

将flag文档加密压缩后,去掉后缀即可

ctfshow-萌新-萌新 隐写2

解题过程

打开压缩包发现要密码,根据题目提示可以猜测压缩包密码格式应该是199?????,因此我们可以进行掩码攻击(其实这个格式感觉不用也行)

image-20241202201314620

爆破后即可得到flag

image-20241203181554251

复现

加密压缩即可

qwq