记录自己做了一道400分的密码学题!!

题目名称

Not that easy!!

题目描述

Not that easy, only fives!!

my_data.dat:

TFTTTTFFTFTTTTFFTTTFFTTFTTFFFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFTFTFFFFTFTTFFFFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFTFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFTFTFFFFTFTTFFFFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFTFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFFFFTTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFTFFFTFFFTFFFTFTFTTFFTFTTTFTTTFTFFFFFTFFFTFFFTFTFTTFFTF

题目破解

题目给了一个my_data.dat文本,其内容是由‘T’和‘F’所组成。由此我们可以想到‘T’和‘F’很可能对应的是二进制的1和0。接着我们输出该字符串的长度,发现其长度为1824,并且8|1824,所以进一步验证了‘T’,‘F’分别对应着二进制1和0。

因为flag一定是可打印字符,其范围是32~126。我们知道126<27,也就是说,每个字符(二进制表示)的高位一定是0。我们将源文件的‘T’和‘F’交换位置,并用0替换F,1替换T。(因为T是true,所以要和1搭配。F是false,要和0搭配)得到以下的值:

010000110100001100011001001111010001000101111101110111010100110100010001011111011101110101001101111000010111110111011101010011011110000101111101110111010100110100010001011111011101110101001101111000010101110111011101010011010001000101111101110111010100110111100001011111011101110101001101111000010111110111010101010011011110000101011101110111010100110100010001010111011101010101001101000100010101110111011101010011010001000101111101110111010100110111100001011111011101010101001101000100010111110111011101010011010001000101111101110101010100110111100001011111011101110101001101101011110100111100010001010111011101110101001101000100010101110111011101010011011110000101011101110111010100110100010001010111011101110101001101000100010101110111010101010011011110000101111101110111010100110100010001010111011101110101001101111000010101110111011101010011011110000101111101110101010100110111100001011111011101110101001101111000010101110111011101010011010001000101111101110101010100110100010001011111011101010101001101111000010111110111010101010011011110000101111101110111010100110100010001010111011101010101001101000100010101110111011101010011010001000101111101110101010100110100010001011111011101110101001101101011110100111111100001011111011101110101001101000100010111110111011101010011011110000101111101110111010100110111100001011111011101110101001101111000010101110111010101010011010001000101111101110111010100110111100001010111011101010101001101000100010111110111011101010011010001000101011101110111010100110100010001010111011101110101001101000100010111110111011101010011010001000101011101110101010100110100010001010111011101110101001101111000010101110111011101010011010001000101011101110111010100110100010001011111011101110101001101000100010111110111011101010011010001000101011101110111010100110100010001011111011101110101001101

然后我们通过下面的代码,将其转为字符:

import binascii
a1 = hex(int(s,2))[2:]  # 其中s是存储二进制的字符串
print(binascii.unhexlify(a1))

其结果是不可打印字符。

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’,所以我们将源字符串进行逆置操作,得到以下结果:

FTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFFFFTTFTFFFFTFTFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFFFFTTFTFFFFTFTFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFTFTFFFTFFFTFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFTFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFTFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTTFFFFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFTTFTFTFFFTFFFTFFFFFTFTTTFTTTFTFFFFTTFTTFFTTTFFTTTTFTFFTTTTFT

如此看来,每8位的最高位一定是0。接着我们走一遍上述流程得到以下结果:

MDAwMDEwMDAwMDAwMDEwMDExMDEwMTEwMDAwMDEwMDEwMDAwMTExMDAwMTExMDAxMDAxMDAwMDAx\r\nMDAwMTAwMDEwMTEwMDAxMTAxMTAwMTAwMDExMDAxMTAxMDExMDEwMDAxMTEwMDEwMDExMDEwMDEw\r\nMDAxMTAwMDAwMTAxMDAwMDEwMTEwMDExMTAxMDAxMDAwMDExMDAwMDAxMDAxMDAwMDAwCg==

该结果一眼就能看出来是用base64编码过的,所以该结果侧面印证了我们上一步操作的准确性。

import base64
print(base64.b64decode(a))  # a是上述结果
000010000000010011010110000010010000111000111001001000001000100010110001101100100011001101011010001110010011010010001100000101000010110011101001000011000001001000000\n'

解码出来是个0和1组成的字符串,莫非是二进制?这里输出一下字符串的长度是165,无法整除8。我们选择填充之后,转为字符,却得到以下结果:

\x01\x00\x9a\xc1!\xc7$\x11\x166FkG&\x91\x82\x85\x9d!\x82@

看来这一步的思路是错误的。于是考虑到Bacon’s cipher,它是每5位对应一个字符,这与5|165不谋而合。但是Bacon’s cipher 表有两个版本,我们分别进行尝试

# 版本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}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘉·沐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值