一、题目
前几天在ctfshow的qq交流群里看到有个师傅在问一道名为“旋转的base,你见过吗”的题目(但这道题不是ctfshow平台上的啦,后来听说好像是个比赛题),题目给出了一串编码过的字符串,但看题目名也能知道解题肯定不是单纯的base64解码。从聊天记录中截了个图:
问题是如何旋转呢?试了一下将题目中的这串字符倒序后做base64解码和将base64标准表倒序后用解换表题的思路去解,都不对,遂决定把这题先放一放。
二、思路
后来群主出来,召唤大牛解码,大牛一本正经地胡说八道了一个看似是那么回事实则离谱的答案,我这里就不放出来了。哦对了,“大牛”是ctfshow交流群里的聊天机器人,好像是接入的chatgpt, 我总感觉大牛最初给的答案是AGI在试图糊弄人类(?
之后,我又尝试对大牛说了一遍“解码y9tl+gDcvc9Zyc/kvdtYfNtafw+ZfYCYCQAZPUDZicEZvgBk/hwVfpQ”
这次,大牛竟改口说“解不了”,我又对大牛说“旋转的base64”,大牛给出了下图中的回复:
虽然其提供的脚本不太对,直接用是得不到正确答案的,但不得不承认,大牛的回复确实启发了我,有了解题的思路后就可以很容易的修改脚本去拿到flag。
思路就是,题目中需要解码的字符串就是用将base64标准表循环移动了某位后得到的表编码得到的,因此这实际上仍是一个换表题,只是暂时不知道换成了什么样子的表因为不知道移动了几位。
那就简单粗暴地试一下移动了几位就好了啊,下面借着大牛的思路和脚本,直接给出我修改后的脚本吧。
三、解题脚本
import base64def rotate_base64(s, n):base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"rotated_chars = base64_chars[n:] + base64_chars[:n]#print('旋转后:',rotated_chars)l=[]for ss in s:l.append(rotated_chars.index(ss))temp=''for ll in l:temp+=base64_chars[ll]f=base64.b64decode(temp)if b'flag' in f:print(f) #b'flag%7B416d3b4a10a9925363a44275d8655c5d%7D'print(n) #12s = "ly9tl+gDcvc9Zyc/kvdtYfNtafw+ZfYCYCQAZPUDZicEZvgBk/hwVfpQ"
for n in range(1,64):rotate_base64(s, n)
通过自己写脚本知道了是向左(逆时针)旋转12位,编码用的表变成了MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKL
再回过头看看大牛的代码,发现它只是把
table = str.maketrans(base64_chars, rotated_chars)中函数的两个参数写反了,交换一下两个参数的位置即可,然后现在又已经知道了n=12,只要修改这两处就可以得到flag了,脚本如下:
import base64def rotate_base64(s, n):base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"rotated_chars = base64_chars[n:] + base64_chars[:n]table = str.maketrans(rotated_chars, base64_chars)return base64.b64decode(s.translate(table))s = "ly9tl+gDcvc9Zyc/kvdtYfNtafw+ZfYCYCQAZPUDZicEZvgBk/hwVfpQ"
n = 12
print(rotate_base64(s, n))
#b'flag%7B416d3b4a10a9925363a44275d8655c5d%7D'
其中,table = str.maketrans(rotated_chars, base64_chars)是得到了换了的表和标准表中元素下标的对应关系,s.translate(table)得到的值就是字符串s改用标准base64表编码的结果:ZmxhZyU3QjQxNmQzYjRhMTBhOTkyNTM2M2E0NDI3NWQ4NjU1YzVkJTdE
以上这些都是通过看大牛的脚本新学到的内容哎!虽然估计以后也不会用,还是会用自己顺手的老方法哈哈(小声