# afctf 一道有趣的题目
链接
#加密代码 | |
def encrypt(plainText): | |
space = 10 | |
cipherText = "" | |
for i in range(len(plainText)): | |
if i + space < len(plainText) - 1: | |
cipherText += chr(ord(plainText[i]) ^ ord(plainText[i + space])) | |
else: | |
cipherText += chr(ord(plainText[i]) ^ ord(plainText[space])) | |
if ord(plainText[i]) % 2 == 0: | |
space += 1 | |
else: | |
space -= 1 | |
return cipherText | |
# 密码 | |
# 15120d1a0a0810010a031d3e31000d1d170d173b0d173b0c07060206 |
首先可以知道明文的长度
这里有一个坑,他给的是 hex,要转成字节,28 位
要知道每一位的奇偶性,才能知道 space 的变化
28 位可以爆破
def get_temp(cipher): | |
for x in range(1 << len(cipher)): | |
temp = bin(x)[2:].zfill(len(cipher)) | |
space = 10 | |
flag = 0 | |
for i in range(len(temp)): | |
if i + space < len(temp) - 1: | |
tempx = int(temp[i]) ^ int(temp[i + space]) | |
else: | |
tempx = int(temp[i]) ^ int(temp[space]) | |
if tempx != (cipher[i] % 2): | |
flag = 1 | |
break | |
elif int(temp[i]) % 2 == 0: | |
space += 1 | |
else: | |
space -= 1 | |
if flag != 1: | |
return temp | |
break |
得到末位的奇偶性
然后得到每一位和另一位的异或
space=10 | |
c=[] | |
for i in range(len(cipher)): | |
if i + space < 28 - 1: | |
a=[i,i+space] | |
else: | |
a=[i,space] | |
if ord(tmp[i]) % 2 == 0: | |
space += 1 | |
else: | |
space -= 1 | |
c.append(a) | |
print(c) |
因为这道题目的 flag 是以 'afctf {' 开头的,就可以继续爆破了
plain=['a','f','c','t','f','{']+[-1]*22 | |
while -1 in plain: | |
for i in range(26): | |
if(plain[i]!=-1): | |
plain[c[i][1]]=chr(cipher[i]^ord(plain[i])) | |
elif(plain[c[i][1]]!=-1): | |
plain[i]=chr(cipher[i]^ord(plain[c[i][1]])) | |
for i in plain: | |
print(i,end='') |