下载看到附件:
# flag = 'xxxxxxxxxxxxxxxxxx'
# list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
# result = ''
# for i in range(len(list)):
# key = (list[i]>>4) + ((list[i] & 0xf) << 4) # key加密解密过程中都不变
# result += str(hex(ord(flag[i]) ^ key))[2:].zfill(2)
# print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
先解释解释先关函数:
ord()函数:是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了 Python 定义范围,则会引发一个 TypeError 的异常。
hex()函数:hex() 函数用于将10进制整数转换成16进制,以字符串形式表示。(结果自带0x前缀)
str()函数:str函数是Python的内置函数,它将参数转换成字符串类型,即人适合阅读的形式。
zfill():zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0。
切片:切片
现在简单分析一下加密过程:
我们要求flag,现在知道flag和key进行异或运算就得到了result(key和result是以知的)
因为异或运算是可逆的,所以 result 和 key 异或就可以得到flag
加密过程:
for i in range(len(list)):
key = (list[i]>>4) + ((list[i] & 0xf) << 4) # key加密解密过程中都不变,所以可以不在意key
result += str(hex(ord(flag[i]) ^ key))[2:].zfill(2)
加密过程分析
4.再将异或的结果转成字符
5.将得到的字符切片(因为hex函数返回的是带0x前缀的,要去掉0x)
6.使用zfill函数让得到的字符补足两位
exp:
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = 'bcfba4d0038d48bd4b00f82796d393dfec'
flag = ''
print(result)
for i in range(len(list)):
key = (list[i] >> 4)+((list[i] & 0xf) << 4)
flag += chr(int(result[2 * i:2 * i + 2], 16) ^ key)
print(result[2 * i:2 * i + 2])
print(flag)
result[2 * i:2 * i + 2] 因为转为十六进制的原因所以都是两个一组两个一组的
第一次当i等于0时(2*0:2*0+2)是第0个到底2个
int(..., 16):将切片得到的两个字符从16进制数转为10进制整数
NSSCTF{EZEZ_RERE}