转载声明:
原文链接:https://g3rling.top/209
原作者:G3rling✌️
本文已获得原作者转载授权
“燃烧自己!这样,即使你化为灰烬,人们也会从火光中找到你……”
前言
初衷是记录Misc常见的题目类型以及相关工具的使用,也是对知识点的复习(会不定时更新)。最开始接触CTF的时候也是很多✌无私地分享才得以收集到这么多非常好用的工具和脚本(特别感谢MiniNK的师傅们以及其他开源的师傅们),所以在这里将我的知识成果也分享出来,希望自己能做一个有用的人帮助到大家。
图片隐写
Exif信息
1.右键属性查看
2.在线网站:EXIF信息查看器 (tuchong.com)
Exif信息可能会含有存储图片拍摄设备,生成软件,拍摄地点等相关信息。
图片宽高
1.PNG和BMP图片可以用PuzzleSolver——ImageTools进行爆破
2.JPG图片需要进行手动在010editor中修改,修改位置如下:
盲水印
1.单图:PuzzleSolver——FFT——FFT/Java
2.双图:PuzzleSolver——FFT——bwn/频域
3.可能会用到PhotoShop
LSB隐写
1.Stegslove(详细使用方法见工具食用说明)
2.zsteg
图像缩放攻击
特征:图片中有等距像素点阵
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
常用于LSB隐写,常用功能如下:
1.File Format(文件格式)
能获取图片的具体信息
2.Data Extract(数据提取)
3. Steregram Solve(立体试图)
控制图片左右偏移
4.Frame Browser(帧浏览器)
对GIF之类的动图进行分解
5.Image Combiner(图片拼接)
根据需求调整模式
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
图片查看工具,可以初步判断数据异常
如上图可以发现是IEND块异常,从IEND块入手。
PNG Debugger
检测各数据块(IHDR、IDAT、IEND)中的 CRC 是否正确
pngdebugger 图片路径 #CRC检验并回显
pngdebugger --verbose 图片路径 #查看数据块详细信息
pngdebugger 图片路径 > 1.txt #保存输出信息
tweakpng
查看数据块异常以及应该修改的值
cloacked-pixel
已整合在PuzzleSolver——BruteForce中,可直接使用
stegpy
已整合在PuzzleSolver——BruteForce中,可直接使用
PixelJihad
OurSecret
此隐写的特征JPG与PNG同理,在文件层结束后出现 ž—º *(9E 97 BA 2A)
提示与*“我们的秘密”*有关
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
可视化解密工具
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)