BUUCTF 编码与调制实战:从曼彻斯特到差分曼彻斯特的CTF信号解码

发布时间:2026/7/16 23:00:44
BUUCTF 编码与调制实战:从曼彻斯特到差分曼彻斯特的CTF信号解码 1. 曼彻斯特编码的CTF实战解码技巧第一次在BUUCTF遇到曼彻斯特编码的题目时我盯着那串5555555595555A65556AA696AA6666666955的十六进制数据发了半天呆。后来才发现这类题目其实有规律可循只要掌握几个关键点就能轻松破解。曼彻斯特编码最让人头疼的就是它的两种不同约定标准。我在实际解题过程中发现第一种标准GE Thomas提出将01对应010对应1而第二种标准IEEE 802.3/802.4使用则正好相反10对应001对应1。这个区别直接影响到最终解码结果是否正确。这里分享一个我总结的快速识别技巧当密文中只出现5、6、9、A这几个十六进制字符时基本可以确定是曼彻斯特编码。因为0101二进制对应十六进制50110对应61001对应91010对应A解码时我通常分三步走将每个十六进制字符转为4位二进制每两位二进制按编码规则转换01→1或10→1取决于采用哪种标准将转换后的二进制数据按8位一组转为十六进制txt 5555555595555A65556AA696AA6666666955 plain for i in txt: plain bin(int(i,16))[2:].zfill(4) # 十六进制转4位二进制 temp for i in range(0,len(plain),2): temp plain[i1] # 按第二种标准转换取每对的第二位 flag for i in range(0,len(temp),8): flag hex(eval(0btemp[i:i8][::-1]))[2:] # 8位一组转十六进制 print(flag.upper())2. 差分曼彻斯特编码的识别与处理差分曼彻斯特编码比普通曼彻斯特更复杂一些但CTF题目中出现的频率也不低。我遇到的一道典型题目是[BJDCTF2020]编码与调制题目给出了NRZ、曼彻斯特和差分曼彻斯特三种编码的对比图。差分曼彻斯特的特点是每个比特周期开始时都会有一次电平跳变比特中间根据数值决定是否跳变0有跳变1无跳变解码时不依赖绝对电平而是看跳变沿实战中我发现一个快速判断方法如果数据中出现大量连续的5或A很可能是差分曼彻斯特编码。因为稳定的时钟信号会表现为规律的电平变化。解码差分曼彻斯特时我常用的Python脚本如下from Crypto.Util.number import * txt 2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6 temp for i in txt: pd bin(int(i,16))[2:].zfill(4) temp pd[0] pd[2] # 特殊处理差分曼彻斯特 flag for i in range(0,len(temp),8): flag hex(eval(0btemp[i:i8]))[2:] print(long_to_bytes(eval(0xflag)))这个脚本的关键在于对每4位二进制数的特殊处理方式通过取特定位来还原原始数据。在实际比赛中如果一种解码方式不奏效可以尝试将二进制数据反转后再解码有时会有意外收获。3. CTF中常见的编码混合题型很多CTF题目不会直接告诉你使用哪种编码方式而是将多种编码方式混合使用。我遇到过最棘手的一道题是将NRZ、曼彻斯特和ASCII编码混合在一起。解题时我总结了一套流程先观察数据特征长度、字符分布、特殊字符尝试常见编码转换hex、base64、ASCII检查是否有规律的电平变化模式用Python脚本批量尝试不同解码方式例如下面这段数据48 65 6C 6C 6F 20 57 6F 72 6C 64 21 5A 5A 5A 5A A6 A6 A6 A6前半部分明显是ASCII码后半部分突然变成5A和A6交替这就提示可能需要切换解码方式。对于混合编码题目我建议准备一个多功能的解码脚本import binascii from Crypto.Util.number import * def try_decodings(data): # 尝试ASCII try: print(ASCII:, bytes.fromhex(data).decode(ascii)) except: pass # 尝试Base64 try: print(Base64:, b64decode(bytes.fromhex(data)).decode()) except: pass # 尝试曼彻斯特解码 manchester_decoded manchester_decode(data) print(Manchester:, manchester_decoded) # 其他解码方式...4. 实战中的二进制处理技巧在信号解码类题目中二进制处理是最基础也是最重要的技能。我总结了几种常见场景的处理方法二进制反转问题 很多传感器数据传输时会采用LSB-first或MSB-first的不同约定。如果解码后发现数据不对可以尝试反转二进制位序binary 11001010 reversed_bin binary[::-1] # 反转位序二进制与十六进制转换 Python的bin()函数生成的二进制字符串会带0b前缀记得去掉hex_str 5A binary bin(int(hex_str, 16))[2:].zfill(8) # 转8位二进制处理不完整字节 当二进制数据长度不是8的倍数时需要特别处理binary_data 110101001 # 补零到完整字节 if len(binary_data) % 8 ! 0: binary_data binary_data.zfill((len(binary_data)//8 1)*8)多进制转换技巧 有时需要直接在十六进制、十进制和二进制间转换# 十六进制转十进制 dec int(FF, 16) # 十进制转二进制字符串 bin_str format(255, 08b)在实际比赛中我通常会准备一个包含这些常用函数的工具脚本遇到编码题目时快速尝试各种可能性。记住信号解码类题目的关键就是多尝试、多验证不要被表面的复杂度吓倒。