CTFHub题解-历年真题-Crypto-2020BJDCTF【编码与调制、base??】
CTFHub题解-历年真题-Crypto篇
2020-BJDCTF-Crypto
(一)编码与调制
本题要点:binascii进制转换、曼彻斯特编码
下载附件看一下:
有一张图,I· m hint,上面有一串二进制01001100011,暂时还不知道是什么意义......
先了解一下曼彻斯特编码和差分曼彻斯特编码
曼彻斯特编码:每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号;从高到低跳变表示"1",从低到高跳变表示"0"。
差分曼彻斯特编码:每位中间的跳变仅提供时钟定时,而用每位开始时有无跳变表示"0"或"1",有跳变为"0",无跳变为"1"。
一:标准曼彻斯特编码波形图1代表从高到低,0代表从低到高
二:差分曼彻斯特编码波形图1代表没有跳变(也就是说上一个波形图在高现在继续在高开始,上一波形图在低继续在低开始)开始画0代表有跳变(也就是说上一个波形图在高位现在必须改在低开始,上一波形图在高位必须改在从低开始)
注:第一个是0的从低到高,第一个是1的从高到低,后面的就看有没有跳变来决定了(差分曼彻斯特编码)
emmmm,看懂了两种编码的原理,感觉那一串二进制好像没什么解题思路呢....还是先看看密文吧.....
密文:2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6
密文看起来像是16进制,但是解转字符串出来是乱码....
参考了一些大佬的wp,发现还有这个16进制转2进制和曼彻斯特编码的转码工具~
为什么选标准曼彻斯特,因为笔者用小工具试了一下 802.3曼彻斯特和差分曼彻斯特,转出来的16进制转字符都是乱码(捂脸)...
曼彻斯特解码之后的16进制我们再转一下字符串~
16进制:024A447B4469664D616E63686573746572636F64657D
咦,第一位没有显示出来诶........当然,比赛的时候,猜的话肯定能猜到是BJD{}......
试试用python转一下呢~
补充一点py的语法~
python内置函数: hex(): #把10进制转整形换成16进制 #内置函数hex和binascii.hexlify()的区别就在于, #hex只能接受整形不能接受字符串
import binascii x=0x024A447B4469664D616E63686573746572636F64657D x=binascii.unhexlify(hex(x)[2:]) print(x)
binascii模块是python的一个用于进制转换的模块,关于binascii.unhexlify感兴趣的小伙伴可以参考这篇博客:
python binascii 二进制转换实例【b2a_hex、a2b_hex、hexlify、unhexlify】
由于笔者的py学的比较差,好多语法都还不会,起初没太明白这个地方的hex(x)[2:]是什么意思.....网上找了半天资料,也没有解释...
后来笔者经过测试和猜测:
x=binascii.unhexlify(hex(x)[2:]) 此处的[2:]应该是读取x的0x这两个字节,因为我发现当把[2:]中的2改成4的时候,输出结果就变成了JD{DifManchestercode};依次变成6/8/10的时候,输出的字符串的开头就会少一位。
因为如果删去[2:],运行会报错binascii.Error: Non-hexadecimal digit found,不识别十六进制数。
啊哦,发现报错~
因为hexstr必须包含偶数个十六进制数字,所以奇数长度会报错。
参考很多大佬的wp都是让添加‘0’,而且我也没有懂为什么要加‘0’,其实只要补一个字节就可以了。
而且之所以会变成奇数长度,主要是因为hex在转换16进制的时候,把x=0x024A...36F64657D开头的024A直接转换成了24A;
所以你其实在x=0x ?24A...36F64657D这里改成任何一个非零的数字就可以。
import binascii x=0x024A447B4469664D616E63686573746572636F64657D x=binascii.unhexlify('0'+hex(x)[2:]) print(x)
运行是正常了,但是结果似乎不太对呢~
难道是转码转错了?但是其他的转出来就更离谱.....
思索了半天,其实报错是因为字符串是一个奇数字符串,所以要加一个字节变成偶数,B的16进制应该是42。
按理说 x=424A447B4469664D616E63686573746572636F64657D 就是正确的flag了
(笔者这属于没事干瞎想,比赛的时候,直接猜就完事了!)
有可能是出题人出错了,也有可能暗含其他玄机,懂得小伙伴可以给我评论,指点一下迷津~
import binascii x=0x424A447B4469664D616E63686573746572636F64657D #此处改成0x42才能运行出正确结果 x=binascii.unhexlify(hex(x)[2:]) print(x)
BJD{DifManchestercode}
完成!
(二)base??
本题要点:base64编解码原理、python基础编程
题目是这样:
emmm....给出了字典,给出了密文,有可能是让我们根据base64编码原理,解明文
先学习一下base64的编码原理:
Base64是一种基于64个可打印字符来表示二进制数据的表示方法
Base64是一种编码方式,提及编码方式,必然有其对应的字符集合。在Base64编码中,相互映射的两个集合是:
二进制数据{0, 1}
{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, /}
Base64编码方式可使得信息在这两种字符集表示法之间相互等价转换。
因为Base64的编码方式是公开的,所以base64也可以算是公开算法的加密方法;但是只能简单的“加密”保护某些数据,决不能在需要安全等级较高的场景中使用,因为可以使用公开的编码方法轻易从base64字符表示的数据解码二进制数据。
base64编码过程
由于base64的字符集大小为64,那么,需要6个比特的二进制数作为一个基本单元表示一个base64字符集中的字符。因为6个比特有2^6=64种排列组合。
具体来说,编码过程如下:
将每三个字节作为一组,共24bit,若不足24bit在其后补充0;
将这24个bit分为4组,每一组6个bit;
在每组前加00扩展为8个bit,形成4个字节,每个字节表示base64字符集索引;
扩展后的8bit表示的整数作为索引,对应base64字符集的一个字符,这就是base64编码值;在处理最后的不足3字节时,缺一个字节索引字节取3个,最后填充一个=,;缺两个字节取2个索引字节,最后填充==。
解码时将过程逆向即可。
# -*- coding: UTF-8 -*- import base64 dict={0: 'J', 1: 'K', 2: 'L', 3: 'M', 4: 'N', 5: 'O', 6: 'x', 7: 'y', 8: 'U', 9: 'V', 10: 'z', 11: 'A', 12: 'B', 13: 'C', 14: 'D', 15: 'E', 16: 'F', 17: 'G', 18: 'H', 19: '7', 20: '8', 21: '9', 22: 'P', 23: 'Q', 24: 'I', 25: 'a', 26: 'b', 27: 'c', 28: 'd', 29: 'e', 30: 'f', 31: 'g', 32: 'h',33: 'i', 34: 'j', 35: 'k', 36: 'l', 37: 'm', 38: 'W', 39: 'X', 40: 'Y', 41: 'Z', 42: '0', 43: '1', 44: '2', 45: '3', 46: '4', 47: '5', 48: '6', 49: 'R', 50: 'S', 51: 'T', 52: 'n', 53: 'o', 54: 'p', 55: 'q', 56: 'r', 57: 's', 58: 't', 59: 'u', 60: 'v', 61: 'w', 62: '+', 63: '/', 64: '='} base64_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'] cipher='FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw' res='' for i in range(len(cipher)): for j in range(64): if(dict[j]==cipher[i]): res+=base64_list[j] print(res) flag=base64.b64decode(res) print(flag)
在线的python环境可以运行出来:
BJD{D0_Y0u_kNoW_Th1s_b4se_map}
完成!
参考资料
https://www.soinside.com/question/JpjZizLwHTBaXKVn3ZzM5g
https://www.cnblogs.com/yinsjun/p/6951588.html
https://www.cnblogs.com/hushaojun/p/7552138.html
--------------------- ┑( ̄Д  ̄)┍ --------------------------
作者:0yst3r[一只在安全领域努力奋斗的小菜鸡]
来源:博客园[ https://www.cnblogs.com/0yst3r-2046/ ] 引用时请注明来源哦~
(๑•̀ㅂ•́)و✧ヽ(✿゚▽゚)ノ(*^▽^*) φ(≧ω≦*)♪
如果本文对你有用,本人不胜欢喜。
The world is your oyster.