-
-
[原创]记录自己做了一道400分的密码学题!!
-
发表于: 2020-11-30 15:24 4571
-
题目名称
<font color = 'blue' size = '6'>Not that easy!!</font>
题目描述
Not that easy, only fives!!
my_data.dat:
1 | TFTTTTFFTFTTTTFFTTTFFTTFTTFFFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFTFTFFFFTFTTFFFFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFTFTFFFFTFTTFFFFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTF |
题目破解
题目给了一个my_data.dat文本,其内容是由‘T’和‘F’所组成。由此我们可以想到‘T’和‘F’很可能对应的是二进制的1和0。接着我们输出该字符串的长度,发现其长度为1824,并且8|1824,所以进一步验证了‘T’,‘F’分别对应着二进制1和0。
因为flag一定是可打印字符,其范围是32~126。我们知道126<2<sup>7</sup>,也就是说,每个字符(二进制表示)的高位一定是0。我们将源文件的‘T’和‘F’交换位置,并用0替换F,1替换T。(因为T是true,所以要和1搭配。F是false,要和0搭配)得到以下的值:
1 | 010000110100001100011001001111010001000101111101110111010100110100010001011111011101110101001101111000010111110111011101010011011110000101111101110111010100110100010001011111011101110101001101111000010101110111011101010011010001000101111101110111010100110111100001011111011101110101001101111000010111110111010101010011011110000101011101110111010100110100010001010111011101010101001101000100010101110111011101010011010001000101111101110111010100110111100001011111011101010101001101000100010111110111011101010011010001000101111101110101010100110111100001011111011101110101001101101011110100111100010001010111011101110101001101000100010101110111011101010011011110000101011101110111010100110100010001010111011101110101001101000100010101110111010101010011011110000101111101110111010100110100010001010111011101110101001101111000010101110111011101010011011110000101111101110101010100110111100001011111011101110101001101111000010101110111011101010011010001000101111101110101010100110100010001011111011101010101001101111000010111110111010101010011011110000101111101110111010100110100010001010111011101010101001101000100010101110111011101010011010001000101111101110101010100110100010001011111011101110101001101101011110100111111100001011111011101110101001101000100010111110111011101010011011110000101111101110111010100110111100001011111011101110101001101111000010101110111010101010011010001000101111101110111010100110111100001010111011101010101001101000100010111110111011101010011010001000101011101110111010100110100010001010111011101110101001101000100010111110111011101010011010001000101011101110101010100110100010001010111011101110101001101111000010101110111011101010011010001000101011101110111010100110100010001011111011101110101001101000100010111110111011101010011010001000101011101110111010100110100010001011111011101110101001101 |
然后我们通过下面的代码,将其转为字符:
1 2 3 | import binascii a1 = hex ( int (s, 2 ))[ 2 :] # 其中s是存储二进制的字符串 print (binascii.unhexlify(a1)) |
其结果是不可打印字符。
1 | CC\x19 = \x11}\xddM\x11}\xddM\xe1}\xddM\xe1}\xddM\x11}\xddM\xe1]\xddM\x11}\xddM\xe1}\xddM\xe1}\xd5M\xe1]\xddM\x11]\xd5M\x11]\xddM\x11}\xddM\xe1}\xd5M\x11}\xddM\x11}\xd5M\xe1}\xddM\xafO\x11]\xddM\x11]\xddM\xe1]\xddM\x11]\xddM\x11]\xd5M\xe1}\xddM\x11]\xddM\xe1]\xddM\xe1}\xd5M\xe1}\xddM\xe1]\xddM\x11}\xd5M\x11}\xd5M\xe1}\xd5M\xe1}\xddM\x11]\xd5M\x11]\xddM\x11}\xd5M\x11}\xddM\xafO\xe1}\xddM\x11}\xddM\xe1}\xddM\xe1}\xddM\xe1]\xd5M\x11}\xddM\xe1]\xd5M\x11}\xddM\x11]\xddM\x11]\xddM\x11}\xddM\x11]\xd5M\x11]\xddM\xe1]\xddM\x11]\xddM\x11}\xddM\x11}\xddM\x11]\xddM\x11}\xddM |
根据打印结果来看,结果中出现了很多超过ascii码为127的字符,这也就说明源字符串每8位的最高位出现了不是0的情况。原来是对源字符串处理不当产生的问题。继续观察源字符串发现,每8位的最低有效位一定是‘F’,那也就是说是‘0’,所以我们将源字符串进行逆置操作,得到以下结果:
1 | FTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFFFFTTFTFFFFTFTFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFFFFTTFTFFFFTFTFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFFFTTFTTFFTTTFFTTTTFTFFTTTTFT |
如此看来,每8位的最高位一定是0。接着我们走一遍上述流程得到以下结果:
1 | MDAwMDEwMDAwMDAwMDEwMDExMDEwMTEwMDAwMDEwMDEwMDAwMTExMDAwMTExMDAxMDAxMDAwMDAx\r\nMDAwMTAwMDEwMTEwMDAxMTAxMTAwMTAwMDExMDAxMTAxMDExMDEwMDAxMTEwMDEwMDExMDEwMDEw\r\nMDAxMTAwMDAwMTAxMDAwMDEwMTEwMDExMTAxMDAxMDAwMDExMDAwMDAxMDAxMDAwMDAwCg = = |
该结果一眼就能看出来是用base64编码过的,所以该结果侧面印证了我们上一步操作的准确性。
1 2 | import base64 print (base64.b64decode(a)) # a是上述结果 |
1 | 000010000000010011010110000010010000111000111001001000001000100010110001101100100011001101011010001110010011010010001100000101000010110011101001000011000001001000000 \n' |
解码出来是个0和1组成的字符串,莫非是二进制?这里输出一下字符串的长度是165,无法整除8。我们选择填充之后,转为字符,却得到以下结果:
1 | \x01\x00\x9a\xc1!\xc7$\x11\x166FkG&\x91\x82\x85\x9d!\x82@ |
看来这一步的思路是错误的。于是考虑到Bacon's cipher,它是每5位对应一个字符,这与5|165不谋而合。但是Bacon's cipher 表有两个版本,我们分别进行尝试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 版本1 dic1 = { '00000' : "A" , '00001' : 'B' , '00010' : 'C' , '00011' : 'D' , "00100" : "E" , "00101" : 'F' , "00110" : 'G' , "00111" : 'H' , '01000' : 'I' , '01001' : 'K' , '01010' : 'L' , '01011' : 'M' , '01100' : 'N' , '01101' : 'O' , '01110' : 'P' , '01111' : 'Q' , '10000' : 'R' , '10001' : 'S' , '10010' : 'T' , '10011' : 'U' , '10100' : 'W' , '10101' : 'X' , '10110' : 'Y' , '10111' : 'Z' } # 版本2 每个字符对应着相应的值 dic2 = { '00000' : "A" , '00001' : 'B' , '00010' : 'C' , '00011' : 'D' , "00100" : "E" , "00101" : 'F' , "00110" : 'G' , "00111" : 'H' , '01000' : 'I' , '01001' : 'J' , '01010' : 'K' , '01011' : 'L' , '01100' : 'M' , '01101' : 'N' , '01110' : 'O' , '01111' : 'P' , '10000' : 'Q' , '10001' : 'R' , '10010' : 'S' , '10011' : 'T' , '10100' : 'U' , '10101' : 'V' , '10110' : 'W' , '10111' : 'X' , '11000' : 'Y' , '11001' : 'Z' } a = [ '00001' , '00000' , '00010' , '01101' , '01100' , '00010' , '01000' , '01110' , '00111' , '00100' , '10000' , '01000' , '10001' , '01100' , '01101' , '10010' , '00110' , '01101' , '01101' , '00011' , '10010' , '01101' , '00100' , '01100' , '00010' , '10000' , '10110' , '01110' , '10010' , '00011' , '00000' , '10010' , '00000' ] flag1 = '' for i in a: for j in dic1: if i = = j: flag + = dic1[j] break print (flag1) # BACONCIPHERISNOTGOODTOENCRYPTDATA # 同理输出flag2 # BACNMCIOHEQIRMNSGNNDSNEMCQWOSDASA |
flag1输出的是一句话,更像是flag。
所以flag=JISCTF{BACONCIPHERISNOTGOODTOENCRYPTDATA}
粗体文本
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [原创]搞懂差分密码分析,这篇文章就够了 18418
- [原创]记录自己做了一道400分的密码学题!! 4572
- [原创]RSA数字签名?原来这么好理解! 17341