第一层: 文件头混乱
打开 winhex ,将文件拖入后发现:
set 0 1 2 3 4 5
0000 FF FF FF FF 27 1C发现27 1C的关键头文件标识,这与7z的头文件 37 7A BC AF 27 1C 相吻合
于是将其修改为
set 0 1 2 3 4 5
0000 37 7A BC AF 27 1C修改后得到了一个7z文件,解压后得到一个png文件 layer2.png
第二层:LSB隐写
打开kali,对文件layer2.png跑隐写检测:
Zsteg -a layer2.png运行命令后观察第四行:
b1,rgb,1sb,xy .. text:"flag.zip"发现存在一个名为flag.zip的文件,在次隧道 b1,rgb,lsb,xy 将其提取为bin文件:
Zsteg -E "b1,rgb,lsb,xy" layer2.png >111.bin第三层:crc加密
使用binwalk命令,看看目录下还有没有东西:
binwalk -e 111.bin可以发现有7个zip文件:
flag.zip,pass1.zip,pass2.zip.......pass6.zip并且每个zip文件都进行了加密
此时想到可能是crc碰撞题型,为了验证猜想,对pass.zip依次执行zipinfo -v命令:
zipinfo -v pass1.zip发现了以下信息:
32-bit CRC value(hex): ce70d424果然,就是四位crc加密,对六个pass.zip文件依次挖掘后,使用crc碰撞脚本还原出明文:
(该脚本由网上搜集,可以解决1-5字节的crc碰撞,非本人撰写)
# coding:utf-8
"""
Author:spaceman
"""
import binascii
import string
from time import sleep
def is_number(s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False
# 进度条
def progress(percent=0, width=40):
left = width * percent // 95
right = width - left
print ('\r[', '#' * left, ' ' * right, ']',f' {percent:.0f}%',sep='', end='', flush=True)
# 一位字节
def crc1(strs,dic):
strs = hex(int(strs,16))
rs = ''
for i in dic:
s = i
if hex(binascii.crc32(s.encode())) == strs:
rs += s
print (strs+' : '+s)
return rs
# 两位字节
def crc2(strs,dic):
strs = hex(int(strs,16))
rs = ''
for i in dic:
for j in dic:
s = i + j
if hex(binascii.crc32(s.encode())) == strs:
rs += s
print (strs+' : '+s)
return rs
# 三位字节
def crc3(strs,dic):
strs = hex(int(strs,16))
rs = ''
for i in dic:
for j in dic:
for k in dic:
s = i+j+k
if hex(binascii.crc32(s.encode())) == strs:
rs += s
print (strs+' : '+s)
return rs
# 四位字节
def crc4(strs,dic):
strs = hex(int(strs,16))
rs = ''
it = 1
for i in dic:
for j in dic:
for k in dic:
for m in dic:
s = i+j+k+m
if hex(binascii.crc32(s.encode())) == strs:
rs += s
print ()
print (strs+' : '+s)
print ('\n')
progress(it)
sleep(0.1)
it += 1
return rs
# 五位字节
def crc5(strs,dic):
strs = hex(int(strs,16))
rs = ''
it = 1
for i in dic:
progress(it)
for j in dic:
for k in dic:
for m in dic:
for n in dic:
s = i+j+k+m+n
if hex(binascii.crc32(s.encode())) == strs:
rs += s
print ()
print (strs+' : '+s)
print ('\n')
sleep(0.1)
it += 1
return rs
# 计算碰撞 crc
def CrackCrc(crclist,length):
print ()
print ("正在计算...")
print ()
dic = ''' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~''' # 碰撞需要的字符字典
dic = dic[::-1]
text = ''
for i in crclist:
if length == '1':
text += crc1(i,dic)
if length == '2':
text += crc2(i,dic)
if length == '3':
text += crc3(i,dic)
if length == '4':
text += crc4(i,dic)
if length == '5':
text += crc5(i,dic)
print ('\n')
if text == '':
print ("碰撞失败,无结果")
exit()
print ("字符顺序组合:",end=' ')
print ()
print (text)
print ()
input("回车确认结束程序...")
# 主函数
print ('''
##############################
###### Author:spaceman ######
### Thank you for your use ###
##############################
''')
listcrc = [] # 用于存储crc值
length = (input("请输入文本字节大小(1-5):")) # 即文本内容大小,如文本内容为flag,大小即为4
if is_number(length) == False or length not in ("1,2,3,4,5"):
exit("非指定数字,退出")
print ()
while 1:
crc = input('请输入crc值(例如:d1f4eb9a,输入n完成输入):')
if crc == 'n':
break
crc = '0x'+crc
if len(crc) != 10:
print ("rcr长度不对,请重新输入")
continue
listcrc.append(crc)
CrackCrc(listcrc,length)或者也可以用曾哥开源的crc碰撞程序 曾哥crc碰撞tool
最后得到明文: pass is c1!xxtLf%fXYPkaA
所以 flag.zip 的解压密码为 c1!xxtLf%fXYPkaA
第四层:零宽字符解码
对 flag.zip 解压后得到 flag.txt
注意:零宽字符在多数编辑器下不会直接显示,所以我们用linux的vim编辑器打开:
flag is here<200b><200c><200c><200b><200b>........<200c><200c><200b><200c>由于篇幅问题就不全写出了
这里的200b表示着0,200c表示1,flag用01去表示,大概率是 八位二进制 转 ascii
编写简单脚本:
import binascii
a='''<200b><200c><200c><200b><200b>...<200c><200c><200b><200c>'''
str=''
for i in a:
if i == 'b':
str += '0'
elif i == 'c':
str += '1'
print (str) 得到二进制字符串,可以手动编写脚本或者去在线网站直接解密为ascii,这里就不演示了
最后得到flag: dart{bf4100d9-cc8d-48f6-a095-54cbfad189e1}
评论 (0)