当前位置:网站首页>ctf misc 图片题知识点

ctf misc 图片题知识点

2022-08-09 08:33:00 z.volcano

补充了一点东西

常规思路

图片名及图片内容

除了题目描述和给的提示外,注意图片名图片里的内容,很有可能是接下来要用到的隐写工具或者加密方法的提示

例如第四届蓝帽杯决赛的一道misc:MISC隐写 给了一张图片,里面是一条蛇,这个提示的是后面会用到的一种解密方法;然后从图片中提取出一个pdf文件,文件名是no password.pdf,也提示了需要用到工具,不需要输入密码。

bpg图片

bpg格式的图片在windows系统下是不能直接查看的,需要下载工具
在这里插入图片描述
输入命令查看图片
在这里插入图片描述

exif信息

拿到一个图片时,建议查看一下它的exif信息,可能会有意想不到的收获
出题人经常在图片的exif信息中藏flag或者提示信息,这里以bugku的misc题目有黑白棋的棋盘为例在这里插入图片描述
这里是直接右键查看属性,不过这样能获取的信息十分有限
ctfshow中八神出的misc入门misc18-21考察的都是这个知识点,具体可以看我另一篇博客

拿其中的misc20为例,直接右键查看属性,翻看详细信息,得不到任何线索,推荐使用一个在线查看exif信息的网站,这里能得到的结果更详细,也可以使用exiftool
在这里插入图片描述

修改图片宽高

很多时候,所给的图片的宽高,甚至crc32校验值都是被修改过的,需要我们去爆破得到正确的值。

这里推荐使用010editor,它的模板功能非常好用,我是010editor+winhex配合使用的。
在这里插入图片描述

png

png图片修改宽高还是很容易的,这里是png.bt模板,框中的值分别是宽高crc值,这里修改之后保存即可
在这里插入图片描述
对于png,一般情况下,是把高度改大,看下面有没有内容
在这里插入图片描述

jpg

运用jpg.bt,可以很方便修改jpg的宽高
在这里插入图片描述
对于jpg,一般情况下也是把高度改大,能看到图片下面的内容

gif

整体和前两种差不多,借助gif.bt,这里比较特殊的是,每一帧都有独立的宽高,因为不知道flag藏在哪一帧,一般建议把所有帧的高度都改大,然后用Stegsolve打开,翻看每一帧图片。

bmp

借助bmp.bt,整体和前面差不多,当宽度错误时,图片显示很乱
在这里插入图片描述
问题就是如何计算正确的宽度和高度,以ctfshow-misc入门的misc24为例,在这里插入图片描述
目前是900*150=135000个像素大小,文件头占了53个字节,文件尾的位置在675053字节处(后面两个字节是windows的”补0”),又因为每个像素点由3个字节(十六进制码6位)表示,每个字节负责控制一种颜色,分别为蓝(Blue)、绿(Green)、红(Red),所以文件真实的像素大小为:(675053-53)/3=225000

这题中给出了正确的宽度900,所以正确的高度就是225000/900=250

爆破脚本

png图片,已知正确的IHDR块的CRC值时,爆破宽度和高度

import zlib
import struct

# 同时爆破宽度和高度
filename = "misc32.png"
with open(filename, 'rb') as f:
    all_b = f.read()
    data = bytearray(all_b[12:29])
    n = 4095
    for w in range(n):
        width = bytearray(struct.pack('>i', w))
        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)
            #替换成图片的crc
            if crc32result == 0xE14A4C0B:
                print("宽为:", end = '')
                print(width, end = ' ')
                print(int.from_bytes(width, byteorder='big'))
                print("高为:", end = '')
                print(height, end = ' ')
                print(int.from_bytes(height, byteorder='big'))

png图片,如果IHDR块的CRC的值被修改过,那就直接爆破,运行后会生成很多个图片,看一下哪个是正常的就行
这里是已知高度的情况下爆破宽度,根据自己需要修改脚本

import zlib
import struct
filename = "misc34.png"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[16:20]
    #h = all_b[20:24]
    for i in range(901,1200):  #界定宽度的范围
        name = str(i) + ".png"
        f1 = open(name,"wb")
        im = all_b[:16]+struct.pack('>i',i)+all_b[20:]
        f1.write(im)
        f1.close()

jpg图片,已知高度,爆破宽度
如果跑出来的图片看不到想要的东西,可能是狗出题人把原本的高度调小了,可以试一下把高度改大,再跑一遍试试

