CTBUCTF2025 Misc方向 Writeup

CTBUCTF2025 Misc方向 Writeup

666和999的故事

出题人:G3rling

难度:Easy

题目描述:

Misc之旅从这里开始……

拿到题目附件打开,将字符缩小,可以依稀看到01组成的是一个类似于二维码一样的东西

让GPT写一个脚本进行转化,将666转化为黑色像素,999转化成白色像素

from PIL import Image

def read_pattern_from_file(file_path):
    with open(file_path, 'r') as file:
        lines = [line.strip() for line in file.readlines() if line.strip()]

    # 按3个字符一组分割每行的数字
    pattern = []
    for line in lines:
        pattern.append([line[i:i+3] for i in range(0, len(line), 3)])

    width = len(pattern[0])  # 每行的数字组数
    height = len(pattern)    # 行数

    return pattern, width, height

def create_image_from_pattern(pattern, width, height):
    pic = Image.new("1", (width, height))  # 使用 "1" 模式创建黑白图像

    for y in range(height):
        for x in range(width):
            # 将"999"转换为白色(255),"666"转换为黑色(0)
            pixel_value = 255 if pattern[y][x] == '999' else 0
            pic.putpixel((x, y), pixel_value)

    pic.show()
    pic.save("flag.png")

file_path = "attachment.txt"  # 替换为你的txt文件路径
try:
    pattern, width, height = read_pattern_from_file(file_path)
    print(f"图像尺寸: {width}x{height}")
    create_image_from_pattern(pattern, width, height)
except ValueError as e:
    print(f"错误: {e}")

这里还可以直接用记事本进行一个小小的非预期,缩到最小即可看到Flag

image-20250503013825267

转化后得到一张二维码,扫码得到Flag

ctbuctf{The_Misc_Begins_Here_0a5cda}

Do you know SSTV?

出题人:G3rling

难度:Mid

题目描述:

什么是"SSTV"?,第一个"S"代表“Slow”,意为“缓慢的”;第二个"S"代表“Scan”,意为“扫描”;"S"代表“Slow”,意为“缓慢的”;不然就“To Vanish“吧

根据题目可以知道这道题是SSTV(慢扫描电视)

慢扫描电视(Slow-scan television),简称SSTV,是业余无线电爱好者的一种主要图片传输方法,慢扫描电视通过无线电传输和接收单色或彩色静态图片,且完全不依赖网络。

这里通过配置虚拟声卡采集电脑内的声音,借助SSTV接收软件显示出图像(MMSSTV接收出来的是有问题的,需要换一个其他的接收软件,这里使用的是RX-SSTV)

image-20250502211545636

得到Flag

ctbuctf{N0thing_1s_impossible}

Ez_Base64

出题人:G3rling

难度:Mid

题目描述:

Think carefully.This Base64 is very simple.

尝试解码几排,发现内容都是重复的

image-20250502213243846

但是编码后的内容存在不同,这就涉及到Base64的编码原理了

Base64 是一种将二进制数据编码为 ASCII 字符的编码方式,其核心原理是将 3 字节(24 位)的二进制数据分割为 4 个 6 位的片段,再将每个 6 位片段映射到预定义的 64 个可打印 ASCII 字符上。但是如果编码内容不为3字节的整数倍,那么就会出现特殊情况

拿A的编码作为例子

image-20250502214121469

可以看到为了凑成3字节组,编码时将会在二进制数据后补0。二进制数据中标为黄色的0是可以隐藏信息,因为在黄色位置将默认的0修改为其他二进制数,在解码时不会影响其解码结果。

根据这个原理写出解密脚本

file_path = "attachment.txt"
file = open(file_path,'r')
a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

flag_temp = ''
while True:
    text = file.readline()
    text = text.replace("\n", "")
    if not text:
        break
    if text.count('=') == 1:
        flag_temp = flag_temp + \
            str('{:02b}'.format((a.find(text[len(text)-2])) % 4))
    if text.count('=') == 2:
        flag_temp = flag_temp + \
            str('{:04b}'.format((a.find(text[len(text)-3])) % 16))
file.close()

flag = ""
temp = len(flag_temp)
temp = temp//8*8
for i in range(0,temp,8):
    flag = flag + chr(int(flag_temp[i:i+8],2))

print(flag)

得到Flag

ctbuctf{Base64_1s_Fun_0a1304}

