网站首页 > 技术文章 正文
CRC全称为Cyclic redundancy check,即循环冗余校验码,是一种根据输入数据产生简短的固定位数校验码的散列函数。CRC主要用来检测或者校验数据经过传输或者保存后可能出现的错误,CRC32产生32位的散列值(即4字节)。CRC32可以用于数据的校验,在WinRAR等压缩软件中也使用了这一技术,压缩包中每个文件都保存有一个对应的CRC32值,这个值是对压缩前的文件数据计算出来的散列值,在进行解压时会再次计算文件的CRC32值来进行对比,判断压缩包文件是否损坏。尽管CRC32在错误检测中非常有用,但是并不能可靠地校验数据完整性(即数据没有发生任何变化),这是因为CRC多项式是线性结构,可以非常容易地故意改变数据而维持CRC不变,即存在产生碰撞的可能性。
本次实验地址:
https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182015011915463900001&pk_campaign=toutiao-wemedia
先来看一下题目,在实验主机上的C:\Crypto\2目录下的flag.zip为本题所提供的文件,请对flag.zip文件进行分析,提取出压缩包中7个txt文件的内容,然后找出Flag字符串。
这个题目意在考察选手对CRC32的了解,以及通过CRC32枚举来还原压缩包文件内容的方法。
实验步骤一、思路分析
打开flag.zip压缩包文件,发现里面有7个txt文件,但是压缩包经过加密了,所以无法直接对其进行解压操作。题目除了这个压缩包之外没有提供任何提示,使用十六进制编辑器查看flag.zip文件似乎也找不到可疑的信息,那么可行的方法似乎就只有一个了,那就是对密码进行暴力破解操作。
暴力破解无非是使用可能的密码尝试进行解压操作,可行的方法有两种:
\1. 通过密码字典收集的常用密码进行破解;
\2. 通过穷举可能的密码进行破解;
对于第一种方式而言,如果机器性能足够好,几千万的密码字典可以很快就跑完;对于第二种方式而言,穷举的空间是非常大的,因为RAR压缩文件密码的最大长度为127个字符,而且不局限于英文字符,因此完全的暴力破解是不可能的。
密码破解并不是本题的出题初衷,这里将介绍一种基于CRC32来还原压缩包内容的方法。观察flag.zip在WinRar中的显示信息,如下图所示:
在WinRAR下方的列表视图中,最后一列是CRC32值,这个值代表的是对应的文件在压缩之前的内容计算出来的CRC32散列值,考虑到这里每个txt文件原始的大小只有4个字节,因此我们可以尝试枚举可能的4字节内容,然后计算CRC32值来进行校验。4字节的枚举空间并不是无法接受,因此可以尝试这样的操作。
这样我们就完成了第一个步骤,接下来开始实验步骤二、CRC32计算
为了快速方便的还原压缩包的内容,我们需要编程来计算CRC32的值。计算CRC32可以有多种方法,可以从网上找一个实现好的C/C++源文件,也可以使用Python提供的库函数来进行计算,这里我们选择后者。
Python的binascii模块提供了一个crc32方法,可以方便的计算所给参数的CRC32值。但是这里的计算结果有一点问题,因为计算出来的结果是一个有符号数,所以可能会看到结果为负数,因此需要将结果和0xFFFFFFFF进行一个位运算与操作。Python计算CRC32的代码如下:
import binascii
def calcCRC32(s):
crc = binascii.crc32(s)
return crc & 0xFFFFFFFF
需要注意的是,前面提到CRC32会存在冲突的可能,也就是说,不同的内容在经过计算后得到的CRC32散列值可能是一样的。
这都是出题人布置的陷阱,你自己做实验的时候要注意,最后一步,实验步骤三、使用脚本进行快速破解
经过前面的分析,我们已经知道了可以通过CRC32来还原压缩包中的4字节文本,以及通过Python计算CRC32的方法,现在只需要给Python脚本添加枚举功能即可,代码如下:
#!/usr/bin/env python
# -- coding:utf-8 --
import datetime
import binascii
def showTime():
print datetime.datetime.now().strftime("%H:%M:%S")
def crack():
crcs = set([0xE761062E, 0x2F9A55D3, 0xF0F809B5,
0x645F52A4, 0x0F448B76, 0x3E1A57D9, 0x3A512755])
r = xrange(32, 127)
for a in r:
for b in r:
for c in r:
for d in r:
txt = chr(a)+chr(b)+chr(c)+chr(d)
crc = binascii.crc32(txt)
if (crc & 0xFFFFFFFF) in crcs:
print txt
if name == "main":
showTime()
crack()
showTime()
在命令行下运行上面的Python脚本,等待一段时间后即可看到结果,具体的运行时间由机器的配置决定(经测试,实验机器只需要两分钟左右的时间即可完成破解,破解过程因为占用CPU比较高,因此可能会比较卡,耐心等待即可)。运行结果如下图所示:
这里不到两分钟就完成了整个枚举过程,得到的字符串为:FLAG, assw, dono, ed_p, ord}, t_ne, {we_,我们尝试对其进行拼接,得到一个有意义的结果为:FLAG{we_donot_need_password},这就是我们所要找的Flag字符串。
猜你喜欢
- 2024-11-27 「重磅」Xilinx下载文件破解及LUT在线可编程研究
- 2024-11-27 2020年4月Redis面试题和答案整理
- 2024-11-27 分析Redis key,value的size
- 2024-11-27 自主可控的PLC编程软件:kVPAC/Beremiz操作实践
- 2024-11-27 面试官:说说 Redis 的缓存雪崩、缓存穿透和缓存击穿问题
- 2024-11-27 Redis内存管理:配置与版本事项
- 2024-11-27 Kubernetes全栈架构师(Docker基础)--学习笔记
- 2024-11-27 串口通讯继电器-modbus通信上位机调试软件工具项目开发案例
- 2024-11-27 GCKontrol模型的自动创建
- 2024-11-27 推荐:工业数字化系统开发用到的串口调试小助手
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 505℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 484℃MySQL service启动脚本浅析(r12笔记第59天)
- 465℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 462℃启用MySQL查询缓存(mysql8.0查询缓存)
- 442℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 422℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 418℃MySQL server PID file could not be found!失败
- 最近发表
-
- netty系列之:搭建HTTP上传文件服务器
- 让deepseek教我将deepseek接入word
- 前端大文件分片上传断点续传(前端大文件分片上传断点续传怎么操作)
- POST 为什么会发送两次请求?(post+为什么会发送两次请求?怎么回答)
- Jmeter之HTTP请求与响应(jmeter运行http请求没反应)
- WAF-Bypass之SQL注入绕过思路总结
- 用户疯狂点击上传按钮,如何确保只有一个上传任务在执行?
- 二 计算机网络 前端学习 物理层 链路层 网络层 传输层 应用层 HTTP
- HTTP请求的完全过程(http请求的基本过程)
- dart系列之:浏览器中的舞者,用dart发送HTTP请求
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)