window.onload=function(){ /*页面加载完成之后生成博客目录*/ BlogDirectory.createBlogDirectory("cnblogs_post_body","h2","h3",20); }

[CISCN 2023 初赛]puzzle

1、要

import os
files = os.listdir('./tmp4')
size = []
for file in files:
  with open('./tmp4/'+file,'rb') as fr:
    data = fr.read(0x1A)
  x = int.from_bytes(data[6:8],'little')
  y = int.from_bytes(data[8:10],'little')
  width = int.from_bytes(data[0x12:0x16],'little')
  height = 100
  size.append([(y,x),(height,width)])
sorted_size = sorted(size,key=lambda x:x[0])
img_height = sorted_size[-1][0][0] + sorted_size[-1][1][0]
img_width = sorted_size[-1][0][1] + sorted_size[-1][1][1]
print(img_height,img_width)
# 4000 7200

7200 4000 是根bmp数据

这就是拼图的关键点,别人说必须要为0,但是这个出题人就利用了不为0,也不会影响读取显示所以就可以利用这点了,bfReserved1 代表了 x,bfReserved2 代表了 y

x和y代表的是图像的左上角的位置,我们就根据这个还有高度是负数的情况是等于垂直翻转了,代码中遇到了高度是负数的,也就是等于-100的我们再做一个垂直翻转不就给翻转回来了。

bmp高度问题:

正常情况下:

实际本题情况:

因此需要垂直翻转

import os
import cv2
import numpy as np


new_img = np.zeros(shape=(4000, 7200, 3), dtype=np.uint8)

for root, dirs, files in os.walk("./tmp4"):
    for file in files:
        imgPath = os.path.join(root, file)
        img = cv2.imread(imgPath, cv2.IMREAD_UNCHANGED)
        row, col = img.shape[:2]
        
        with open(imgPath, "rb") as f:
            data = f.read(0x16+4)
        x = int.from_bytes(data[6:8], byteorder="little", signed=False)
        y = int.from_bytes(data[8:10], byteorder="little", signed=False)
        
        if int.from_bytes(data[0x16:0x16+4], byteorder="little", signed=True) == -100:
            img = cv2.flip(img, 0) # 垂直翻转一下
        new_img[y:y+row, x:x+col] = img
        
cv2.imwrite("part1.png", new_img)

得到图片:

然后利用zsteg进行对bmp隐写分析

2、出是有更
制内

import os
import libnum
from PIL import Image

# 7200, 4000
dic = {i: [] for i in range(4000 // 100)}

for root, dirs, files in os.walk("./tmp4"):
    for file in files:
        imgPath = os.path.join(root, file)
        img = Image.open(imgPath)
        
        with open(imgPath, "rb") as f:
            data = f.read(0x16+4)
        x = int.from_bytes(data[6:8], byteorder="little", signed=False)
        y = int.from_bytes(data[8:10], byteorder="little", signed=False)
        height = 0 if int.from_bytes(data[0x16:0x16+4], byteorder="little", signed=True) == -100 else 1

        dic[y//100].append([x, height])

bin_str = ""
for key, values in dic.items():
    values = sorted(values, key=lambda x: x[0])
    for value in values:
        bin_str += f"{value[-1]}"

# print(bin_str)
print(libnum.b2s(bin_str)) #二进制转字符

得到

3、flag摩斯padflag

分则bmp数据4数据
0数据数据。

FF D8 jpg

from PIL import Image
import os
files = os.listdir('./tmp4')
my_data = []
for file in files:
    with open('./tmp4/'+file,'rb') as fr:
        data = fr.read()
    x = int.from_bytes(data[6:8],'little')
    y = int.from_bytes(data[8:10],'little')
    width = int.from_bytes(data[0x12:0x16],'little',signed=True)
    padding_size = 0 if 4- 3*width%4 == 4 else 4- 3*width%4#计算填充字节
    img_data_size = 3*width#计算数据字节
    length = len(data[54:])#文件头占54字节
    img_data = data[54:]
    padding_data = b''
    for i in range(img_data_size,length,padding_size+img_data_size):
        padding_data += img_data[i:i+padding_size]
    my_data.append([(y,x),padding_data])#先排横坐标,再排纵坐标
sorted_data = sorted(my_data,key=lambda x:x[0])#按拼图顺序排序
padding_msg = b''
for v in sorted_data:
    padding_msg += v[1]
with open('1.jpg','wb') as fw:
    fw.write(padding_msg)
#3rd_parT_1s_paddINGINGING}

posted @ 2023-06-03 13:42  Kicky_Mu  阅读(231)  评论(0编辑  收藏  举报