书读万遍其意自现

出题人:G3rling

难度:Hard

题目描述:

这是一本答案之书,随便翻开一页,他会给你想要的答案

本题设置了两种做法,第一种是常规解,这道题主要考察词频分析,在收集到5w次左右词频会趋于稳定

from pwn import *

flags = []
char_count = {}
io = remote('ctf.ctbu.edu.cn', 32940)

for _ in range(50000):
    io.sendlineafter(b'you want >', b'1')
    io.recvuntil(b'and saw: ')
    char = io.recv(1).decode('utf-8')

    if char in char_count:
        char_count[char] += 1
    else:
        char_count[char] = 1

sorted_char_count = sorted(char_count.items(), key=lambda item: item[1], reverse=True)

for char, count in sorted_char_count:
    print(f"Character: {char}, Frequency: {count}")
for char, count in sorted_char_count:
    print(char, end='')

io.close()

另外一种是Pwn的解法,设置了一个整形溢出(这里应该先弄个溢出的,很多同学都走了这个解法)

from pwn import *

io = remote('ctf.ctbu.edu.cn', 32940)

io.sendlineafter(b'want >',   str((ord('C')+0xdeadbeef)-(1<<32)).encode())
io.sendlineafter(b'what?',    str((ord('T')+0xdeadbeef)-(1<<32)).encode())
io.sendlineafter(b'pwner??',  str((ord('B')+0xdeadbeef)-(1<<32)).encode())
io.sendlineafter(b'so crazy!',str((ord('U')+0xdeadbeef)-(1<<32)).encode())

io.interactive()

因为Flag头中有重复的英文单词,需要修改一下统计得到的Flag头

ctbuctf{CAYLESsaNDdOMoRe}

Png_Aio

出题人:G3rling

难度:Hard

题目描述:

小小PNG,拿下!

首先对图像宽高进行爆破,得到Flag1

image-20250503110850225

使用zsteg查看LSB通道,发现Flag2

image-20250503111035982

同时可以看到存在一个zlib,继续查看图片的IDAT块

image-20250503111604148

可以看到在中部出现了断层,将第一个到长度为42628的IDAT块删除后对宽高进行爆破,得到Flag3

image-20250503111730695

综上所述

ctbuctf{Look_H1gher_And_DeEeper}

vivo50保卫战:决战星期四

出题人:G3rling

难度:Baby

题目描述:

爷爷最近想起在家里存放着一张 vivo50 代金券,这张代金券被锁在一个保险箱里,但他忘记了密码。而更让人头疼的是,这个保险箱的锁并不是普通的密码锁,而是一个特殊的 Brainfuck 编写的程序,你能帮助爷爷破解保险箱密码,让爷爷在星期四前拿到 vivo50 代金券吗?

👉 第一位打开保险箱的同学请联系G3rling领取vivo50代金卷

考点是Brainfuck,为了模拟保险箱逐位破解的效果,带了一点侧信道爆破味儿

from pwn import *

charset = '0123456789abcdefghijklmnopqrstuvwxyz'

def bf_encode_string(s):
    return ''.join(['+' * ord(c) + '.[-]' for c in s])

io = remote("ctf.ctbu.edu.cn", 32975)
password = "ctbuctf{" 

while not password.endswith('}'):
    for ch in charset:
        io.recvuntil(b'Enter the password')

        attempt = password + ch + "}"
        bf_code = bf_encode_string(attempt)
        io.sendlineafter(b'>> ', bf_code.encode())

        response = b""
        while b"\nW" not in response:   # 只获取Wrong Password的首字母,节省时间
            response += io.recv(1)

            if password.encode() in response:
                print(response)

            if b"\nC" in response:
                password += ch + "}"
                print(f"Final password: {password}")
                exit(0)

        if attempt.encode() in response:    # 只有ch正确时才会处理},当接收到@时证明ch正确
            password += ch
            print(f"Found next password: {password}")
            break

Zip_Master

出题人:G3rling

难度:Baby

题目描述:

想必新生赛你已经学会基本操作了,是不是很简单呢?那让我们来练习一下前面的操作,快来试试这个吧~

G3rling把flag.txt压缩后放在了桌面上,但是附件遭到了损坏,很多关键部分都被删除了。
据G3rling回忆能够记得这些信息:

