一、题目描述
打开题目链接文件,一看妥妥的python代码,最后一行print函数后面注释了一串字符串:
]$^<[<?^<$[^:^}?<$[^$$}?>$<<}?):>$?$:<}?>^-^?$[<^^}??${<&?}?$$}>$?#$$^[^)^^^@
题目代码
flag=""
old_str = ''
new_str= []
enc_data = ''
conversion_table="{[:<>?^$%&(#)]-}"
#flag 经过第一个循环得到了新的字符串,old_str
for i in flag:
old_str += bin(ord(i))[2:].rjust(8,'0')
#
for i in range(0,len(old_str),4):
print(i)
new_str.append(old_str[i:i+4].ljust(4,'0'))
new_str.reverse()
for i in new_str:
enc_data += conversion_table[int(i,2)]
if len(flag) % 3 == 1:
enc_data += "@"
elif len(flag) % 3 == 2:
enc_data += "@"
print(enc_data) # ]$^<[<?^<$[^:^}?<$[^$$}?>$<<}?):>$?$:<}?>^-^?$[<^^}??${<&?}?$$}>$?#$$^[^)^^^@
二、解题分析
把代码复制到vscode 方便调试分析
从整个代码看很明显了,明文作为flag值输入,密文输出,在print函数中注释留的字符串应该就是flag值加密后得到的密文:
]$^<[<?^<$[^:^}?<$[^$$}?>$<<}?):>$?$:<}?>^-^?$[<^^}??${<&?}?$$}>$?#$$^[^)^^^@
1.分析过程
初次做crypto类型的题目,我的做法从整体上读懂代码的执行流程,过程中即使有些函数不知道是什么功能也不要紧,后面可以百度该函数的作用。一段一段的分析代码功能,中间不清楚的地方可以用函数打印结果
2.还原加密
最后还原出flag为:flag{WOw_Y0u_f1und_2ut,_3t_was_base16}
还原代码:
#enc_data="]$^<[<?^<$[^:^}?<$[^$$}?>$<<}?):>$?$:<}?>^-^?$[<^^}??${<&?}?$$}>$?#$$^[^)^^^"
from turtle import st
#代码实现还原解密
#字符替换表
#密文 ]$^<[<?^<$[^:^}?<$[^$$}?>$<<}?):>$?$:<}?>^-^?$[<^^}??${<&?}?$$}>$?#$$^[^)^^^@
conversion_table="{[:<>?^$%&(#)]-}"
#最后的符号@可以直接去掉,还原了第五步
enc_data="]$^<[<?^<$[^:^}?<$[^$$}?>$<<}?):>$?$:<}?>^-^?$[<^^}??${<&?}?$$}>$?#$$^[^)^^^"
#加密,代码执行是从上而下的,在还原的时候应该是从下而上
#第四步还原
str_value=[]
#加密过程
#在加密过程中,enc_data的值是根据(下标索引)在conversion_table 字符替换表中取出来的,(下标索引)是怎么来的,
# 是由int(i,2) 转换来的int(i,2)==下标,知道了下标就知道了i,知道了i就能还原出第四步之前的new_str值
# 第四步还原流程:enc_data[i]->i->bin(i)->new_str
for i in range(0,len(enc_data)):
for j in range(0,len(conversion_table)):
# 我们怎么才能知道enc_data原来的值呢??这里拿enc_data每一个字符去到字符替换表找这个字符出现的
# 下标索引位置,该索引值就是二进制值,由于拿到的索引值是十进制,使用bin函数转为二进制切片去掉0b,高位补零之后,
# 存放在str_value中
if enc_data[i] == conversion_table[j]:
str_value.append(bin(j)[2:].rjust(4,'0'))
#第三步翻转还原
str_value.reverse()
old_str = ''
print(str_value)
#还原第二步
#第二步之前是字符串,这里把字符串数组进行拼接即可
for i in range(0,len(str_value)):#
old_str+=(str_value[i])
#还原第一步
#从字符串从每一次取8位,转为整型数值,得到的数值是assic表值,用chr函数转为字符,即可还原到最初形态。
for i in range(0,len(old_str),8):
k=old_str[i:i+8]
print(chr(int(k,2)), end="")
总结
初次打ctf做这类型的题目,感觉做完之后对还原代码的效率还是不够快。