转载声明:

原文链接:https://g3rling.top/209
原作者:G3rling✌️
本文已获得原作者转载授权


“燃烧自己!这样,即使你化为灰烬,人们也会从火光中找到你……”

前言

初衷是记录Misc常见的题目类型以及相关工具的使用,也是对知识点的复习(会不定时更新)。最开始接触CTF的时候也是很多✌无私地分享才得以收集到这么多非常好用的工具和脚本(特别感谢MiniNK的师傅们以及其他开源的师傅们),所以在这里将我的知识成果也分享出来,希望自己能做一个有用的人帮助到大家。


图片隐写

Exif信息

1.右键属性查看

2.在线网站:EXIF信息查看器 (tuchong.com)

Exif信息可能会含有存储图片拍摄设备,生成软件,拍摄地点等相关信息。


图片宽高

1.PNG和BMP图片可以用PuzzleSolver——ImageTools进行爆破

2.JPG图片需要进行手动在010editor中修改,修改位置如下:

image-20240326220516376


盲水印

1.单图:PuzzleSolver——FFT——FFT/Java

2.双图:PuzzleSolver——FFT——bwn/频域

3.可能会用到PhotoShop


LSB隐写

1.Stegslove(详细使用方法见工具食用说明)

2.zsteg


图像缩放攻击

特征:图片中有等距像素点阵

image-20240331135314899

1.PS——图像大小——邻近法(九合一)

2.提取图像间隔像素脚本(因为是从MiniNK收集到的脚本,不清楚是否能开源)


IDAT及其他块隐写

1.ImageGlass可得知是否存在数据块错误

2.PNG Debugger进行CRC检验

3.tweakpng对数据块进行修改


其他隐写

图像类型 隐写工具
PNG cloacked-pixel, stegpy, PixelJihad, OurSecret, DeEgger Embedder
JPG/JPEG SilentEye, steghide, outguess, jphide, F5-steganography, JSteg, Free File Camouflage, DeEgger Embedder, OurSecret
BMP SilentEye, wbStego4, steghide
PNM outguess

字体加粗的都是没有密码的工具,大部分都可以设置密码,也可以不设置密码,看出题人


音频隐写

音频类型 隐写工具
WAV SilentEye, steghide, stegpy, DeEgger Embedder, DeepSound, MP3Stego
MP3 DeepSound, MP3Stego
AU steghide
FLAC DeepSound
APE DeepSound

字体加粗的都是没有密码的工具,大部分都可以设置密码,也可以不设置密码,看出题人


压缩包

伪加密

1.7-zip (经测试7-zip可以直接解压两种伪加密的压缩包)

2.ZipCenOp修复

3.手动修复

在修复之前我们需要知道zip压缩包的文件结构,一个 ZIP 文件由三个部分组成:

压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志

而伪加密中我们需要注意压缩源文件数据区的全局加密和压缩源文件目录区的全局方式位标记

压缩源文件数据区:50 4B 03 04 14 00 00 00

压缩源文件目录区:50 4B 01 02 3F 00 00 00

无加密 压缩源文件数据区的全局加密与压缩源文件目录区的全局方式位标记均为00 00
假加密 1.压缩源文件数据区的全局加密与压缩源文件目录区的全局方式位标记一个为00 00 一个为09 00
2.压缩源文件数据区的全局加密与压缩源文件目录区的全局方式位标记均为09 00
真加密 压缩源文件数据区的全局加密与压缩源文件目录区的全局方式位标记均为09 00

注意:00 00可以由02 00等偶数等效替代,同理09 00也可以由01 00等奇数等效替代


暴力破解

枚举爆破

使用工具:ARCHPR

注意枚举范围以及长度的设置(一般先用数字再用大小写字母,长度1-8)

CRC碰撞

特征:压缩包内文件大小均为相同字节(1bytes,2bytes,3bytes,4bytes)


字典攻击

1.根据题目生成字典

2.遍历常用字典进行爆破


掩码攻击

不确定位为英文?

明文攻击

1.ARCHPR

2.bkcrack

攻击需要至少 12 字节的已知明文。 其中至少 8 个必须是连续的。 连续的已知明文越大,攻击速度越快。

