ctf misc 图片题知识点

过几天有比赛了,总结一下自己遇到过的知识点,争取能把签到题做出来

图片隐写

  • 常规思路
    • 图片名及图片内容
    • exif信息
    • 修改图片宽高
      • png
      • jpg
      • gif
      • bmp
      • 爆破脚本
    • 查看文件的字节
      • 分析文件头文件尾
      • 看看字节流中有没有隐藏信息
    • 使用stegsolve
      • lsb隐写
      • 有密码的lsb隐写
  • 工具隐写
    • SilentEye
    • OurSecret
    • jpg
      • Jphswin.exe
      • Free_File_Camouflage
      • f5-steganography (F5隐写,需要passwd)
      • outguess (可需要passwd)
      • steghide
    • png & bmp
      • 普通盲水印
      • 频域盲水印
      • JAVA盲水印
      • zsteg(lsb隐写)
      • PNGDebugger.exe(检查IDAT块)
      • tweakpng.exe

常规思路

图片名及图片内容

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

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

exif信息

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

拿其中的misc20为例,直接右键查看属性,翻看详细信息,得不到任何线索,推荐使用一个在线查看exif信息的网站,这里能得到的结果更详细,也可以使用exiftool
ctf misc 图片题知识点_第2张图片

修改图片宽高

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

这里推荐使用010editor,它的模板功能非常好用,我是010editor+winhex配合使用的。
ctf misc 图片题知识点_第3张图片

png

png图片修改宽高还是很容易的,这里是png.bt模板,框中的值分别是宽高crc值,这里修改之后保存即可
ctf misc 图片题知识点_第4张图片
对于png,一般情况下,是把高度改大,看下面有没有内容
ctf misc 图片题知识点_第5张图片

jpg

运用jpg.bt,可以很方便修改jpg的宽高
ctf misc 图片题知识点_第6张图片
对于jpg,一般情况下也是把高度改大,能看到图片下面的内容

gif

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

bmp

借助bmp.bt,整体和前面差不多,当宽度错误时,图片显示很乱
ctf misc 图片题知识点_第7张图片
问题就是如何计算正确的宽度和高度,以ctfshow-misc入门的misc24为例,ctf misc 图片题知识点_第8张图片
目前是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了
ctf misc 图片题知识点_第9张图片
也有可能不是直接给到的,需要进行进一步的处理
ctf misc 图片题知识点_第10张图片

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

使用stegsolve

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

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

如果是gif图片,可以使用frame browser查看所有帧
ctf misc 图片题知识点_第11张图片

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

lsb隐写

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

使用stegsolve的data extract,选上对应的通道(比较常见的是如下配置),就可以得到隐藏的信息
ctf misc 图片题知识点_第12张图片

有密码的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>

工具隐写

SilentEye

打开图片后点decode进行解密
ctf misc 图片题知识点_第13张图片
可以注意到有bmp和jpg两种,如果有密码,勾选encrypteddata输入密码再解密即可
ctf misc 图片题知识点_第14张图片

OurSecret

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

也是windows下的软件,界面如下
ctf misc 图片题知识点_第15张图片
使用也很简单,在右侧(UNHIDE)打开文件,输入密码,再点击UNHIDE就行

jpg

Jphswin.exe

我用的是windows版本的,界面如下
ctf misc 图片题知识点_第16张图片
使用起来也很简单,点击open jpeg打开图片,然后点击seek,如果有密码就输入密码,没有就直接回车
ctf misc 图片题知识点_第17张图片

Free_File_Camouflage

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

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

ctf misc 图片题知识点_第18张图片

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
具体安装过程自行百度

使用:

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

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

频域盲水印

脚本:

# 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互换位置试一下

JAVA盲水印

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

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

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就不建议用这个软件打开


先写这么多,想起来再补

你可能感兴趣的:(misc)