白帽子社区端午节活动-白帽寻宝记-纪念屈原Writeup
Posted 末 初
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了白帽子社区端午节活动-白帽寻宝记-纪念屈原Writeup相关的知识,希望对你有一定的参考价值。
搜索引擎找一下即可得知:
- 姓:芈
- 氏:屈
- 名:平
- 字:原
md5(芈屈平原,32) = 16ccb09f96f27af192f541992560d695
解压后先查看文件先来看看这个吧
在两张图片的的中间存在一串base64
解码得到WingDing
编码
◻︎♋︎⬧︎⬧︎⬥︎□︎❒︎♎︎ ♓︎⬧︎ ♋︎ ♌︎❍︎◻︎ ♐︎♓︎●︎♏︎ ⬥︎♓︎⧫︎♒︎ ♋︎ ♌︎♓︎⧫︎ ♎︎♏︎◻︎⧫︎♒︎ □︎♐︎ 🗏︎📄︎
得到线索
p︎a︎s︎s︎w︎o︎r︎d︎ i︎s︎ a︎ b︎m︎p︎ f︎i︎l︎e︎ w︎i︎t︎h︎ a︎ b︎i︎t︎ d︎e︎p︎t︎h︎ o︎f︎ 3︎2︎
文件password
是位深度为32bit
的bmp
文件,很明显需要通过对bmp
文件结构的相关了解来计算出bmp文件头
和位图信息头
的一些信息并修改,得以正常显示图片
BMP文件结构可自行查阅资料
password
文件大小为:324212 Bytes
做所周知,图像的分辨率和像素的颜色深度决定了图像文件的大小,计算公式如下
图像分辨率 x 颜色深度/8 = 图像所占的字节数
对于bmp文件来说,这里的图像所占字节数并不是文件的大小,文件大小的计算公式如下:
分辨率(width x height) x (颜色深度/8)+ bmp文件头(共14Bytes) + 位图信息头(共40Bytes) + 文件尾(共2bytes: 00 00) = 图像文件大小
已知图像文件大小为324212 Bytes
,颜色深度为32bit
width * height * 4 + 56 = 324212
width * height = 81039
Python简单爆破求解
for width in range(1,500):
for height in range(1,500):
if width * height == 81039:
print("{} * {} = {}".format(width, height,width*height))
print("width: {}({})\\nheight: {}({})\\n".format(width, hex(width)[2:].upper(), height, hex(height)[2:].upper()))
227 * 357 = 81039
width: 227(E3)
height: 357(165)
357 * 227 = 81039
width: 357(165)
height: 227(E3)
OK,根据这些已知信息就可以进行修改正确的文件格式,具体信息可查看:https://www.cnblogs.com/Matrix_Yao/archive/2009/12/02/1615295.html
bmp文件头
42 4D 74 F2 04 00 00 00 00 00 36 00 00 00
位图数据
只要修改前面这几项即可回显出正常数据
28 00 00 00 65 01 00 00 E3 00 00 00 01 00 20 00 00 00 00 00
是什么的密码暂且不知,先看最后一个文件base_data.txt
base64先解码看看内容
from base64 import *
with open('./base_data.txt','r') as f:
lines = f.readlines()
for line in lines:
print(b64decode(line).decode())
解码出来是十六进制数据,每一行中都带有一个时间,按照时间戳来重新排序。
zip
的文件头,写成zip
文件。Python简单处理即可,最终脚本如下:
from binascii import *
from base64 import *
from time import *
with open('./base_data.txt','r') as f:
lines = f.readlines()
mydic = {}
for line in lines:
line = b64decode(line).decode()
local_time = line[:19]
timestamp = int(mktime(strptime(local_time, r"%Y-%m-%d %H:%M:%S")))
mydic[lines.index(b64encode(line.encode()).decode() + '\\n')] = timestamp
mydic = sorted(mydic.items(), key=lambda item: item[1], reverse=False)
with open('flag.zip','wb') as f:
for line_num in mydic:
line_num = line_num[0]
hexdata = b64decode(lines[line_num]).decode()[22:]
print(hexdata)
f.write(unhexlify(hexdata))
密码是之前的得到的bmp
图片提示的信息
md5(白帽子社区CTF团队祝您端午节安康,32) = 74636cc4cfe7cc222130ea50bb2e23c2
解压之后,DuanWu.png.txt
提示的是png
数据,而且查看内容时,不难发现png的十六进制数据的倒序
Python简单处理下即可得到图片
from binascii import *
with open('DuanWu.png.txt','r') as f:
hexdata = f.read()[::-1]
with open('DuanWu.png','wb') as f1:
f1.write(unhexlify(hexdata))
接着看This-Is-Flag.png
,用010 Editor
打开发现CRC
校验不匹配
猜测长宽被修改,直接上crc
爆破宽高脚本
import binascii
import struct
import sys
file = './This-Is-Flag.png'
fr = open(file,'rb').read()
data = bytearray(fr[0x0c:0x1d])
crc32key = eval('0x'+str(binascii.b2a_hex(fr[0x1d:0x21]))[2:-1])
n = 4095
for w in range(n):
width = bytearray(struct.pack('>i', w))
for h in range(n):
height = bytearray(struct.pack('>i', h))
for x in range(4):
data[x+4] = width[x]
data[x+8] = height[x]
crc32result = binascii.crc32(data) & 0xffffffff
if crc32result == crc32key:
print(width,height)
newpic = bytearray(fr)
for x in range(4):
newpic[x+16] = width[x]
newpic[x+20] = height[x]
fw = open(file+'.png','wb')
fw.write(newpic)
fw.close
sys.exit()
PS C:\\Users\\Administrator\\Downloads\\解题\\端午\\DuanWu> python .\\crc.py
bytearray(b'\\x00\\x00\\x05\\xdc') bytearray(b'\\x00\\x00\\x00\\xc8')
接下来的思路就是参考b01lers-ctf-2020-misc-image_adjustments
:https://github.com/b01lers/b01lers-ctf-2020/tree/master/misc/image_adjustments
在原来的flag图片基础上,对每一列的所有像素使用特定的处理逻辑(随机数
)打乱了排序。但是可以通过使用爆破加上特定的特征(蓝色基准线
)来进行还原之前每一列的像素在这一列上的位置从而还原整张图片。
from PIL import Image
img = Image.open('./DuanWu.png')
width, height = img.size[0], img.size[1]
pixels = img.load()
for row in range(width):
data_row = []
for col in range(height):
data_row += [pixels[row, col]]
done = False
for random_num in range(0, height):
if done:
break
for col in range(height):
pixels[row, (col + random_num) % height] = data_row[col]
if(pixels[row, 165] == (255, 255, 255) and pixels[row, 175] == (0, 0, 255) and pixels[row, 180] == (0, 0, 255) and pixels[row, 190] == (255, 255, 255)):
done = True
print('Done: {}'.format(row))
img.save('./flag.png')
img.show()
BMZCTF{Mochu7&Cyz-Wish-You-Happy-DuanWu-Festival}
以上是关于白帽子社区端午节活动-白帽寻宝记-纪念屈原Writeup的主要内容,如果未能解决你的问题,请参考以下文章