这里需要注意的是,明文爆破其实并不是一定需要CRC检验值完全一样,满足上述条件即可


取证

Office相关隐写

工具食用说明

Stegslove

image-20240330210447662

常用于LSB隐写,常用功能如下:

1.File Format(文件格式)

image-20240330210809981

能获取图片的具体信息

2.Data Extract(数据提取)

image-20240331010423873

3. Steregram Solve(立体试图)

控制图片左右偏移

image-20240331011905357

4.Frame Browser(帧浏览器)

对GIF之类的动图进行分解

5.Image Combiner(图片拼接)

根据需求调整模式

image-20240331012057429


zsteg

zsteg xxx.png
zsteg -a xxx.png							#查看各个通道的lsb
zsteg -e b8,a,lsb,xy xxx.png -> out.png		#提取该通道图片

montage+gaps

图片拼接:

示例: 
montage 1.png -tile 8X6 -geometry +0+0 flag.png

#tile 长宽数量
#geometry 拼图间隙

图片排序:

示例: 
gaps run flag.png newfalg.png --generations=9999 --population=300 --size=100

#generations 遗传算法的代的数量
#population 个体数量
#size 拼图块的像素尺寸 <------IMPORTANT------> 

ImageGlass

图片查看工具,可以初步判断数据异常

image-20240331143313131

如上图可以发现是IEND块异常,从IEND块入手。


PNG Debugger

检测各数据块(IHDR、IDAT、IEND)中的 CRC 是否正确

pngdebugger 图片路径			#CRC检验并回显
pngdebugger --verbose 图片路径	#查看数据块详细信息
pngdebugger 图片路径 > 1.txt	#保存输出信息

tweakpng

查看数据块异常以及应该修改的值

image-20240331143903554

image-20240331143925238


cloacked-pixel

已整合在PuzzleSolver——BruteForce中,可直接使用

image-20240331144745560


stegpy

已整合在PuzzleSolver——BruteForce中,可直接使用

image-20240331144827827


PixelJihad

在线网站:PixelJihad (sekao.net)


OurSecret

此隐写的特征JPG与PNG同理,在文件层结束后出现 ž—º *(9E 97 BA 2A)

image-20240331152320942

提示与*“我们的秘密”*有关


DeEgger Embedder

无隐写特征(可能),可不需要密码

提示与*“嵌入”*有关


SilentEye

无隐写特征(可能)

提示与*“眼睛”*有关


steghide+stegbreak/stegseek

已知密码:

steghide extract -sf 1.jpg -p 123456

#-sf  参数
#test.jpg  图片名称
#-p 密码参数,后面空格跟密码,无密码可不加参数,回车就好

密码爆破:

stegbreak.exe -r rules.ini -f rockyou.txt -t p 图片名
stegseek 1.jpg rockyou.txt

outguess

outguess -k “secret key” -r 1.jpg flag.txt

#secret key	密码
#1.jpg		隐藏信息的图片载体
#flag,txt	隐藏的文字信息

jphide

可视化解密工具

image-20240331155159331


ZipCenOp

java -jar ZipCenOp.jar r xxx.zip

bkcrack

Key爆破:

bkcrack -C 1.zip -c 1.txt -p 2.txt

#-C 加密ZIP文件名
#-c ZIP文件中已知的加密文件名
#-p 已知的明文文件名
#-k 已知明文在加密文件中的偏移量
#如果没有偏移量信息,可以尝试自动找到正确的偏移量,但这通常需要明文文件和加密文件有足够长的相同内容。

修改压缩包密码:

bkcrack -C 1.zip -k 7163444a 203b76b0 17de1387 -U ./2.zip 123

#-C 加密ZIP文件名
#-k Key值
#-U	新压缩包及密码

密码爆破(不推荐):

bkcrack -k 7163444a 203b76b0 17de1387 -r 16 \?a

#-k Key值
#-r	<Length>密码的最大长度		<charset>密码可能会使用的字符集
?1:小写字母 (a-z)
?u:大写字母(A-Z)
?d:十进制数字(0-9)
?s:标点符号
?a: 字母数字字符,即小写字母、大写字母和数字的组合 (相当于 ?1?u?d)
?p:可打印字符,包括字母数字字符和标点符号 (相当于 ?a?s)
?b:所有字节 (0x00-0xff)

