CTFshow之CRYPTO从入门到精通全解:超级详解+精讲【3】

_萌新

(1)萌新_密码1

在这里插入图片描述
接下来开始分析及解题。


一、题目分析

1. 密文特征

  • 密文由 0-9A-F 组成,符合 十六进制(Hex) 编码的特征。
    • 字符集:仅包含 0-9 和 A-F,每两位表示一个字节(0~255)。

    • 长度:总长度104为偶数(因 2 Hex 字符 = 1 字节)。

2. 预期目标
通过逐步解码和密码破解,最终得到 KEY{XXXXXXXXXXXXXX} 格式的明文。

二、解题过程详细

第1步:Hex → 字符串

  • 原始密文:
    53316C6B5A6A42684D3256695A44566A4E47526A4D5459774C5556375A6D49324D32566C4D4449354F4749345A6A526B4F48303D
  • 使用 Python 或在线工具将 Hex 转换为 ASCII 字符串:
    bytes.fromhex("53316C6B5A6A42684D3256695A44566A4E47526A4D5459774C5556375A6D49324D32566C4D4449354F4749345A6A526B4F48303D").decode('utf-8')
    
  • 转换结果:
    S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0=

第2步:观察字符串特征

  • 转换后的字符串 S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0=
    字符集:包含 A-Z、a-z、0-9、+、/ 和末尾的 =(填充符),符合 Base64 标准字符集。
    长度特征:长度是 4 的倍数(此处为 52 字符,含 = 填充)。

第3步:尝试 Base64 解码

  • 输入:S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0=
  • Base64 解码(注意去掉末尾的 = 尝试):
    import base64
    base64.b64decode("S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0=").decode('utf-8')
    
  • 解码结果:
    KYdf0a3ebd5c4dc160-E{fb63ee0298b8f4d8}

第4步:分析解码结果

  • 解码后字符串:KYdf0a3ebd5c4dc160-E{fb63ee0298b8f4d8}
    • 前半部分 KYdf0a3ebd5c4dc160 像随机字符。
    • 后半部分 -E{fb63ee0298b8f4d8} 类似 KEY{...} 格式,但开头是 -E 不是 KEY
    • 可能是 栅栏密码其他加密方式 的密文。

第5步:尝试栅栏密码解密
栅栏密码的原理是将明文按“之字形”排列后按行读取。解密时需要尝试不同栏数(密钥)。
这里不同的栏数去尝试:
(1)传统栅栏密码

  • 输入字符串:KYdf0a3ebd5c4dc160-E{fb63ee0298b8f4d8}
  • 尝试栏数 = 2
    • 解密方法:
      将密文分成两行,按“之字形”重新排列。
    • 解密结果:
      KEY{dffb06a33eeeb0d259c84bd8cf146d08-} 符合 KEY{...} 格式。

在这里插入图片描述
!这里注意:
W型栅栏密码是传统栅栏密码的变种,栏数=2时与传统栅栏一致。

栏数=2的解密结果与传统栅栏一致,无需额外尝试。

三、总结

  1. 解题流程
    • Hex → ASCII → Base64 → 栅栏解密(栏数=2)。
  2. 关键点
    • 无提示时需尝试常见编码(Hex、Base64)。
    • 栅栏密码需尝试不同栏数,栏数=2时解密结果符合格式。
  3. 最终答案
    KEY{dffb06a33eeeb0d259c84bd8cf146d08-}

附:完整解密代码(Python)

import base64

# Hex to ASCII
hex_str = "53316C6B5A6A42684D3256695A44566A4E47526A4D5459774C5556375A6D49324D32566C4D4449354F4749345A6A526B4F48303D"
ascii_str = bytes.fromhex(hex_str).decode('utf-8')
print("Hex → ASCII:", ascii_str)  # S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0=

# Base64 decode
base64_str = "S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0="
decoded_str = base64.b64decode(base64_str).decode('utf-8')
print("Base64 → Plaintext:", decoded_str)  # KYdf0a3ebd5c4dc160-E{fb63ee0298b8f4d8}