import zlib
import struct
filename = "misc35.jpg"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[159:161]
    #h = all_b[157:159]
    for i in range(901,1200): #界定宽度范围
        name = str(i) + ".jpg"
        f1 = open(name,"wb")
        im = all_b[:159]+struct.pack('>h',i)+all_b[161:]
        f1.write(im)
        f1.close()

gif图片,已知高度爆破宽度
如果跑出来没东西,试试把高度改高

import zlib
import struct
filename = "misc36.gif"
with open(filename, 'rb') as f:
    all_b = f.read()
    for i in range(920,951):
        name = str(i) + ".gif"
        f1 = open(name,"wb")
        im = all_b[:38]+struct.pack('>h',i)[::-1]+all_b[40:]
        f1.write(im)
        f1.close()

查看文件的字节

使用010editor和winhex对文件进行分析

分析文件头文件尾

如果图片打开错误,先看看文件头和文件尾出错没,如果有错误进行修改

JPEG (jpg),
文件头:FFD8FF   文件尾:FF D9 
              
PNG (png),   
文件头:89504E47  文件尾:AE 42 60 82
GIF (gif),   
文件头:47494638  文件尾:00 3B
ZIP Archive (zip),
文件头:504B0304   文件尾:50 4B
TIFF (tif),  
文件头:49492A00
Windows Bitmap (bmp),  
文件头:424D
      
CAD (dwg),  
文件头:41433130 
                     
Adobe Photoshop (psd),
文件头:38425053 
                     
Rich Text Format (rtf),
文件头:7B5C727466 
                   
XML (xml),
文件头:3C3F786D6C 
                   
HTML (html),
文件头:68746D6C3E
Email [thorough only] (eml),
文件头:44656C69766572792D646174653A
Outlook Express (dbx),
文件头:CFAD12FEC5FD746F
Outlook (pst),
文件头:2142444E
MS Word/Excel (xls.or.doc),
文件头:D0CF11E0
MS Access (mdb),
文件头:5374616E64617264204A
WordPerfect (wpd),
文件头:FF575043
Adobe Acrobat (pdf),
文件头:255044462D312E
Quicken (qdf),
文件头:AC9EBD8F
Windows Password (pwl),
文件头:E3828596
RAR Archive (rar),
文件头:52617221
Wave (wav), 文件头:57415645
AVI (avi), 文件头:41564920
Real Audio (ram), 文件头:2E7261FD
Real Media (rm), 文件头:2E524D46
MPEG (mpg), 文件头:000001BA
MPEG (mpg), 文件头:000001B3
Quicktime (mov), 文件头:6D6F6F76
Windows Media (asf), 文件头:3026B2758E66CF11
MIDI (mid), 文件头:4D546864

看看字节流中有没有隐藏信息

推荐使用winhex或者notepad,打开后直接拉到底部,看有没有什么额外信息
然后直接ctrl+f搜索keyflagpassword等字样,没准就拿到flag了
在这里插入图片描述
也有可能不是直接给到的,需要进行进一步的处理
在这里插入图片描述

其实更常见的是,在尾部隐写另一个文件的数据,一般是一个压缩包,可以手动把数据提取出来,或者使用foremostbinwalk提取。

使用stegsolve

stegsolve是非常常用的工具,功能十分强大

用stegsolve打开图片后,建议先把所有的图层都看一遍,可能会有flag或者提示信息

如果是gif图片,可以使用frame browser查看所有帧
在这里插入图片描述

如果是两张很相似的图片,但是其中一张有很难以辨认的文字痕迹,可以用image combiner功能

lsb隐写

在翻看图层的时候,可能会发现lsb隐写的痕迹(不太好描述,做习惯了就知道)

使用stegsolve的data extract,选上对应的通道(比较常见的是如下配置),就可以得到隐藏的信息
在这里插入图片描述

有密码的lsb隐写

项目地址:https://github.com/cyberinc/cloacked-pixel

这个项目是基于python2的,如果环境中同时有Py2和Py3需要注意下

加密
python2 lsb.py hide <img_file> <payload_file> <password>
解密
python2 lsb.py extract <stego_file> <out_file> <password>

gif帧数间隔隐写

使用linux下的工具identify

安装命令:sudo apt-get install imagemagick
基本的命令格式:
  identify [options] input-fileidentify:命令名称
  options:参数
  input-file:文件名。
提取命令:identify -format "%T " misc39.gif > 1.txt