相关脚本

CRC碰撞

python CRC-Tools.py -bytes 1.zip

#-bytes		1-4	只支持1-4Byte的压缩包CRC碰撞
#1.zip		压缩包路径
import zipfile
import argparse
import string
import binascii
import io, sys

def FileRead(zipname):
    try:
        f =open(zipname)                               #打开目标文件
        f.close()
    except FileNotFoundError:
        print ("未找到同目录下的压缩包文件" + zipname) #如果未找到文件,输出错误
        return                                         #退出线程,进行详细报错
    except PermissionError:
        print ("无法读取目标压缩包(无权限访问)")     #如果发现目标文件无权限,输出错误
        return                                         #退出线程,进行详细报错

def ReadCRC(zipname):
    zip_url = "./" + zipname
    file_zip = zipfile.ZipFile(zip_url) #用zipfile读取指定的压缩包文件
    name_list = file_zip.namelist()     #使用一个列表,获取并存储压缩包内所有的文件名
    crc_list = []
    print('+--------------遍历指定压缩包的CRC值----------------+')
    for name in name_list:
        name_message = file_zip.getinfo(name)
        crc_list.append(hex(name_message.CRC))
        print('[OK] {0}: {1}'.format(name,hex(name_message.CRC)))
    print('+---------------------------------------------------+')
    crc32_list = str(crc_list)
    crc32_list = crc32_list.replace('\'' , '')
    print("读取成功,导出CRC列表为:" + crc32_list) #导出CRC列表后,导入其他脚本进行CRC碰撞
    
def OneByte(zipname):
    zip_url = "./" + zipname
    file_zip = zipfile.ZipFile(zip_url)    #用zipfile读取指定的压缩包文件
    name_list = file_zip.namelist()        #使用一个列表,获取并存储压缩包内所有的文件名
    crc_list = []
    crc32_list = []
    print('+--------------遍历指定压缩包的CRC值----------------+')
    for name in name_list:
        name_message = file_zip.getinfo(name)
        crc_list.append(name_message.CRC)
        crc32_list.append(hex(name_message.CRC))
        print('[OK] {0}: {1}'.format(name,hex(name_message.CRC)))
    print('+-------------对输出的CRC值进行碰撞-----------------+')
    comment = ''
    chars = string.printable
    for crc_value in crc_list:
        for char1 in chars:                              #获取任意1Byte字符
            thicken_crc = binascii.crc32(char1.encode()) #获取任意1Byte字符串的CRC32值
            calc_crc = thicken_crc & 0xffffffff          #将任意1Byte字符串的CRC32值与0xffffffff进行与运算
            if calc_crc  crc_value:                    #匹配两个CRC32值
                print('[Success] {}: {}'.format(hex(crc_value),char1))
                comment += char1
    print('+-----------------CRC碰撞结束!!!-----------------+')
    crc32_list = str(crc32_list)
    crc32_list = crc32_list.replace('\'' , '')
    print("读取成功,导出CRC列表为:" + crc32_list)                     #导出CRC列表
    if comment:
        print('CRC碰撞成功,结果为: {}'.format(comment))                  #输出CRC碰撞结果
    else:
        print('CRC碰撞没有结果,请检查压缩包内文件是否为1Byte!!!')

def TwoByte(zipname):
    zip_url = "./" + zipname
    file_zip = zipfile.ZipFile(zip_url)    #用zipfile读取指定的压缩包文件
    name_list = file_zip.namelist()        #使用一个列表,获取并存储压缩包内所有的文件名
    crc_list = []
    crc32_list = []
    print('+--------------遍历指定压缩包的CRC值----------------+')
    for name in name_list:
        name_message = file_zip.getinfo(name)
        crc_list.append(name_message.CRC)
        crc32_list.append(hex(name_message.CRC))
        print('[OK] {0}: {1}'.format(name,hex(name_message.CRC)))
    print('+-------------对输出的CRC值进行碰撞-----------------+')
    comment = ''
    chars = string.printable
    for crc_value in crc_list:
        for char1 in chars:
            for char2 in chars:
                res_char = char1 + char2                        #获取任意2Byte字符
                thicken_crc = binascii.crc32(res_char.encode()) #获取任意2Byte字符串的CRC32值
                calc_crc = thicken_crc & 0xffffffff             #将任意2Byte字符串的CRC32值与0xffffffff进行与运算
                if calc_crc  crc_value:                       #匹配两个CRC32值
                    print('[Success] {}: {}'.format(hex(crc_value),res_char))
                    comment += res_char
    print('+-----------------CRC碰撞结束!!!-----------------+')
    crc32_list = str(crc32_list)
    crc32_list = crc32_list.replace('\'' , '')
    print("读取成功,导出CRC列表为:" + crc32_list)                     #导出CRC列表
    if comment:
        print('CRC碰撞成功,结果为: {}'.format(comment))                  #输出CRC碰撞结果
    else:
        print('CRC碰撞没有结果,请检查压缩包内文件是否为2Byte!!!')

