KCTF_MISC:神秘的图片
题目
我在虚拟机Ubuntu 20.04中安装010 Editor 软件尝试打开release.png图片:
PNG图片格式
由开头的十六进制可知:
89 50 4E 47 0D 0A 1A 0A为png的文件头
00 00 00 0D代表数据块的长度13 IHDR
49 48 44 52 文件头数据块标志IDCH
00 00 01 F4 图像的宽 500像素
00 00 01 A3 图像的高 419像素
08 06 00 00 00 分别表示图片的图像深度, 颜色类型, 压缩方法, 滤波器方法,隔行扫描方法
剩下的4字节CB D6 DF 8A 为该PNG的CRC32校验码, 由从IDCH到IHDR的十七位字节进行CRC计算得到
AE 42 60 82 文件尾
CRC校验码
计算原理详见mooc
CRC码不仅能校验传递过来的数据正确性,还能筛查出哪一位出现了错误.它的局限性是只能校验一位数据发生跳变
CRC实现
不同CRC标准
CRC4:x4+x+1
CRC8: x8+x5+x4+1
CRC16: x16+x12+x5+1
CRC32: x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
CRC检验
当一个图片只被修改了宽高而没有被修改CRC码时,再通过前面的值去算CRC码就会跟原本的CRC值不一样,因此需要先计算CRC码进行判断:
# 根据当前PNG宽高计算出CRC码,比较原本CRC
import zlib
image_data = open("release.png", "rb")
bin_data = image_data.read()
crc32key = zlib.crc32(bin_data[12:29]) # 调用函数计算当前PNG大小下的CRC校验码
# print(crc32key)
if crc32key == int(bin_data[29:33].hex(), 16): # 对比算出的CRC和原本的CRC(29-33byte 4字节为CRC码)
print("PNG 宽高没有问题")
else:
print("PNG 宽高被修改")
运行结果:
CRC暴力破解
因为CRC校验码只能对一位数据进行校验,这里的PNG图片的数据可能不止一位出现错误,所以采取的办法时是枚举PNG图片的宽高,然后计算修改后图片的CRC值,与正确的CRC值比较看是否一致
# PNG图片爆破CRC32的宽和高
import zlib
import struct
crcbp = open("release.png", "rb").read() # 打开图片
# 高和宽不对都会影响CRC32的值,所以要一起爆破
for w in range(0xFFFF):
for h in range(0xFFFF):
data = crcbp[12:16] + struct.pack('>i', w) + struct.pack('>i', h) + crcbp[24:29] #'>' 表示大端
crc32 = zlib.crc32(data) & 0xFFFFFFFF # 计算CRC码(无符号)
#print(crc32)
if(crc32 == 0xCBD6DF8A): # 图片当前CRC校验码
print(w, h)
print('hex:', hex(w), hex(h))
对CRC校验码进行爆破后获得该图片正常的高宽:
使用修改图片的高为500,可以看到:
IEND处理
因为图片提示剩余flag在末尾,使用010 Editor 软件打开修改后的图片找到结束标识符IEDN
正常PNG图片在IEND就结束了,而release.png在IEDN后面仍有内容,把这部分内容以十六进制形式提取放到文件release.txt中
可以看出来这串代码仅有”0x20”和“0x09”,二者重复出现,所以猜想可能某一个表示’1’,另一个表示‘0‘,这代码就是一个表示01的串
编写脚本处理release.txt,将所有空格与回车删除后放到result.txt里
# 删除编码中所有的空格和回车
import os
data = '' # 保存最后处理完的文本
with open('release.txt', 'r') as f: # 按行处理 txt 文本
for line in f:
line = line.replace(' ', '') # 删除所有空格
line = line.replace('\n', '') # 删除所有回车
data = data + line # 字符串拼接
fw = open('result.txt', 'w')
fw.write(data) # 将最终结果保存到目标文件
接下来对result.txt进行字符串的替换,将’20’<-‘1’, ‘09’ <- ‘0’的替换放到文件result_1.txt中,将’20’<-‘0’, ‘09’ <- '1’的替换放到文件result_2.txt
# 将得到的编码进行替换,'20'<-'0', '09' <- '1'
import os
with open('result.txt', 'r') as f:
result = f.read() # 读取文件
# result = result.replace("20", "1")
# result = result.replace("09","0")
result = result.replace("09", "1") # 替换
result = result.replace("20","0")
# with open('result_1.txt', 'w') as f:
with open('result_2.txt', 'w') as f:
f.write(result) # 将替换结果写入另外的文件
最开始得到的十六进制代码串为16x625 byte的,在通过字符串替换后得到的01串也为16x625byte ,刚好为10000 = 100x100,正好可以表示一个100x100的矩阵,如果‘1‘代表黑色,’0‘代表白色,则可以根据PTL库画出二维码
from PIL import Image
MAX = 100# 二维码大小
pic = Image.new("RGB",(MAX, MAX))
# str为获取的01片段
str = """0000000000000000000000000000111100001111111111111111111111110000000011110000000000000000000000000000000000000000000000000000000011110000111111111111111111111111000000001111000000000000000000000000000000000000000000000000000000001111000011111111111111111111111100000000111100000000000000000000000000000000000000000000000000000000111100001111111111111111111111110000000011110000000000000000000000000000000011111111111111111111000011110000111111110000000000001111111100001111000011111111111111111111000000001111111111111111111100001111000011111111000000000000111111110000111100001111111111111111111100000000111111111111111111110000111100001111111100000000000011111111000011110000111111111111111111110000000011111111111111111111000011110000111111110000000000001111111100001111000011111111111111111111000000001111000000000000111100001111000000001111111100001111000000000000111100001111000000000000111100000000111100000000000011110000111100000000111111110000111100000000000011110000111100000000000011110000000011110000000000001111000011110000000011111111000011110000000000001111000011110000000000001111000000001111000000000000111100001111000000001111111100001111000000000000111100001111000000000000111100000000111100000000000011110000111100000000000011110000111111111111000011110000111100000000000011110000000011110000000000001111000011110000000000001111000011111111111100001111000011110000000000001111000000001111000000000000111100001111000000000000111100001111111111110000111100001111000000000000111100000000111100000000000011110000111100000000000011110000111111111111000011110000111100000000000011110000000011110000000000001111000011111111000000001111000011110000000000001111000011110000000000001111000000001111000000000000111100001111111100000000111100001111000000000000111100001111000000000000111100000000111100000000000011110000111111110000000011110000111100000000000011110000111100000000000011110000000011110000000000001111000011111111000000001111000011110000000000001111000011110000000000001111000000001111111111111111111100001111000000000000111111111111111111111111111100001111111111111111111100000000111111111111111111110000111100000000000011111111111111111111111111110000111111111111111111110000000011111111111111111111000011110000000000001111111111111111111111111111000011111111111111111111000000001111111111111111111100001111000000000000111111111111111111111111111100001111111111111111111100000000000000000000000000000000111100001111000011110000111100001111000011110000000000000000000000000000000000000000000000000000000011110000111100001111000011110000111100001111000000000000000000000000000000000000000000000000000000001111000011110000111100001111000011110000111100000000000000000000000000000000000000000000000000000000111100001111000011110000111100001111000011110000000000000000000000000000111111111111111111111111111111111111111100000000111100001111111100001111111111111111111111111111111111111111111111111111111111111111111111110000000011110000111111110000111111111111111111111111111111111111111111111111111111111111111111111111000000001111000011111111000011111111111111111111111111111111111111111111111111111111111111111111111100000000111100001111111100001111111111111111111111111111111100000000111111110000000000001111111111110000111100000000111111110000111111110000111100000000000000000000000011111111000000000000111111111111000011110000000011111111000011111111000011110000000000000000000000001111111100000000000011111111111100001111000000001111111100001111111100001111000000000000000000000000111111110000000000001111111111110000111100000000111111110000111111110000111100000000000000001111000000001111000011111111000000001111111111111111000000000000000000001111000000001111000000001111111100000000111100001111111100000000111111111111111100000000000000000000111100000000111100000000111111110000000011110000111111110000000011111111111111110000000000000000000011110000000011110000000011111111000000001111000011111111000000001111111111111111000000000000000000001111000000001111000000001111111111111111000000000000000000000000000000001111111111111111000011110000111100000000111100000000111111111111111100000000000000000000000000000000111111111111111100001111000011110000000011110000000011111111111111110000000000000000000000000000000011111111111111110000111100001111000000001111000000001111111111111111000000000000000000000000000000001111111111111111000011110000111100000000111100000000111111111111111111110000111111111111000000001111111100001111000011111111000000000000111100000000111100001111111111111111000011111111111100000000111111110000111100001111111100000000000011110000000011110000111111111111111100001111111111110000000011111111000011110000111111110000000000001111000000001111000011111111111111110000111111111111000000001111111100001111000011111111000000000000111100000000111100001111111111111111111111110000111111111111111100001111000000000000111111110000000011110000000011110000111111111111111111111111000011111111111111110000111100000000000011111111000000001111000000001111000011111111111111111111111100001111111111111111000011110000000000001111111100000000111100000000111100001111111111111111111111110000111111111111111100001111000000000000111111110000000011110000000011110000000000000000111100000000111100000000111100001111000011111111000000000000111111110000111111110000111100000000000011110000000011110000000011110000111100001111111100000000000011111111000011111111000011110000000000001111000000001111000000001111000011110000111111110000000000001111111100001111111100001111000000000000111100000000111100000000111100001111000011111111000000000000111111110000111111110000111111111111111100001111111100000000000000000000000000000000000000001111111111111111000000000000000011111111111111110000111111110000000000000000000000000000000000000000111111111111111100000000000000001111111111111111000011111111000000000000000000000000000000000000000011111111111111110000000000000000111111111111111100001111111100000000000000000000000000000000000000001111111111111111000000000000000011111111111111110000000011111111000011111111111100001111000011110000111100001111000011111111000000001111111111111111000000001111111100001111111111110000111100001111000011110000111100001111111100000000111111111111111100000000111111110000111111111111000011110000111100001111000011110000111111110000000011111111111111110000000011111111000011111111111100001111000011110000111100001111000011111111000000001111000000001111000000001111000011110000000011111111000000001111111100000000000000000000111100000000000000000000111100000000111100001111000000001111111100000000111111110000000000000000000011110000000000000000000011110000000011110000111100000000111111110000000011111111000000000000000000001111000000000000000000001111000000001111000011110000000011111111000000001111111100000000000000000000111100000000000011111111111111111111111111111111000011110000111111110000000011110000111111111111000011111111000011111111111111111111111111111111111100001111000011111111000000001111000011111111111100001111111100001111111111111111111111111111111111110000111100001111111100000000111100001111111111110000111111110000111111111111111111111111111111111111000011110000111111110000000011110000111111111111000011111111000011110000000000000000000000000000111111110000111111111111111111111111000011110000111100000000111100001111000000000000000000000000000011111111000011111111111111111111111100001111000011110000000011110000111100000000000000000000000000001111111100001111111111111111111111110000111100001111000000001111000011110000000000000000000000000000111111110000111111111111111111111111000011110000111100000000111100001111000011111111111111111111000011110000111111111111000011110000111100001111111111110000000000000000000000001111111111111111111100001111000011111111111100001111000011110000111111111111000000000000000000000000111111111111111111110000111100001111111111110000111100001111000011111111111100000000000000000000000011111111111111111111000011110000111111111111000011110000111100001111111111110000000000000000000000001111000000000000111100001111000011110000000011110000000011110000000000000000000000000000111100000000111100000000000011110000111100001111000000001111000000001111000000000000000000000000000011110000000011110000000000001111000011110000111100000000111100000000111100000000000000000000000000001111000000001111000000000000111100001111000011110000000011110000000011110000000000000000000000000000111100000000111100000000000011110000111111111111111111110000111111110000000011110000000011110000111100000000000011110000000000001111000011111111111111111111000011111111000000001111000000001111000011110000000000001111000000000000111100001111111111111111111100001111111100000000111100000000111100001111000000000000111100000000000011110000111111111111111111110000111111110000000011110000000011110000111100000000000011110000000000001111000011111111000011110000000000000000111100001111000000001111000011110000111100001111000000000000111100001111111100001111000000000000000011110000111100000000111100001111000011110000111100000000000011110000111111110000111100000000000000001111000011110000000011110000111100001111000011110000000000001111000011111111000011110000000000000000111100001111000000001111000011110000111100001111111111111111111100001111000011110000000011110000111111111111111111111111000011110000000011110000111111111111111111110000111100001111000000001111000011111111111111111111111100001111000000001111000011111111111111111111000011110000111100000000111100001111111111111111111111110000111100000000111100001111111111111111111100001111000011110000000011110000111111111111111111111111000011110000000011110000000000000000000000000000111100000000000011110000000011110000111100000000111100000000000000000000000000000000000000000000000011110000000000001111000000001111000011110000000011110000000000000000000000000000000000000000000000001111000000000000111100000000111100001111000000001111000000000000000000000000000000000000000000000000111100000000000011110000000011110000111100000000111100000000000000000000"""
i = 0
for y in range (0,MAX):
for x in range (0,MAX):
if(str[i] == '1'): # 一次读取01片段
pic.putpixel([x,y],(0, 0, 0)) # putpixel() 设置[x,y]处的像素颜色
else:
pic.putpixel([x,y],(255,255,255))
i = i+1
pic.show()
分别输入两个01的片段,可以得到两个相反的二维码,手机扫码都得到一个结果:
最终的flag为:flag{wocs34vu9rsd4390b6vfg245weori}