提取之后会得到一系列数字,一般是由两种数字重复组成,其中一种转成1,另一种换成0,得到一长串二进制,后面一般是转字符或者转二维码

apng帧数间隔隐写

apng也是和gif一样会动的,使用工具APNG Disassembler提取出每一帧图片,和对应的详细信息,其中就包括间隔时间,注意使用这个工具的时候,提前把图片放在一个文件夹里…

后面步骤同上

工具隐写

SilentEye

打开图片后点decode进行解密
在这里插入图片描述
可以注意到有bmp和jpg两种,如果有密码,勾选encrypteddata输入密码再解密即可
在这里插入图片描述

OurSecret

也是很常用的工具,如果解题需要用到这个工具,出题人一般会给提示,比如我们的秘密是绿色的,其中的秘密英文是Secret,就是暗示用这个工具。

也是windows下的软件,界面如下
在这里插入图片描述
使用也很简单,在右侧(UNHIDE)打开文件,输入密码,再点击UNHIDE就行

S-Tools

下载地址及详细内容

加密

打开之后,把要加密的图片拖进去,然后把要隐写的文件也拖进去,此时会提示让输入密码,设置密码后得到隐写后的文件

解密

打开之后,把要解密的图片拖进去,然后右键→Reveal→输入密码
在这里插入图片描述
就可以得到隐藏的文件了

jpg

JAVA盲水印

项目地址:https://github.com/ww23/BlindWaterMark/releases

使用命令:java -jar BlindWatermark.jar decode -c bingbing.jpg decode.jpg

Jphswin.exe

我用的是windows版本的,界面如下
在这里插入图片描述
使用起来也很简单,点击open jpeg打开图片,然后点击seek,如果有密码就输入密码,没有就直接回车
在这里插入图片描述

Free_File_Camouflage

不算太常见的一个软件,123分别是

解密的图片的位置
如果有密码就勾选,然后输入密码,没有就直接跳过
解出文件放在什么位置

在这里插入图片描述

f5-steganography (F5隐写,需要passwd)

kali中安装,直接git clone https://github.com/matthewgao/F5-steganography

具体使用:

进入f5-steganography文件夹后,打开终端
# 解密
java Extract filename.jpg -p 密码
运行后会在文件夹里生成一个output.txt,打开即可

# 加密
java Embed 原图.jpg 生成图.jpg -e 隐藏的文件.txt -p 密码

outguess (可需要passwd)

kali中安装:

先下载
git clone https://github.com/crorvick/outguess
然后进入outguess文件夹,打开终端输入./configure && make && make install
成功之后即可

使用:

进入文件夹后打开终端

加密
outguess -k 密码 -d hidden.txt 1.jpg 2.jpg
#hidden.txt是要隐写的内容,运行后1.jpg会覆盖2.jpg

解密
outguess -k 密码 -r 2.jpg out.txt
outguess -r 2.jpg out.txt   #不用密码的情况

steghide

kali中的安装:sudo apt-get install steghide

使用:

加密
steghide embed -cf out.jpg -ef flag.txt [-p 密码]
把flag.txt隐写到out.jpg中,如果要添加密码,尾部接上 -p 密码

解密
steghide info out.jpg  #查看图片中嵌入的文件信息
#提取隐藏内容
steghide extract -sf out.jpg -p 密码
steghide extract -sf out.jpg

steghide本身不支持爆破密码,可以借助https://github.com/Va5c0/Steghide-Brute-Force-Tool

使用前还要安装一个库:pip install progressbar2

使用方法:

python steg_brute.py -b -d [字典] -f [jpg_file]

png & bmp

普通盲水印

项目地址:https://github.com/chishaxie/BlindWaterMark
具体安装过程自行百度

使用:

加密
python2 bwm.py encode 1.png water.png 2.png #PY2
python3 bwmforpy3.py encode 1.png water.png 2.png #PY3

解密
python2 bwm.py decode 1.png 2.png out.png  #PY2
python3 bwmforpy3.py decode 1.png 2.png out.png  #PY3
py2和py3的算法不一样,得到的out.png清晰度也不一样,建议都试一下

也可以加--alpha参数  可能会使图片更清晰
python3 bwmforpy3.py decode 1.png 2.png out.png --alpha 10 #PY3

频域盲水印

脚本:

# coding=utf-8
import cv2   
import numpy as np
import random
import os
from argparse import ArgumentParser
ALPHA = 5
def build_parser():
    parser = ArgumentParser()
    parser.add_argument('--original', dest='ori', required=True)
    parser.add_argument('--image', dest='img', required=True)
    parser.add_argument('--result', dest='res', required=True)
    parser.add_argument('--alpha', dest='alpha', default=ALPHA)
    return parser