# Rail Fence Decryption (栏数=2)
def rail_fence_decrypt(cipher, rails):
    fence = [[] for _ in range(rails)]
    rail = 0
    direction = 1
    for _ in cipher:
        fence[rail].append(None)
        rail += direction
        if rail == rails - 1 or rail == 0:
            direction = -direction
    index = 0
    for i in range(rails):
        for j in range(len(fence[i])):
            fence[i][j] = cipher[index]
            index += 1
    rail = 0
    direction = 1
    plaintext = []
    for _ in cipher:
        plaintext.append(fence[rail].pop(0))
        rail += direction
        if rail == rails - 1 or rail == 0:
            direction = -direction
    return ''.join(plaintext)

cipher = "KYdf0a3ebd5c4dc160-E{fb63ee0298b8f4d8}"
print("Rail Fence (2):", rail_fence_decrypt(cipher, 2))  # KEY{dffb06a33eeeb0d259c84bd8cf146d08-}

输出得到:
在这里插入图片描述

★KEY{dffb06a33eeeb0d259c84bd8cf146d08-}


(2)萌新_密码2

在这里插入图片描述
接下来开始分析及解题。


一、题目分析及解题:

  • 题目提到键盘,提示解密关联到键盘,且密文有中出现了空格,可能是某种暗示,可能明文是不同部分的组成;
  • 且三个。。。也是某种暗示;

接下来便来观察键盘:
在这里插入图片描述
rdcvbg、2qase3、6tghu7,均为6个字符的组合,尝试在键盘上按顺序去标记,发现每组密文可以组成一个闭合的圈,也就是起来了,联想到题目的三个。。。就是暗示起来。

因此明文就是三个被围起来的FWY/fwy(交的时候大小写自行测试再判断)

在这里插入图片描述
得到:

★KEY{fwy}

二、总结

通过这道键盘密码题,我深刻体会到CTF解题的几个关键要点:

1. 信息整合能力
题目中"随便敲键盘"和"。"的提示,结合三组6字符密文的特征,自然引导我们想到要在键盘布局上寻找规律。这说明抓住题目给出的每一个线索都至关重要。

2. 可视化思维
将抽象的密文字符在键盘上实际标注出来,这种空间可视化方法让"围住字母"的概念变得具体可操作。在密码题中,画图往往能打开思路。

3. 模式识别技巧
发现三组密文都采用"字母包围+数字定界"的统一结构,这种模式识别能力需要培养。相似的解题模式在其他密码题中也会反复出现。

4. 验证迭代过程
从三个。。。的作用不是很确定到实际键盘上密文的具象化围住推导验证了 起来作用。题目线索不确定在刚开始的不确定通过实际验证确定其作用。

这道题很好地诠释了CTF解题的通用方法:仔细审题→建立假设→可视化验证→总结规律。这种结构化思维不仅适用于密码学,也是解决各类技术问题的有效途径。通过这样循序渐进的思考,即使最初看似晦涩的题目,其解答路径也会逐渐清晰起来。


(3)萌新_密码3

在这里插入图片描述

– — .-. … . …–.- … … …–.- -.-. — — .-… …–.- -… …- - …–.- -… .- -.-. — -. …–.- … … …–.- -.-. — — .-… . .-. …–.- – – -… -… – -… – -… – – – -… -… -… /-- -… – -… -… --/ – – – – – /-- -… -… – -… – /-- -… -… –

接下来开始分析及解题。


一、题目分析详解

  1. 题目名称与描述
  • 题目名称:我想吃培根

    • 提示可能与培根密码(Bacon’s Cipher)相关。
  • 题目描述给出的密文很容易想到是需要摩斯密码解码的,之后再进一步分析。

二、解题

使用标准摩斯电码表解码得到结果如下:

MORSE_IS_COOL_BUT_BACON_IS_COOLER_MMDDMDMDMMMDDDMDMDDMMMMMMMDDMDMMDDM

这里观察分析,提到了Morse(摩斯)也提到了BACON(培根),说明需要确实用到培根密码解码。

这里暂时将之前得到的摩斯解码结果的前面的内容看作只是提示信息,重点关注后面:

