下载地址:
https://adworld.xctf.org.cn/match/list?event_hash=a37c4ee0-1808-11ee-ab28-000c29bc20bf
题目代码分析:
- #这两行导入了Python标准库中的 random 和 string 模块,用于生成随机数和处理字符串
- import random
- import string
-
- characters = string.printable[:-6]
- #这一行创建了一个字符串 characters,其中包含了string.printable中的可打印字符,但去掉了后面6个不常用的控制字符。
- digits = string.digits
- #这一行创建了一个字符串 digits,其中包含了0到9的数字字符。
- ascii_letters = string.ascii_letters
- #这一行创建了一个字符串 ascii_letters,其中包含了英文字母的大小写。
-
- def Ran_str(seed : int, origin: str):
- #这一行定义了一个名为 Ran_str 的函数,它接受两个参数:seed 是一个整数种子,origin 是一个字符串。
- random.seed(seed)
- #这一行使用给定的种子初始化随机数生成器,以便生成可重现的随机序列。
- random_sequence = random.sample(origin, len(origin))
- #这一行使用给定的 origin 字符串中的字符,生成一个与原字符串长度相同的随机排列。
- return ''.join(random_sequence)
- #这一行将生成的随机排列字符列表连接成一个字符串,并将其返回。
-
- rseed = int(input())
- #这一行从用户输入中获取一个整数种子,该种子将用于生成随机字符串。
- assert rseed <= 1000 and rseed >= 0
- #这一行使用 assert 语句来确保输入的种子在0到1000之间,以确保种子的范围是合理的。
-
- map_string1 = Ran_str(rseed, characters)
- map_string2 = Ran_str(rseed * 2, characters)
- map_string3 = Ran_str(rseed * 3, characters)
- #这三行分别使用不同的种子值生成三个乱序字符串 map_string1、map_string2 和 map_string3,这些字符串将用于加密和解密。
-
- #接下来的代码是一系列自定义函数,用于加密字符串。以下是这些函数的解释:
-
- #这是一个辅助函数,接受一个字符串 flag 作为参数,返回字符串中从索引9到倒数第二个字符的部分。
- def util(flag):
- return flag[9: -1]
-
- #这是另一个辅助函数,接受一个字符串 map_string 和一个字符 c 作为参数,返回字符 c 在字符串 map_string 中的索引位置。
- def util1(map_string: str, c):
- return map_string.index(c)
-
- #这是一个函数,用于执行字符串的异或操作。它接受两个字符串 s 和 k 作为参数,然后将这两个字符串按字符进行异或操作,返回结果。
- def str_xor(s: str, k: str):
- return ''.join(chr((ord(a)) ^ (ord(b))) for a, b in zip(s, k))
-
- #这是一个名为 mess_sTr 的函数,接受两个参数:一个字符串 s 和一个整数 index。该函数执行了以下操作:
-
- def mess_sTr(s : str, index : int):
-
- map_str = Ran_str(index, ascii_letters + digits)#1.使用 index 作为种子生成了一个包含英文字母和数字的乱序字符串 map_str。
- new_str = str_xor(s, map_str[index])#2.对输入字符串 s 和 map_str 中的字符进行异或操作,生成新的字符串 new_str。
-
- if not characters.find(new_str) >= 0:
- new_str = "CrashOnYou??" + s
- #3.检查 new_str 是否包含在可打印字符集 characters 中,如果不包含,则将字符串改为 "CrashOnYou??" 加上原字符串 s。
- return new_str, util1(map_str, s)#4.返回新字符串 new_str 和字符在 map_str 中的索引。
-
- #这是名为 crypto_phase1 的函数,接受一个字符串 flag 作为参数,执行以下操作:
- def crypto_phase1(flag):
- flag_list1 = util(flag).split('_')#1.使用 util 函数将输入字符串 flag 拆分成一个列表 flag_list1,以下划线为分隔符。
- newlist1 = []
- newlist2 = []
- index = 1
- k = 0#2.初始化两个空列表 newlist1 和 newlist2,以及两个索引变量 index 和 k
- for i in flag_list1:#3.遍历 flag_list1 中的每个子字符串 i,并根据其长度的奇偶性进行不同的处理:
- if len(i) % 2 == 1:#如果长度为奇数,对子字符串的每个字符执行 mess_sTr 操作,并将结果连接到新字符串 i1 中。同时更新索引。
- i1 = ""
- for j in range(len(i)):
- p, index = mess_sTr(i[j], index)
- i1 += p
-
- p, index = mess_sTr(i[0], index)
- i1 += p
-
- i1 += str(k)
- k += 1
- newlist1.append(i1)
-
- else:#如果长度为偶数,将子字符串末尾添加上一个递增的数字,并将其加入到 newlist2 中。
- i += str(k)
- k += 1
- newlist2.append(i)
-
- return newlist1, newlist2#4.返回两个列表 newlist1 和 newlist2。
-
-
- #这是名为 crypto_phase2 的函数,接受一个列表作为参数,执行以下操作:
- def crypto_phase2(list):
- newlist = []#1.初始化一个空列表 newlist。
- for i in list:#2.遍历输入列表中的每个字符串 i。
- str = ""
- for j in i:
- str += map_string1[util1(map_string3, j)]
- #3.遍历字符串 i 中的每个字符 j,并根据 map_string1 中字符在 map_string3 中的索引位置获取字符,然后将其连接到新字符串 str 中。
- newlist.append(str)#4.将新字符串 str 添加到 newlist 中。
- return newlist#返回包含加密结果的列表 newlist。
-
-
- #这是名为 crypto_phase3 的函数,接受一个列表作为参数,执行以下操作:
- def crypto_phase3(list):
- newlist = []#初始化一个空列表 newlist。
- for i in list:#遍历输入列表中的每个字符串 i。
- str = ""
- for j in i:
- str += map_string2[util1(map_string3, j)]
- #遍历字符串 i 中的每个字符 j,并根据 map_string2 中字符在 map_string3 中的索引位置获取字符,然后将其连接到新字符串 str 中。
- newlist.append(str)#将新字符串 str 添加到 newlist 中。
- return newlist#返回包含加密结果的列表 newlist。
-
-
- #这是名为 crypto_final 的函数,接受一个列表作为参数,执行以下操作:
- def crypto_final(list):
- str=""#初始化一个空字符串 str。
- for i in list[::-1]:#遍历输入列表中的每个字符串 i(以倒序方式遍历)。
- str += i#将每个字符串 i 连接到结果字符串 str 中。
- return str#返回最终的加密字符串。
-
- #这是一个条件语句,它检查是否在直接运行这个脚本时才执行以下的代码块。
- if __name__ == '__main__':
- format="sixstars{XXX}"
- flag="Nothing normal will contribute to a crash. So when you find nothing, you find A Crashhhhhhhh!!! "
- #这两行定义了两个字符串变量,format 和 flag。
- flaglist1, flaglist2 = crypto_phase1(flag)
- #这一行调用 crypto_phase1 函数,对输入的 flag 进行第一阶段加密,然后将结果分成两个列表:flaglist1 和 flaglist2。
- cipher = crypto_final(crypto_phase3(crypto_phase2(flaglist1) + flaglist1) + crypto_phase2(crypto_phase3(flaglist2)))
- #这一行对 flaglist1 进行第二和第三阶段的加密,然后将结果拼接起来,最后通过 crypto_final 函数进行最终的加密,得到最终的加密字符串 cipher。
- print("map_string2: " + map_string2)
- print("cipher: " + cipher)
- #这两行分别打印了 map_string2 和加密后的字符串 cipher,以供查看结果。
output:
map_string2: \W93VnRHs
A,x@DQ.Sj:_$E/%"+{1
cipher: &I1}ty~A:bR>)Q/;6:*6`1;bum?8i[LL*t`1;bum?8i[LL?Ia`1;bum?8i[LL72;xl:mvHF"z4_/DD+c:mvHF"z4_/DDzbZ:mvHF"z4_/DDr}vS?
解密代码:
参考网站:*CTF 2023 Writeup - 星盟安全团队 (xmcve.com)
- import random
- import string
-
- rseed = 0
- characters = string.printable[:-6]
- for rseed in range(0, 1001):
- random.seed(rseed)
- random_sequence = random.sample(characters, len(characters))
- map_string1 = ''.join(random_sequence)
-
- random.seed(rseed * 2)
- random_sequence = random.sample(characters, len(characters))
- map_string2 = ''.join(random_sequence)
- if map_string2[:10] == '8K#Ttr@&5=':
- print('rseed =', rseed)
- break
-
- random.seed(rseed * 3)
- random_sequence = random.sample(characters, len(characters))
- map_string3 = ''.join(random_sequence)
-
-
- def re_xor(c, a, index: int):
- return chr(((ord(a) + index) ^ ord(c)) - index)
-
-
- cipher = "edT0O
3/LZALI]~S=}NP=7zY" - for i in range(0, len(cipher), 2):
- hou = cipher[:-i]
- hou = ''.join([map_string3[map_string1.index(h)] for h in hou])
- hou = ''.join([map_string3[map_string2.index(h)] for h in hou])
- if hou and hou[-1] in string.digits:
- qian = cipher[-i:]
- qian = ''.join([map_string3[map_string2.index(q)] for q in qian])
- qian1 = qian[:len(qian)//2]
- qian2 = ''.join([map_string3[map_string1.index(q)] for q in qian[len(qian)//2:]])
- if qian1 == qian2:
- qian = qian1
- print(hou)
- print(qian)
- qian11 = qian[:(len(qian)-2)//2]
- qian22 = qian[-(len(qian) - 2) // 2-1:-1]
- print(qian11)
- print(qian22)
-
- for c in characters:
- index = 2
- qian_ = ''
- qian_ += c
- try:
- for x in qian11:
- qian_ += re_xor(x, qian_[-1], index)
- if all([y in string.ascii_letters+string.digits for y in qian_]):
- print(qian_+'3')
- except:
- continue
-
- for c in characters:
- index = 1
- qian_ = ''
- qian_ += c
- try:
- for x in qian22:
- qian_ += re_xor(x, qian_[-1], index)
- if all([y in string.ascii_letters+string.digits for y in qian_]):
- print(qian_+'0')
- except:
- continue
- print()
-
- # cR7PtO5 ln4 s0m32 F1nD1
- # ~F3&)0
- # F4n3TrY0
-
- # sixstars{TrY_F1nD_s0m3_F4n_ln_cR7PtO}