难度一如既往,和今年i春秋的其他比赛差不多,都挺难的(我菜)
队伍成绩:1118pt/11kill/33名/1550有解/2026登录/2794报名
个人成绩:503pt/5kill/57名/2107有解/4594登录/6522报名

Misc

签到

过程

EBCDIC编码,解就行了。

解题脚本

import codecs

with open("EBCDIC.txt", "rb") as f:
    ebcdic = f.read(27)
    ascii_txt = codecs.decode(ebcdic, "cp500")
    print(ascii_txt)

flag

flag{we1c0me_t0_redhat2021}

colorful code

过程

data1内的数字数量7067可以分解成37*191,猜测可能是图片宽高。

data2768字节且内容上大致为3字节一段,猜测是RGB值。

于是可以根据data2[data1]这个思路进行画图。

编写脚本得到data.png

file

发现是色块图,猜测是npiet编码。

解码和得到flag。

file

解题脚本

import cv2
import numpy as np

with open("data1", 'r') as f:
    data1 = f.read(15340)
    data1 = data1.split(' ')
    data1 = data1[:-1]
with open("data2", 'rb') as f:
    data2 = f.read(768)
canvas = np.zeros((191, 37, 3), dtype="uint8")

for dd in enumerate(data1):
    i, d = dd
    d = int(d)
    canvas[i % 191][i // 191][0] = data2[d*3+2]
    canvas[i % 191][i // 191][1] = data2[d*3+1]
    canvas[i % 191][i // 191][2] = data2[d*3]
cv2.imwrite('data.png', canvas)

flag

flag{88842f20-fb8c-45c9-ae8f-36135b6a0f11}

Crypto

primegame

过程

KAPO 2020有差不多一样的,直接套脚本。(下附的脚本已将爆破结果832130写好)

file

解题脚本

import math
from decimal import *
import random
import struct

getcontext().prec = int(100)

primes = [2]
for i in range(3, 90):
    f = True
    for j in primes:
        if i * i < j:
            break
        if i % j == 0:
            f = False
            break
    if f:
        primes.append(i)

keys = []
for i in range(24):
    keys.append(Decimal(int(primes[i])).ln())

arr = []
for v in keys:
    arr.append(int(v * int(16) ** int(64)))

def encrypt(res):
    h = Decimal(int(0))
    for i in range(len(keys)):
        h += res[i] * keys[i]

    ct = int(h * int(16)**int(64))
    return ct

def f(N):
    ln = len(arr)
    A = Matrix(ZZ, ln + 1, ln + 1)
    for i in range(ln):
        A[i, i] = 1
        A[i, ln] = arr[i] // N
        A[ln, i] = 64

    A[ln, ln] = ct // N

    res = A.LLL()

    for i in range(ln + 1):
        flag = True
        for j in range(ln):
            if -64 <= res[i][j] < 64:
                continue
            flag = False
            break
        if flag:
            vec = [int(v + 64) for v in res[i][:-1]]
            ret = encrypt(vec)
            if ret == ct:
                print(N, bytes(vec))
                return True
            else:
                pass
                #print("NO", ret, bytes(vec))
    return False

ct = 597952043660446249020184773232983974017780255881942379044454676980646417087515453
print(ct)
for i in range(2, 10000):
    i=83#go
    if(f(i)):
        break
ct = 425985475047781336789963300910446852783032712598571885345660550546372063410589918
print(ct)
for i in range(2, 10000):
    i=2130#go
    if (f(i)):
        break

flag

flag{715c39c3-1b46-4c23-8006-27b43eba2446}

hpcurve

过程

hxp CTF 2020有差不多一样的,直接套脚本。

file

解题脚本

import itertools
import struct

p = 10000000000000001119
K = GF(p)
R.<x> = K[]
y=x
f = y + y^7
C = HyperellipticCurve(f, 0)
J = C.jacobian()

def get_u_from_out(output, known_input):
    res = []
    for i in range(24):
        res.append(output[i]^^known_input[i])
    res = bytes(res)
    u0, u1, u2 = struct.unpack("<"+'Q'*int(3), res)
    u = x^3+x^2*u2+x*u1+u0
    return u

from itertools import product

def get_v_from_u(u):
    Kbar = GF(p^6)
    Rbar.<t> = Kbar["t"]
    u2 = u.change_ring(Rbar)
    roots = [x[0] for x in u2.roots()]
    ys = []
    for root in roots:
        ys.append(f(root).sqrt(0,1))
    res = []
    for perm in product(range(2), repeat=3):
        poly = Rbar.lagrange_polynomial([(roots[i], ys[i][perm[i]]) for i in range(3)])
        if poly[0] in K:
            res.append(R(poly))
    return res

def try_decode(output, u, v):
    rs = [u[0], u[1], u[2], v[0], v[1], v[2]]
    otp = struct.pack("<"+'Q'*int(6), *rs)
    plain = []
    for i in range(len(output)):
        plain.append(output[i]^^otp[i])
    return bytes(plain)

outputs = bytes.fromhex("66def695b20eeae3141ea80240e9bc7138c8fc5aef20532282944ebbbad76a6e17446e92de5512091fe81255eb34a0e22a86a090e25dbbe3141aff0542f5")
output = outputs[:48]
known_input = b"aaaaaaaaaaaaaaaaaaaaflag{"
u = get_u_from_out(output, known_input)
vs = get_v_from_u(u)
for v in vs:
    flag = try_decode(output,u,v)
    if(flag.find(b'{') != int(-1)):
        print(flag)
        break
output = outputs[48:]
for v in vs:
    flag = try_decode(output,u,v)
    if(flag.find(b'}') != int(-1)):
        print(flag)
        break

flag

flag{1b82f60a-43ab-4f18-8ccc-97d120aae6fc}