def main():
    parser = build_parser()
    options = parser.parse_args()
    ori = options.ori
    img = options.img
    res = options.res
    alpha = options.alpha
    if not os.path.isfile(ori):
        parser.error("original image %s does not exist." % ori)
    if not os.path.isfile(img):
        parser.error("image %s does not exist." % img)
    decode(ori, img, res, alpha)
def decode(ori_path, img_path, res_path, alpha):
    ori = cv2.imread(ori_path)
    img = cv2.imread(img_path)
    ori_f = np.fft.fft2(ori)
    img_f = np.fft.fft2(img)
    height, width = ori.shape[0], ori.shape[1]
    watermark = (ori_f - img_f) / alpha
    watermark = np.real(watermark)
    res = np.zeros(watermark.shape)
    random.seed(height + width)
    x = range(height / 2)
    y = range(width)
    random.shuffle(x)
    random.shuffle(y)
    for i in range(height / 2):
        for j in range(width):
            res[x[i]][y[j]] = watermark[i][j]
    cv2.imwrite(res_path, res, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
if __name__ == '__main__':
    main()

使用命令:python BlindWaterMarkplus.py --original 1.png --image 2.png --result res.png

如果得到的res.png有问题,把1.png和2.png互换位置试一下

zsteg(lsb隐写)

kali安装:gem install zsteg

使用:

zsteg 1.png
zsteg 1.bmp

PNGDebugger.exe(检查IDAT块)

一般在windows系统下使用,在文件夹中打开cmd命令行

输入:PNGDebugger.exe filename.png

tweakpng.exe

windows系统下的一个软件,是很好用的一个PNG图像浏览工具

用来增加或者删除png图片的IDAT块很方便,之前做过八神的一个题,就是删除了一个png的图片中的部分IDAT块,保存得到一张不同的图片,其中就有flag,这里因为对png的结构了解的不是很透彻,原理说不清楚。

在使用这个软件打开图片之前,建议先用PNGDebugger看一下图片中有多少IDAT块的crc32是出错的,因为在使用这个软件的时候,每一个错误都会有一个弹窗。

比如misc入门的misc44就不建议用这个软件打开

二维码

二进制转二维码

这里以bugku中的神奇宝贝为例

拿到一串二进制,如果它的长度被开方后正好是整数,比如这题,满足625=25*25,就可以考虑转二维码。

import PIL
from PIL import Image
MAX = 25  #图片边长
img = Image.new("RGB",(MAX,MAX))
str="1111111001110111001111111100000100001101010100000110111010011100101010111011011101010110000101011101101110101010111010101110110000010011001101010000011111111010101010101111111000000000100101000000000011000111011010110000110001000000010100001010111100001011110101100111110011100101101001100101010010111000101011100100101101001111110000110101011110011010000010010001011100001111000010011101010110001100101110101000111011111010100000000110001101000110001111111011001100101010101100000101111001110001100010111010011100011111101111011101001101111011010011101110100010011010010010110000010100011010011110011111111011011100101010001"
i = 0
for y in range (0,MAX):
    for x in range (0,MAX):
        if(str[i] == '1'):
            img.putpixel([x,y],(0, 0, 0))
        else:
            img.putpixel([x,y],(255,255,255))
        i = i+1
img.show()
img.save("flag.png")

二维码的修复

有的时候,得到的二维码是不完整的,如果缺失的部分比较少,是可以直接扫出来的。

缺失部分比较多的时候就要考虑修复了,这里以bugku的Improve yourself为例,其中一步得到的二维码缺了三块定位符。
在这里插入图片描述
这里推荐一个在线网站,https://merricx.github.io/qrazybox/,进去的页面如下,蓝色箭头位置是二维码大小,根据实际情况进行修改。在这里插入图片描述
红色箭头位置也可以点击,这里根据实际情况对定位符的一些设置进行修改。
在这里插入图片描述
有的时候,题目给了一个图片文件,打开发现是只有上半部分的二维码,一般把图片高度改高就能得到完整的二维码。

Aztec Code

大概长这样
请添加图片描述
使用在线网站进行解码:https://products.aspose.app/barcode/recognize/aztec#result


先写这么多,想起来再补

原网站

版权声明
本文为[z.volcano]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_45696568/article/details/116082336