浅谈使用Python脚本爆破CRC32


CRC(Cyclic Redundancy Check)校验实用程序库在数据存储和数据通讯领域,为了保证数据的正确,就不得不采用检错的手段。在诸多检错手段中,CRC是最著名的一种。CRC的全称是循环冗余校验

每个文件都有唯一的CRC32值,即便数据发生很微小的变化,都会导致CRC32的值变化。假设知道段数据的长度和CRC32值,那么便可穷举数据,与其CRC32的值比较匹配,这样就可以达到暴力破解的目的。但是这么做缺点也很明显,就是只适用于数据内容较小的文件

注意:一般数据内容小于5Bytes(<=4Bytes)即可尝试通过爆破CRC32穷举数据内容


获取文件的CRC值

因为压缩包软件显示的文件CRC值不可复制,所以手抄比较麻烦,而且容易出错,所以使用脚本和获取比较方便

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_list = [0xef347b51, 0xa8f1b31e, 0x3c053787, 0xbbe0a1b]

内容为1Byte的CRC爆破

首先我们先构造一个zip压缩包,里面存放四个大小为1Byte的文件
在这里插入图片描述
4个1Byte文件内容如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编写脚本,开始爆破

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()

在这里插入图片描述
可以看到通过爆破CRC我们成功获取到了文件的内容

内容为2Byte的CRC爆破

与前面同样的条件,只是增加了文件内容,大小变为2Byte的文件
在这里插入图片描述
4个2Byte文件内容如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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()

在这里插入图片描述

内容为3Byte的CRC爆破

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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()

在这里插入图片描述

内容为4Byte的CRC爆破

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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的内容的CRC跟前面的相比已经非常耗时间了(174.025s),当然也只是当前脚本的爆破的方式太简单了,导致耗时间

所以4Byte-6Byte的CRC32爆破推荐使用:https://github.com/theonlypwner/crc32

PS D:\Tools\Misc\crc32> python .\crc32.py reverse 0xc0a3a573
4 bytes: {0x54, 0x39, 0x5e, 0x6e}
verification checksum: 0xc0a3a573 (OK)
alternative: DgQUDh (OK)
alternative: JhNexf (OK)
alternative: cqeRUF (OK)
alternative: p1gRfQ (OK)
alternative: t5zSg2 (OK)
alternative: uYHOxo (OK)
PS D:\Tools\Misc\crc32> php -r "var_dump(hex2bin('54395e6e'));"
Command line code:1:
string(4) "T9^n"
PS D:\Tools\Misc\crc32> python .\crc32.py reverse 0x3cb6ab1c
4 bytes: {0x6d, 0x50, 0x33, 0x21}
verification checksum: 0x3cb6ab1c (OK)
alternative: 0CKdyP (OK)
alternative: 22cGME (OK)
alternative: 4GVex3 (OK)
alternative: 6FB7Iv (OK)
alternative: 9USjou (OK)
alternative: A2Vm_A (OK)
alternative: EZ8AZf (OK)
alternative: GGcOj7 (OK)
alternative: PNQs5K (OK)
alternative: RrTmlV (OK)
alternative: VvIlm5 (OK)
alternative: YeX1K6 (OK)
alternative: cLMwPQ (OK)
alternative: dUJIzz (OK)
alternative: gHPvQ2 (OK)
alternative: i7s7hl (OK)
alternative: jZUyFt (OK)
alternative: mCRGl_ (OK)
alternative: o2zdXJ (OK)
alternative: vyzUV0 (OK)
PS D:\Tools\Misc\crc32> php -r "var_dump(hex2bin('6d503321'));"
Command line code:1:
string(4) "mP3!"
PS D:\Tools\Misc\crc32> python .\crc32.py reverse 0x85bb0ad4
4 bytes: {0x23, 0x55, 0x67, 0x35}
verification checksum: 0x85bb0ad4 (OK)
alternative: 4fFpEk (OK)
alternative: Ff2kLv (OK)
alternative: GfsZWo (OK)
alternative: Iiljka (OK)
alternative: NpkTAJ (OK)
alternative: RnU49V (OK)
alternative: VWYyPm (OK)
alternative: VjH585 (OK)
alternative: XXFIlc (OK)
alternative: _AAwFH (OK)
alternative: e96P13 (OK)
alternative: if_SPd (OK)
alternative: xWupWf (OK)
PS D:\Tools\Misc\crc32> php -r "var_dump(hex2bin('23556735'));"
Command line code:1:
string(4) "#Ug5"
PS D:\Tools\Misc\crc32> python .\crc32.py reverse 0xf4fde00b
4 bytes: {0x77, 0x32, 0x58, 0x40}
verification checksum: 0xf4fde00b (OK)
alternative: 7gGtPB (OK)
alternative: 9hXDlL (OK)
alternative: Eg3oY_ (OK)
alternative: MqjPTc (OK)
alternative: RO_Coo (OK)
alternative: bmH4Ie (OK)
alternative: cqFYSh (OK)
alternative: dhAgyC (OK)
alternative: zV5EYV (OK)
PS D:\Tools\Misc\crc32> php -r "var_dump(hex2bin('77325840'));"
Command line code:1:
string(4) "w2X@"
PS D:\Tools\Misc\crc32>

字节数量更多的爆破

这里只是讲笔者在CTF题目中碰到的一种情况,需要爆破的内容字节数>4Byte,但题目就是通过爆破CRC来猜测文件内容。一般碰到这种情况,只有一种可能能使用CRC爆破文件内容,那就是文件内容的字符范围不大,例如内容是全数字或者特定的一些字符范围。因为上述我们的爆破字符范围非常大(所有可打印字符),所以通过上述这种脚本的爆破方式,4Byte已经是极限了。但是如果知道文件内容的字符范围或猜测文件内容字符范围不大,即可爆破字节数更多的内容。

  • 15
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末 初

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值