压缩软件为Bandizip 7.06
压缩方式为Deflate
被压缩文件的最后修改时间为2025/05/02 10:32:28
文件CRC为 6BB27AB2
原始大小为46
扩展字段长度为36
外部文件属性为32
当前磁盘上的中央目录记录数为1
中央目录总条目数为1
中央目录的总大小为90
中央目录相对于第一个entry的起始位置为81

请根据以上信息修复压缩包,得到flag.txt

因为今年好几次比赛都遇到了修复压缩包的题目,这里直接拉通

Zip文件结构

zip文件结构由三部分组成:压缩文件源数据区 + 压缩源文件目录区 + 压缩源文件目录结束标志

文件源数据区

字段名称 字段描述
frSignature ZIP文件头,固定值504B0304
frVersion 解压所需的 pkware 版本
frFLags 全局方式位标记,最低位的1bit是1表示加密,是0表示未加密
frCompression 压缩方法(具体值如Store、Deflate等)
frFileTime 被压缩文件的最后修改时间
frFileDate 被压缩文件的最后修改日期
frCrc 文件压缩前 CRC-32 的值
frCompressedSize 被压缩文件压缩后的大小
frUncompressedSize 被压缩文件压缩前的大小
frFileNameLength 被压缩文件的文件名长度
frExtraFieldLength 扩展字段长度(具体值如0等)
frFileName 被压缩文件的文件名
frData 被压缩文件压缩后的数据

文件目录区

字段名称 字段描述
deSignature 签名,通常是504B0102
deVersionMadeBy 制作于哪个 pkware 版本
deVersionToExtract 解析该目录需要的版本号,与数据区frVersion的值一致
deFLags 一般标志位,与数据区frFlags的值一致
deCompression 压缩方法,与数据区frCompression的值一致
deFileTime 被压缩文件的最后修改时间,与数据区中对应字段的值一致
deFileDate 被压缩文件的最后修改日期,与数据区中对应字段的值一致
deCrc 文件压缩前 CRC-32 的值
deCompressedSize 被压缩文件压缩后的大小
deUncompressedSize 被压缩文件压缩前的大小
deFileNameLength 被压缩文件的文件名长度
deExtraFieldLength 扩展字段长度(与数据区的对应值可能不一致)
deFileCommentLength 文件备注长度
deDiskNumberStart 文件起始位置所在的磁盘编号(早期磁盘很小的情况下,压缩包可能跨磁盘)
deInternalAttributes 内部文件属性
deExternalAttributes 外部文件属性
uint deHeaderOffset 本目录指向的entry相对于第一个entry的起始位置,单位byte,这也就限制了ZIP文件最大也就是4G了,再大就无法定位了
deFileName 被压缩文件的文件名
deExtraField 扩展字段

文件目录结束

字段名称 字段描述
elSignature 签名,通常是504B0506
elDiskNumber 当前磁盘编号
elStartDiskNumber 中央目录起始磁盘编号
elEntriesOnDisk 当前磁盘上的中央目录记录数
elEntriesInDirectory 中央目录总条目数
elDirectorySize 中央目录的总大小
elDirectoryOffset 中央目录相对于第一个entry的起始位置
elCommentLength 注释长度
char elComment 压缩包注释

根据以上材料对附件进行修复,附上完整十六进制数据(大意了,被GPT秒了)

50 4b 03 04 14 00 00 00 08 00 0e 54 a2 5a b2 7a b2 6b 2b 00 00 00 2e 00 00 00 08 00 00 00 66 6c 61 67 2e 74 78 74 4b 2e 49 2a 4d 2e 49 ab 0e cf cf cf 2f 07 a2 f8 c8 fc fc d2 c4 f8 a8 cc 82 78 df c4 e2 92 54 20 28 52 7c bf a7 51 11 44 d4 02 00 50 4b 01 02 14 00 14 00 00 00 08 00 0e 54 a2 5a b2 7a b2 6b 2b 00 00 00 2e 00 00 00 08 00 24 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 66 6c 61 67 2e 74 78 74 0a 00 20 00 00 00 00 00 01 00 18 00 63 2f 46 71 0a bb db 01 aa 05 16 a7 0a bb db 01 b2 7b f4 08 0a bb db 01 50 4b 05 06 00 00 00 00 01 00 01 00 5a 00 00 00 51 00 00 00 00 00

解压得到Flag

ctbuctf{Wooowoow_Yooua_Zip_Masteeeer!!!!!}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