本文已参与「新人创作礼」活动,一起开启掘金创作之路
压缩包
zip
文件头,文件尾
50 4B 03 04,50 4B 05 06
伪加密
最简单的解伪加密的方式
binwalk -e + 压缩包
或者是看010editor伪加密的是deflag还是frflag
若发现其中是奇数则可能是伪加密。将其改为偶数就可。
真加密
爆破
有的时候考察爆破,常见的是数字爆破,也会有单纯字母的爆破。
使用工具:Advanced Archive Password Recovery
密码有时候不是通过爆破获得的,出题人可能以其他的形式隐写密码。
明文攻击
原理
- 一个加密的压缩文件
- 压缩文件的压缩工具,比如
2345好压,WinRAR,7z。zip版本号等,可以通过文件属性了解。如果是Linux平台,用zipinfo -v可以查看一个zip包的详细信息,包括加密算法等 - 知道压缩包里某个文件的部分连续内容 (至少
12字节)
如果你已经知道加密文件的部分内容,比如在某个网站上发现了它的 readme.txt 文件,你就可以开始尝试破解了。
首先,将这个明文文件打包成 zip 包,比如将 readme.txt 打包成 readme.zip 。
打包完成后,需要确认二者采用的压缩算法相同。一个简单的判断方法是用 WinRAR 打开文件,同一个文件压缩后的体积是否相同。如果相同,基本可以说明你用的压缩算法是正确的。如果不同,就尝试另一种压缩算法。
通过观察加密内容和伪加密内容的文件名以及CRC的值来判断是否为明文攻击
题目:[ACTF新生赛2020]明文攻击,xctf-warmup
掩码攻击
这种情况适用于知道密码中的某一位或者某一段
题目:buumisc_page3 [GUET-CTF2019]zips
通过爆破发现flag.zip被python的时间戳加密了
CRC32
原理
CRC 本身是「冗余校验码」的意思,CRC32 则表示会产生一个 32 bit ( 8 位十六进制数) 的校验值。由于 CRC32 产生校验值时源数据块的每一个 bit (位) 都参与了计算,所以数据块中即使只有一位发生了变化,也会得到不同的 CRC32 值。
CRC32 校验码出现在很多文件中比如 png 文件,同样 zip 中也有 CRC32 校验码。值得注意的是 zip 中的 CRC32 是未加密文件的校验值。
这也就导致了基于 CRC32 的攻击手法。
- 文件内内容很少 (一般比赛中大多为
4字节左右) - 加密的密码很长
我们不去爆破压缩包的密码,而是直接去爆破源文件的内容 (一般都是可见的字符串),从而获取想要的信息。
常见的crc题目是,压缩包里有多个加密的文件,且每个文件的大小都很小。
获取CRC
#author 末初
import zipfile
file_handler = zipfile.ZipFile('./password.zip')#指定压缩包
name_list = file_handler.namelist()#使用一个列表获取压缩包内所有的文件名
crc_list = []
print('-------------Filename CRC Info-------------')
for name in name_list:
name_info = file_handler.getinfo(name)
crc_list.append(hex(name_info.CRC))
print('[+] {0}: {1}'.format(name,hex(name_info.CRC)))
print('-------------------------------------------')
print(crc_list)#根据情况获取,有时并压缩包内可能还有其他文件,可能需要切片,所以择情况选取
注意获取到的CRC为例如['0x11111']这种形式,在用于爆破时要把引号删除
1bytes-crc爆破
#author by 末初
import binascii
import string
def crack_crc():
print('-------------Start Crack CRC-------------')
crc_list = [0xda6fd2a0, 0xf6a70, 0x70659eff, 0x862575d]#文件的CRC32值列表,注意顺序
comment = ''
chars = string.printable
for crc_value in crc_list:
for char1 in chars:
char_crc = binascii.crc32(char1.encode())#获取遍历字符的CRC32值
calc_crc = char_crc & 0xffffffff#将获取到的字符的CRC32值与0xffffffff进行与运算
if calc_crc == crc_value:#将每个字符的CRC32值与每个文件的CRC32值进行匹配
print('[+] {}: {}'.format(hex(crc_value),char1))
comment += char1
print('-----------CRC Crack Completed-----------')
print('Result: {}'.format(comment))
if __name__ == '__main__':
crack_crc()
2bytes-crc爆破
#author by 末初
import binascii
import string
def crack_crc():
print('-------------Start Crack CRC-------------')
crc_list = [0xef347b51, 0xa8f1b31e, 0x3c053787, 0xbbe0a1b]#文件的CRC32值列表,注意顺序
comment = ''
chars = string.printable
for crc_value in crc_list:
for char1 in chars:
for char2 in chars:
res_char = char1 + char2#获取遍历的任意2Byte字符
char_crc = binascii.crc32(res_char.encode())#获取遍历字符的CRC32值
calc_crc = char_crc & 0xffffffff#将获取到的字符的CRC32值与0xffffffff进行与运算
if calc_crc == crc_value:#将获取字符的CRC32值与每个文件的CRC32值进行匹配
print('[+] {}: {}'.format(hex(crc_value),res_char))
comment += res_char
print('-----------CRC Crack Completed-----------')
print('Result: {}'.format(comment))
if __name__ == '__main__':
crack_crc()
3bytes-crc爆破
##author by 末初
import binascii
import string
def crack_crc():
print('-------------Start Crack CRC-------------')
crc_list = [0x2b17958, 0xafa8f8df, 0xcc09984b, 0x242026cf]#文件的CRC32值列表,注意顺序
comment = ''
chars = string.printable
for crc_value in crc_list:
for char1 in chars:
for char2 in chars:
for char3 in chars:
res_char = char1 + char2 + char3#获取遍历的任意3Byte字符
char_crc = binascii.crc32(res_char.encode())#获取遍历字符的CRC32值
calc_crc = char_crc & 0xffffffff#将遍历的字符的CRC32值与0xffffffff进行与运算
if calc_crc == crc_value:#将获取字符的CRC32值与每个文件的CRC32值进行匹配
print('[+] {}: {}'.format(hex(crc_value),res_char))
comment += res_char
print('-----------CRC Crack Completed-----------')
print('Result: {}'.format(comment))
if __name__ == '__main__':
crack_crc()
4bytes-crc爆破
#author by 末初
import binascii
import string
def crack_crc():
print('-------------Start Crack CRC-------------')
crc_list = [0xc0a3a573, 0x3cb6ab1c, 0x85bb0ad4, 0xf4fde00b]#文件的CRC32值列表,注意顺序
comment = ''
chars = string.printable
for crc_value in crc_list:
for char1 in chars:
for char2 in chars:
for char3 in chars:
for char4 in chars:
res_char = char1 + char2 + char3 + char4#获取遍历的任意4Byte字符
char_crc = binascii.crc32(res_char.encode())#获取遍历字符的CRC32值
calc_crc = char_crc & 0xffffffff#将遍历的字符的CRC32值与0xffffffff进行与运算
if calc_crc == crc_value:#将获取字符的CRC32值与每个文件的CRC32值进行匹配
print('[+] {}: {}'.format(hex(crc_value),res_char))
comment += res_char
print('-----------CRC Crack Completed-----------')
print('Result: {}'.format(comment))
if __name__ == '__main__':
crack_crc()
4Byte的CRC32爆破推荐使用:github.com/theonlypwne…
spaceman师傅的脚本
# 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)
其他形式
rar
文件头,文件尾
52 61 72 21 1A 07 00
伪加密
rar4存在伪加密,ra5不存在伪加密
rar4的伪加密方法为,将箭头所指的名称的值改为1即可
真加密
爆破
rar4:Advanced Archive Password Recovery
rar5:hashcat
hashcat的使用