当前位置: 代码迷 >> 综合 >> BUUCTF 打卡9
  详细解决方案

BUUCTF 打卡9

热度:72   发布时间:2023-11-22 18:37:14.0

1.传感器

5555555595555A65556AA696AA6666666955
这是某压力传感器无线数据包解调后但未解码的报文(hex)已知其ID为0xFED31F,请继续将报文完整解码,提交hex。提示1:曼联

曼彻斯特编码:
曼彻斯特编码(Manchester)又称裂相码、同步码、相位编码,是一种用电平跳变来表示1或0的编码方法,其变化规则很简单,即每个码元均用两个不同相位的电平信号表示,也就是一个周期的方波,但0码和1码的相位正好相反。

  • 解码:

第一种约定由1949年由GE托马斯(GE Thomas)所提出。它指定对于0位,信号电平将为低高电平(假设对数据进行幅度物理编码)-在位周期的前半段为低电平,在后半段为高电平。对于1位,信号电平将为高-低。即01 => 0 , 10 => 1。

第二种是IEEE 802.4(令牌总线)和IEEE 802.3(以太网)标准的低速版本所遵循。它指出逻辑0由高-低信号序列表示,逻辑1由低-高信号序列表示。也就是说10代表0,01代表1,这正好也反映了每个码元均用两个不同相位的电平信号表示。

根据别人的wp,得知是每位16进制数转成四位二进制数(位数不够高位补零),再进行转换。ID是用来跟得出的结果进行匹配的,不匹配说明解码错误。如果匹配错误,则根据八位倒序传输协议将二进制每八位reverse。

不过依旧不明白这里为什么要进行八位反转呢?

txt = '5555555595555A65556AA696AA6666666955'
plain =''
for i in txt:plain += bin(int(i,16))[2:].zfill(4)temp = ''
for i in range(0,len(plain),2):temp += plain[i+1]#巧妙根据01->1,10->0来简化操作flag = ''
for i in range(0,len(temp),8):flag += hex(eval('0b'+temp[i:i+8][::-1]))[2:]print(flag.upper())

解出FFFFFED31F645055F9

发现了个小窍门(哈哈哈!!!):
不管题目中曼切斯特编码用的是哪种方法,根据两种方法中的01,10的转换,每四位二进制数进行转换时,
0101正好代表十六进制的5
0110正好代表十六进制的6
1001正好代表十六进制的9
1010正好代表十六进制的A
因此,当密文中只含5,6,9,A时,可以肯定是曼切斯特编码。这个似乎也解释了为什么密文转成二进制时是每位进行转换,且要补成4位二进制数。

2.[BJDCTF2020]编码与调制

在这里插入图片描述

从给出的图片可以看出依次从上到下分别是NRZ(不归零码)、曼切斯特编码、差分曼切斯特编码。
还有一个密文,16进制数,全为5,6,9,A。根据第一题得到的小小窍门。估摸着是曼切斯特编码。那问题来了,是哪种方法呢?又要不要进行二进制八位反转呢?
这里就先用工具试探吧(有工具真的好,啊啊啊,没了工具就是个废物!)

在这里插入图片描述
每次得出的十六进制数转成字节串,看看内容正不正常。

这里给出解出正确结果的代码:


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]#10->1 01->0flag = ''
for i in range(0,len(temp),8):flag +=hex(eval('0b'+temp[i:i+8]))[2:]print(long_to_bytes(eval('0x'+flag)))

解出b’BJD{DifManchestercode}’