2026软件系统安全赛初赛MISC--steganography

前言

一个更好的方法与本文章方法不一样,都可以用来参考。

解题

下载附件得到一个无后缀文件

发现头部被修改。

如果想知道如何判断,可以参考:
CTF必知:以一次MISC题目完整分析png图片16进制分别代表什么(干货满满!)

python 复制代码
data = open("steganography_challenge","rb").read()
print("Header:",data[:35].hex())
idx = data.find(b"\x89PNG")
print("PNG at offset:",idx)

到35字节的地方有PNG的IDAT。

删除前面的字节后。

用zsteg功能扫描一下。

前面的因为跳过的报错不用管,只需要注意最后一条118行无效滤波字节 254。这个警告说明 PNG 滤波字节被修改了。

说明图片身高造假,就是要修改一下图片的高。

把高改成00 00 00 76(118)即可。

如果想知道如何判断,可以参考:
CTF必知:以一次MISC题目完整分析png图片16进制分别代表什么(干货满满!)

提取成功。

解压后每个压缩包都加密了。

但是其中6个和密码有关的只有4个字节。

CRC爆破。

可以用代码:

python 复制代码
import binascii, struct, itertools, string
 
# 从各 pass*.zip 头中读取 CRC32
crcs = {
    "pass1": 0xce70d424,
    "pass2": 0xf90c8a70,
    "pass3": 0xff3fe4bb,
    "pass4": 0x242a5387,
    "pass5": 0x9a27098e,
    "pass6": 0xd3f6df9f,
}
 
# 枚举所有 4 字节可打印 ASCII,匹配 CRC32
charset = "".join(chr(i) for i in range(32, 127))
crc_to_plain = {}
for combo in itertools.product(charset, repeat=4):
    candidate = "".join(combo).encode()
    c = binascii.crc32(candidate) & 0xffffffff
    if c in set(crcs.values()):
        crc_to_plain[c] = candidate.decode()

这4个是CRC32。如果想知道如何判断,可以参考:
CTF必知:以一次MISC题目完整分析png图片16进制分别代表什么(干货满满!)

脚本:

python 复制代码
#!/usr/bin/env python3
import binascii
import itertools
import string
from concurrent.futures import ThreadPoolExecutor

crc_dict = {
    'ce70d424': 'pass1',
    'f90c8a70': 'pass2',
    'ff3fe4bb': 'pass3',
    '242a5387': 'pass4',
    '9a27098e': 'pass5',
    'd3f6df9f': 'pass6'
}

targets = {int(k, 16): v for k, v in crc_dict.items()}
chars = "".join(chr(i) for i in range(32, 127))  # 修复 Bug
results = {}
lock = __import__('threading').Lock()

def check_batch(batch):
    """检查一批组合"""
    local_results = {}
    for p in batch:
        s = "".join(p)
        crc = binascii.crc32(s.encode()) & 0xffffffff
        if crc in targets:
            local_results[targets[crc]] = s
    return local_results

def main():
    print("开始 CRC32 碰撞爆破...")
    print(f"目标 CRC 数:{len(targets)}")
    print(f"字符集大小:{len(chars)}")
    print(f"总组合数:{len(chars)**4:,}")
    print()
    
    # 分批次处理
    all_combos = itertools.product(chars, repeat=4)
    batch_size = 100000
    batch = []
    completed = 0
    
    with ThreadPoolExecutor(max_workers=8) as executor:
        futures = []
        for combo in all_combos:
            batch.append(combo)
            completed += 1
            
            if len(batch) >= batch_size:
                futures.append(executor.submit(check_batch, batch.copy()))
                batch = []
            
            if completed % 1000000 == 0:
                print(f"进度:{completed:,}/{len(chars)**4:,}")
        
        # 处理剩余
        if batch:
            futures.append(executor.submit(check_batch, batch))
        
        # 收集结果
        for future in futures:
            for name, s in future.result().items():
                if name not in results:
                    results[name] = s
                    print(f"✓ {name} = {s}")
        
        # 检查是否完成
        if len(results) == 6:
            print("\n" + "="*50)
            pwd = "".join([results[f'pass{i}'] for i in range(1, 7)])
            print(f"🎉 密码:{pwd}")
            print("="*50)
            return pwd
    
    print(f"\n只找到 {len(results)}/6 个")
    return None

if __name__ == '__main__':
    main()

或者直接用ZipCracker。

最终得到:

python 复制代码
pass is c1!xxtLf%fXYPkaA

解压后得到:

存在零宽字符隐写。

python 复制代码
txt = open("flag.txt",encoding="utf-8").read()
ZWSP = "\u200b" 
ZWNJ = "\u200c"

bits = []
for char in txt:
    if char == ZWSP:
        bits.append("0")
    elif char == ZWNJ:
        bits.append("1")

flag = ""
for i in range(0,len(bits) - 7 ,8):
    flag += chr(int("".join(bits[i:i+8]),2))

print(flag) 

得到dart{bf4100d9-cc8d-48f6-a095-54cbfad189e1}。

相关推荐
m0_569881472 小时前
使用Flask快速搭建轻量级Web应用
jvm·数据库·python
华科易迅2 小时前
Spring XML事务控制
xml·数据库·spring
天行健,君子而铎2 小时前
联动闭环、精确、动态:医疗行业数据库审计与风险监测实践方案
网络·数据库
2401_873204652 小时前
用Pandas处理时间序列数据(Time Series)
jvm·数据库·python
2301_776508722 小时前
定时任务专家:Python Schedule库使用指南
jvm·数据库·python
艾莉丝努力练剑2 小时前
【Linux信号】Linux进程信号(中):信号保存、信号处理(含“OS是如何运行的?”)
大数据·linux·运维·服务器·数据库·c++·mysql
2301_763891952 小时前
使用Python控制Arduino或树莓派
jvm·数据库·python
山峰哥2 小时前
《解锁SQL高效查询:从索引设计到执行计划优化》
服务器·数据库·sql·oracle·性能优化
2401_874732532 小时前
实战:用Python分析某电商销售数据
jvm·数据库·python