白帽子社区端午节活动-白帽寻宝记-纪念屈原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是位深度为32bitbmp文件,很明显需要通过对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_adjustmentshttps://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}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

末 初

谢谢老板!

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值