0


2024年浙江省大学生网络与信息安全竞赛决赛Misc WP by 王八七七

2024年第七届浙江省大学生网络与信息安全竞赛圆满结束,一场汇聚浙江省高校优秀学子的信息安全领域竞技盛宴即将拉开帷幕!本次大赛由杭州电子科技大学与浙大城市学院承办,于2024年11月正式开赛,吸引了来自全省各大高校的众多优秀学子,报名人数再创新高,点燃了浙江省高校学子对网络与信息安全领域的热情之火。

FinalSign(二血)

打开赛题附件,发现存在txt文件(FinaSign.txt),查看txt文件详细内容得到

Ctrl+A全选后发现存在隐藏内容,可能存在SNOW隐写、零宽隐写或者摩斯密码替换隐写

这里我们选择SNOW隐写,使用SNOW.exe工具对文件进行output解密操作得到

xorkey:helloworld

根据明文提示helloworld为xor的key密钥,那么我们将原本的十六进制文本进行异或(xor)操作,即可解开这道题的秘密,接下来我们实现以上操作

发现直接进行xor操作出现乱码,此时我们先将字符串进行hex解密后,再进行异或操作即可得到本题flag,如下图所示

最终,得到本题flag

非黑即白

首先分析附件发现压缩包内存在一个file文件无后缀名,接着我们使用010editor进行十六进制分析

010editor分析结果为:发现文件尾部存在dad98FIG字样,将其逆序后得到GIF89dad,发现是GIF动态图片的文件头,那么我们就可以将该文件进行数据逆序操作,即可恢复GIF动图

恢复后发现由黑白图片交替的gif图片,那么接下来的思路应该就是将黑白图片转1和0(即二进制),我们将黑色转为字符“0”白色转为字符“1”,我们先将gif中的每一帧导出。

进行上述操作后我们就可以得到每一张图片的内容,接着根据上述规则我们恢复原文件

脚本如下

from PIL import Image

# 打开GIF图片
image = Image.open("1.gif")

# 初始化变量
frame_index = 0
binary_string = ""
byte_array = []

# 遍历GIF的每一帧
while True:
    try:
        # 定位到当前帧
        image.seek(frame_index)
        
        # 将图像转换为1位像素图像(黑白)
        bw_image = image.convert('1')
        
        # 获取图像的像素数据
        pixels = bw_image.getdata()
        
        # 假设我们只关心第一个像素(这里可以修改为处理整个图像或其他逻辑)
        first_pixel = pixels[0]
        
        # 将第一个像素的黑白值(0或255)转换为二进制字符串
        binary_string += '0' if first_pixel == 0 else '1'
        
        # 每8位二进制字符串转换为一个字节,并添加到字节数组
        if len(binary_string) == 8:
            byte_array.append(int(binary_string, 2))
            binary_string = ""
        
        # 移动到下一帧
        frame_index += 1
    
    except EOFError:
        # 当没有更多帧时,退出循环
        break

# 将字节数组写入文件
with open("data", "wb") as file:
    file.write(bytes(byte_array))

运行脚本后得到zip压缩包文件

得到存在压缩包密码的flag.txt文件,同时zip文件不存在伪加密

最终我们发现刚开始几个帧的gif动图的时间间隔有所不同,那么压缩包密码就是gif动图的帧间隔GIF帧间隔‌是指GIF动画中每帧之间的时间间隔。帧间隔决定了动画的播放速度,通常以毫秒为单位。帧间隔越短,动画播放速度越快;帧间隔越长,动画播放速度越慢。

通过分析我们发现图片开头的帧间隔有明显的不同,数据如下

'1180', '1060', '690', '740', '480', '980', '830', '1170', '770', '790', '860', '650', '900', '1030', '1010'

接着我们将帧间隔数据每一位最后的数字“0”进行删除,接着将处理后的数据进行十进制转ASCII码(字符串) 操作后得到压缩包的密码

处理后的数据

118, 106, 69, 74, 48, 98, 83, 117, 77, 79, 86, 65, 90, 103, 101

解密后的密码

vjEJ0bSuMOVAZge

解压压缩包后得到flag

天命人

首先分析附件,得到6个无后缀名的file文件,天命人!!!我们先看看六个回目的名称,它们分别是:火照黑云、风起黄昏、夜生白露、曲度紫鸳、日落红尘、未竟。它们分别对应了游戏中的六个角色,黑熊、貂鼠、黄眉、八戒、牛魔、和悟空。其中曲度紫鸳和未竟相对最好理解,曲度紫鸳说的是八戒救度爱人,未竟说的是悟空未完成的事业。

那么他们的排序一定有它们的顺序,我们分开来看,将6个文件依次放入010editor

发现通过排序后每个文件的hex的第一位分别为

50 4B 03 04 0A 00

发现该数据为明显的zip压缩包文件头特征,那么这里的考点为:将文件按顺序排列后,依次按顺序取16进制的值进行拼接,每六个为一个轮回,依次轮替完之后从hex的第二位再次进行循环,直到循环到最后一个文件的最后一位(也就是将zip文件的16进制每6个为一组按顺序拆分成6个file文件,通过顺序再次拼接即可)

恢复文件脚本如下

import os