MMDDMDMDMMMDDDMDMDDMMMMMMMDDMDMMDDM
35个字符为5的倍数 只有两种字符,接下来要关联到培根密码

想到培根密码,自然要知道培根密码(Bacon’s Cipher)是一种用两组符号(如 A 和 B)表示字母的加密方式。

因此,需要将M 和 D 可以分别对应 A 和 B或者 B 和 A (自主尝试)

先考虑将M 和 D 可以分别对应 A 和 B

得到:

AABBABABAAABBBABABBAAAAAAABBABAABBA

由于培根密码每5位代表一个字母,则整理可得:

AABBA+BABAA+ABBBA+BABBA+AAAAA+ABBAB+AABBA

尝试培根密码解码脚本或工具(如:随波逐流)
在这里插入图片描述

最后整理格式得到:

★flag{GUOWANG}

补充培根密码解码脚本:

def decode_bacon(ciphertext, variant='standard'):
    """
    将培根密码解密为明文
    
    参数:
    ciphertext (str): 待解密的培根密码字符串
    variant (str): 培根密码变体,默认为 'standard'
    
    返回:
    str: 解密后的明文字符串
    """
    # 移除所有非A和B的字符
    ciphertext = ''.join([c for c in ciphertext.upper() if c in ['A', 'B']])
    
    # 标准培根密码对照表
    bacon_dict = {
        'AAAAA': 'A', 'AAAAB': 'B', 'AAABA': 'C', 'AAABB': 'D', 'AABAA': 'E',
        'AABAB': 'F', 'AABBA': 'G', 'AABBB': 'H', 'ABAAA': 'I', 'ABAAB': 'J',
        'ABABA': 'K', 'ABABB': 'L', 'ABBAA': 'M', 'ABBAB': 'N', 'ABBBA': 'O',
        'ABBBB': 'P', 'BAAAA': 'Q', 'BAAAB': 'R', 'BAABA': 'S', 'BAABB': 'T',
        'BABAA': 'U', 'BABAB': 'V', 'BABBA': 'W', 'BABBB': 'X', 'BBAAA': 'Y',
        'BBAAB': 'Z'
    }
    
    # 根据变体调整对照表
    if variant == 'alternative':
        # 变体培根密码对照表(I/J和U/V合并)
        bacon_dict = {
            'AAAAA': 'A', 'AAAAB': 'B', 'AAABA': 'C', 'AAABB': 'D', 'AABAA': 'E',
            'AABAB': 'F', 'AABBA': 'G', 'AABBB': 'H', 'ABAAA': 'I/J', 'ABAAB': 'K',
            'ABABA': 'L', 'ABABB': 'M', 'ABBAA': 'N', 'ABBAB': 'O', 'ABBBA': 'P',
            'ABBBB': 'Q', 'BAAAA': 'R', 'BAAAB': 'S', 'BAABA': 'T', 'BAABB': 'U/V',
            'BABAA': 'W', 'BABAB': 'X', 'BABBA': 'Y', 'BABBB': 'Z'
        }
    
    # 按每5个字符分割密文
    chunks = [ciphertext[i:i+5] for i in range(0, len(ciphertext), 5)]
    
    # 解密
    plaintext = ''
    for chunk in chunks:
        if len(chunk) == 5:  # 只处理完整的5字符块
            plaintext += bacon_dict.get(chunk, '?')
    
    return plaintext

# 测试给定的培根密码
ciphertext = "AABBABABAAABBBABABBAAAAAAABBABAABBA"
plaintext = decode_bacon(ciphertext)
print(f"密文: {ciphertext}")
print(f"明文: {plaintext}")    

输出结果如下:
在这里插入图片描述

三、总结
六、总结思考

  1. 关键转折点:

从摩斯电码中发现"BACON"提示

识别出M/D对应A/B的替换规则

  1. 易错点:

培根密码分组时可能多算或少算

需要结合上下文判断解码结果的合理性

总之,成功的解题需要在理论运用到实践中逐渐逻辑清晰,线索可能是在解题过程中逐渐齐全,不要因为一开始的迷茫而摆烂放弃。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值