misc总结之压缩包篇

789 阅读7分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

压缩包

zip

文件头,文件尾

50 4B 03 04,50 4B 05 06

伪加密

最简单的解伪加密的方式

binwalk -e + 压缩包

或者是看010editor伪加密的是deflag还是frflag

若发现其中是奇数则可能是伪加密。将其改为偶数就可。

真加密

爆破

有的时候考察爆破,常见的是数字爆破,也会有单纯字母的爆破。

使用工具:Advanced Archive Password Recovery

密码有时候不是通过爆破获得的,出题人可能以其他的形式隐写密码。

明文攻击
原理
  • 一个加密的压缩文件
  • 压缩文件的压缩工具,比如 2345 好压, WinRAR7zzip 版本号等,可以通过文件属性了解。如果是 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的使用

其他形式

7z