2025H&NCTF 数据处理

100次阅读
没有评论

共计2379个字符,预计需要花费6分钟才能阅读完成。

题目

题目给出了源代码,并且非常精简的代码:

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

分析

flag 先转换成了整数,然后对整数进行字典映射变换,得到 new_flag。其中已经知道 0->7、4->4、9->5,那么这里肯定要暴力求解的。变换后的整数 new_flag 经过以下数学公式:

c = m^{new\_flag} \; mod \; n

最终得到结果,并且根据注释已知 $$c,m,n$$,求 new_flag

思路

由前面分析知道,这是一个 离散对数问题 ,可以用 SageMath 工具来求解,代码如下:

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}")

2025H&NCTF 数据处理

得到 new_flag 为 3282248010524512146638712359816289396373430161050484501341123570760619381019795910712610762203934445754701

接着暴力求解,遍历所有映射组合即可,代码:

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

2025H&NCTF 数据处理

得到 flag 为 H&NCTF{cut_cut_rrioajtfijrwegeriogjiireigji}

正文完
 0
评论(没有评论)
验证码
zh_CN简体中文
文章目录