def ThreeByte(zipname):
    zip_url = "./" + zipname
    file_zip = zipfile.ZipFile(zip_url)    #用zipfile读取指定的压缩包文件
    name_list = file_zip.namelist()        #使用一个列表,获取并存储压缩包内所有的文件名
    crc_list = []
    crc32_list = []
    print('+--------------遍历指定压缩包的CRC值----------------+')
    for name in name_list:
        name_message = file_zip.getinfo(name)
        crc_list.append(name_message.CRC)
        crc32_list.append(hex(name_message.CRC))
        print('[OK] {0}: {1}'.format(name,hex(name_message.CRC)))
    print('+-------------对输出的CRC值进行碰撞-----------------+')
    comment = ''
    chars = string.printable
    result_dict={}
    for char1 in chars:
        for char2 in chars:
            for char3 in chars:
                res_char = char1 + char2 + char3                #获取任意3Byte字符
                thicken_crc = binascii.crc32(res_char.encode()) #获取任意3Byte字符串的CRC32值
                calc_crc = thicken_crc & 0xffffffff             #将任意3Byte字符串的CRC32值与0xffffffff进行与运算
                for crc_value in crc_list:
                    if calc_crc  crc_value:                       #匹配两个CRC32值
                        index = crc32_list.index(hex(crc_value))
                        num = int(index)
                        new_data = {num : res_char}
                        print('[Success] 第 {} 个文件 {}: {}'.format(num,hex(crc_value),res_char))
                        result_dict.update(new_data)
                        break
    sorted_items = sorted(result_dict.items())
    for key, res_char in sorted_items:
        comment += res_char
    print('+-----------------CRC碰撞结束!!!-----------------+')
    crc32_list = str(crc32_list)
    crc32_list = crc32_list.replace('\'' , '')
    print("读取成功,导出CRC列表为:" + crc32_list)                     #导出CRC列表
    if comment:
        print('CRC碰撞成功,结果为: {}'.format(comment))                  #输出CRC碰撞结果
    else:
        print('CRC碰撞没有结果,请检查压缩包内文件是否为3Byte!!!')

def FourByte(zipname):
    zip_url = "./" + zipname
    file_zip = zipfile.ZipFile(zip_url)    #用zipfile读取指定的压缩包文件
    name_list = file_zip.namelist()        #使用一个列表,获取并存储压缩包内所有的文件名
    crc_list = []
    crc32_list = []
    print('+--------------遍历指定压缩包的CRC值----------------+')
    for name in name_list:
        name_message = file_zip.getinfo(name)
        crc_list.append(name_message.CRC)
        crc32_list.append(hex(name_message.CRC))
        print('[OK] {0}: {1}'.format(name,hex(name_message.CRC)))
    print('+-------------对输出的CRC值进行碰撞-----------------+')
    comment = ''
    chars = string.printable
    result_dict={}
    for char1 in chars:
        for char2 in chars:
            for char3 in chars:
                for char4 in chars:
                    res_char = char1 + char2 + char3 + char4        #获取任意4Byte字符
                    thicken_crc = binascii.crc32(res_char.encode()) #获取任意4Byte字符串的CRC32值
                    calc_crc = thicken_crc & 0xffffffff             #将任意4Byte字符串的CRC32值与0xffffffff进行与运算
                    for crc_value in crc_list:
                        if calc_crc  crc_value:                       #匹配两个CRC32值
                            index = crc32_list.index(hex(crc_value))
                            num = int(index)
                            new_data = {num : res_char}
                            print('[Success] 第 {} 个文件 {}: {}'.format(num,hex(crc_value),res_char))
                            result_dict.update(new_data)
                            break
    sorted_items = sorted(result_dict.items())
    for key, res_char in sorted_items:
        comment += res_char
    print('+-----------------CRC碰撞结束!!!-----------------+')
    crc32_list = str(crc32_list)
    crc32_list = crc32_list.replace('\'' , '')
    print("读取成功,导出CRC列表为:" + crc32_list)                     #导出CRC列表
    if comment:
        print('CRC碰撞成功,结果为: {}'.format(comment))                  #输出CRC碰撞结果
    else:
        print('CRC碰撞没有结果,请检查压缩包内文件是否为4Byte!!!')