def read_hex_from_files(files, output_file):
    # 打开输出文件以写入数据
    with open(output_file, "wb") as out_f:
        # 获取文件对象列表
        file_objects = [open(file, "rb") for file in files]
        
        try:
            data_available = True
            index = 0
            # 当有数据可以读取时继续循环
            while data_available:
                data_available = False
                # 循环访问每个文件
                for file in file_objects:
                    # 移动到文件的当前位置
                    file.seek(index)
                    # 读取一个字节
                    byte = file.read(1)
                    if byte:
                        # 如果读取到数据,写入到输出文件
                        out_f.write(byte)
                        data_available = True
                # 增加索引,以便下一次读取下一个字节
                index += 1
        finally:
            # 关闭所有文件
            for file in file_objects:
                file.close()

# 文件夹路径和新文件名称
folder_path = "./"  # 替换为文件夹路径
output_file = "output_file.zip"

# 按文件名顺序将文件路径加入列表
files = [os.path.join(folder_path, str(i)) for i in range(1, 7)]

# 调用函数生成新文件
read_hex_from_files(files, output_file)
print(f"新文件 '{output_file}' 已成功生成。")

恢复文件后得到两个压缩包hint提示“六根齐备,直面天命”,那么zip1的密码应该就存在于zip2中了

通过分析发现zip2的txt文件大小全部相同,那么我们对他们进行CRC32进行爆破

CRC32数据如下

76899D01

8E036AA6

881D716A

7F3D8E75

248D3C69

CB27D2BD

爆破结果如下

{0x43, 0x30, 0x4d, 0x33}

{0x5f, 0x34, 0x4e, 0x44}

{0x5f, 0x47, 0x65, 0x74}

{0x5f, 0x53, 0x31, 0x58}

{0x5f, 0x52, 0x30, 0x30}

{0x54, 0x53, 0x21, 0x21}

16进制解密后得到密码为

C0M3_4ND_Get_S1X_R00TS!!

接着我们解压压缩包得到一个file文件和一个png图片,分析后发现png图片包含彩色像素点,而HDCTF刚好考到此知识点,有两种方法(一)使用Photoshop中的临近硬边缘功能(二)缩小图片产生块状效果进行手动像素修复

(一)使用Photoshop中的临近硬边缘功能

得到VeraCrypt的挂载密码

verapass1:jinggubang

(二)使用脚本对图片进行缩小图片产生块状效果进行手动像素修复

提取脚本如下

from PIL import Image

# 打开原始图片
a = Image.open("金箍棒.png")

# 计算缩放比例,这里是缩小到原来的1/10
scale_factor = 0.1

# 使用resize方法直接缩小图片
b = a.resize((int(a.size[0] * scale_factor), int(a.size[1] * scale_factor)), Image.NEAREST)

# 保存缩小后的图片
b.save('pass.png')

**

resize

**方法接受一个元组作为新尺寸,并可以选择一个过滤器(如

Image.NEAREST

,它使用最近邻算法进行像素重采样)。**

Image.NEAREST

**在缩小图片时通常会产生块状效果,类似于手动像素复制。

得到VeraCrypt的挂载密码

verapass1:jinggubang

接着我们将附件紧箍咒作为VeraCrypt作为挂载的磁盘,为什么我们的思路能够直接到VeraCrypt这个工具上呢???其实做题过程中已经有提示啦!!!

在附件的zip文件说明当中就已经为我们进行了提示。

重走西游,集齐六根,跳出轮回,直面天命!
(你知道raid0吗)

RAID也叫磁盘阵列技术,提供比单个磁盘更高的存储性能和数据冗余的技术。
RAID分类:
RAID0:是一种条带化技术,也就是提高硬盘的存储空间,提高读写效率,至少需要两块,不提供恢复,冗余等操作。
RAID1:是一种数据镜像,相当于1:1备份数据在另一块硬盘上,至少需要两块,具有冗余性,不提供校验。
RAID2:利用海明码技术,提供纠错技术,但是冗余的开销太大,硬盘数取决于数据存储的宽度。
RAID3:是RADI0的增强版,具有容错功能,当一块数据错误时,可以通过校验盘恢复。至少需要3块硬盘。
RAID4:跟RAID3的原理大致相同,区别在于条带化方式不同,也需要3个盘。
RAID5:跟RAID4原理大致相同,区别在于校验存储时在每一块盘上,至少需要3块盘,能够检验恢复数据。只允许一块磁盘损坏。因为两块用于条带化,另一块用于奇偶性校验。
RAID10:可以理解位RAID1+RAID0的版本,没有校验,具有冗余性,至少需要4块盘

那么,这里就提示,我们后续的过程中就会考到关于磁盘的知识点,其次,在恢复后的密码当中,出现了Verapass字样,更能确定了我们应该使用VeraCrypt这个工具对进行磁盘的挂载!!!

接着我们进行挂载,首先我们将jinggubang作为密码进行提交,接着我们将png图片作为密钥文件进行提交,如下所示

成功载raid0磁盘

打开磁盘文件得到flag

总结

明年AK Misc


本文转载自: https://blog.csdn.net/weixin_52365980/article/details/143680818
版权归原作者 王八七七 所有, 如有侵权,请联系我们删除。

“2024年浙江省大学生网络与信息安全竞赛决赛Misc WP by 王八七七”的评论:

还没有评论