A total of 2379 characters, expected to take 6 minutes to complete reading.
Title
The title gives the source code, and very streamlined code:
from Crypto.Util.number import bytes_to_long
import random
flag = b"H&NCTF{}"
btl = str(bytes_to_long(flag))
lowercase = '0123456789'
uppercase = '7***4****5'
table = ''.maketrans(lowercase, uppercase)
new_flag = btl.translate(table)
n = 2 ** 512
m = random.randint(2, n - 1) | 1
c = pow(m, int(new_flag), n)
print('m = ' + str(m))
print('c = ' + str(c))
# m = 5084057673176634704877325918195984684237263100965172410645544705367004138917087081637515846739933954602106965103289595670550636402101057955537123475521383
# c = 2989443482952171039348896269189568991072039347099986172010150242445491605115276953489889364577445582220903996856271544149424805812495293211539024953331399
Analysis
flag First converted to an integer, and then a dictionary mapping transformation of the integer to obtain. new_flag. It is already known that 0->7, 4->4, 9->5, then it must be solved violently here. The transformed integer new_flag goes through the following mathematical formula:
c = m^{new\_flag} \; mod \; n
The final result is obtained, and according to the annotation known 1 TP4T$c,m,n$$, find new_flag.
Ideas
From the previous analysis, it is known that this is a discrete logarithm problem , can be used SageMath tool to solve, the code is as follows:
n = 2**512
m = 5084057673176634704877325918195984684237263100965172410645544705367004138917087081637515846739933954602106965103289595670550636402101057955537123475521383
c = 2989443482952171039348896269189568991072039347099986172010150242445491605115276953489889364577445582220903996856271544149424805812495293211539024953331399
# 创建模 n 的整数环
R = Zmod(n)
# 将 m 和 c 转换为环 R 中的元素
m = R(m)
c = R(c)
# 计算 m 在乘法群 (Z/nZ)* 中的阶
# 最小正整数 k 使得 m^k ≡ 1 mod n
ord = m.multiplicative_order()
new_flag = discrete_log(c, m, ord=ord)
print(f"new_flag = {new_flag}")
get new_flag 3282248010524512146638712359816289396373430161050484501341123570760619381019795910712610762203934445754701
.
Then violently solve, traverse all mapping combinations can be, code:
from Crypto.Util.number import long_to_bytes
from itertools import permutations
new_flag = "3282248010524512146638712359816289396373430161050484501341123570760619381019795910712610762203934445754701"
lowercase = "0123456789"
# 需要暴力求解的位置
positions_to_fill = [1, 2, 3, 5, 6, 7, 8]
available_digits = [d for d in "0123456789" if d not in ["7", "4", "5"]]
# 暴力枚举所有可能的映射组合
for perm in permutations(available_digits, len(positions_to_fill)):
# uppercase 组合
uppercase_list = [""] * 10
uppercase_list[0] = "7" # 0 -> 7
uppercase_list[4] = "4" # 4 -> 4
uppercase_list[9] = "5" # 9 -> 5
for idx, digit in zip(positions_to_fill, perm):
uppercase_list[idx] = digit
uppercase = "".join(uppercase_list)
# 通过逆映射恢复原始字符串
table = str.maketrans(uppercase, lowercase)
flag = new_flag.translate(table)
try:
flag = long_to_bytes(int(flag))
print(flag.decode("gbk"))
# 检测是否为 flag
if flag.startswith(b"H&NCTF{") and flag.endswith(b"}"):
print(f"Flag: {flag.decode()}")
break
except Exception as e:
pass
Get flag H&NCTF{cut_cut_rrioajtfijrwegeriogjiireigji}
.