if __name__  '__main__':
    title()
    parser = argparse.ArgumentParser(description="CRC-Tools V2.2", epilog='根据压缩包内容选择不同参数,诸如:python3 CRC-Tools.py -4 4Byte-Demo.zip 目前只支持1-4Byte的压缩包CRC碰撞')
    #parser = argparse.ArgumentParser(prog="CRC32-Tools", usage="开源项目[%(prog)s] 实现了如下功能:")
    parser.add_argument('-z', action='store', dest='readzip', help='读取对应压缩包,输出各个文件CRC值列表')
    parser.add_argument('-1', action='store', dest='onebyte', help='对1Byte的压缩包自动进行CRC碰撞并输出文件内容')
    parser.add_argument('-2', action='store', dest='twobyte', help='对2Byte的压缩包自动进行CRC碰撞并输出文件内容')
    parser.add_argument('-3', action='store', dest='threebyte', help='对3Byte的压缩包自动进行CRC碰撞并输出文件内容')
    parser.add_argument('-4', action='store', dest='fourbyte', help='对4Byte的压缩包自动进行CRC碰撞并输出文件内容')
    args = parser.parse_args()
    try:
        if args.readzip:
            FileRead(args.readzip)
            ReadCRC(args.readzip)
        if args.onebyte:
            FileRead(args.onebyte)
            OneByte(args.onebyte)
        if args.twobyte:
            FileRead(args.twobyte)
            TwoByte(args.twobyte)
        if args.threebyte:
            FileRead(args.threebyte)
            ThreeByte(args.threebyte)
        if args.fourbyte:
            FileRead(args.fourbyte)
            FourByte(args.fourbyte)
    except KeyboardInterrupt:
        print("Ctrl + C 手动终止了进程")
        sys.exit()
    except BaseException as e:
        err = str(e)
        print('脚本详细报错:' + err)
        sys.exit(0)

base64自定义解码

#s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

s = ""

def My_base64_decode(inputs):
	# 将字符串转化为2进制
	bin_str = []
	for i in inputs:
		if i != '=':
			x = str(bin(s.index(i))).replace('0b', '')
			bin_str.append('{:0>6}'.format(x))
	#print(bin_str)
	# 输出的字符串
	outputs = ""
	nums = inputs.count('=')
	while bin_str:
		temp_list = bin_str[:4]
		temp_str = "".join(temp_list)
		#print(temp_str)
		# 补足8位字节
		if(len(temp_str) % 8 != 0):
			temp_str = temp_str[0:-1 * nums * 2]
		# 将四个6字节的二进制转换为三个字符
		for i in range(0,int(len(temp_str) / 8)):
			outputs += chr(int(temp_str[i*8:(i+1)*8],2))
		bin_str = bin_str[4:]	
	print("Decrypted String:\n%s "%outputs)
	

input_str = input("Please enter a string that needs to be decrypted: \n")
My_base64_decode(input_str)

base64循环解码

import base64

def base64_auto(s):   
    for i in range(1,99999):
        print("Time ",i,":")
        decode_str = base64.decodebytes(bytes(s, encoding='utf8') )
        result=decode_str.decode()
        print(result)
        s=result#把result赋值给s,用于下一次的解码

s=""
base64_auto(s)  

网站的管理员,似乎是个萌新🤔,CTBUer