H&NCTF2025 haN个人wp(密码有全解)

Crypto

哈基coke

猫脸变换我做烂了,这里安利一下我师兄的项目,记得点星星哦

项目地址 https://github.com/Alexander17-yang/Anrold-break
师兄说秒杀一切猫脸题!

这道题查看关键参数:

arnold_encode(img,6,9,1)

直接解密

得到图片,图片上有flag

Lcgp

这个应该是dlp+lcg问题,思路是先用lcg的5个输出恢复lcg的参数seed得到密文c,然后解决离散对数问题

恢复lcg:

from Crypto.Util.number import *
import gmpy2
s0 = 11250327355112956284720719987943941825496074893551827972877616718074592862130806975889275745497426515405562887727117008818863728803549848574821067056997423443681347885027000632462241968640893471352200125748453396098854283137158609264944692129301617338233670002547470932851350750870478630955328653729176440142198779254117385657086615711880537380965161180532127926250520546846863536247569437
s1 = 1289730679860726245234376434590068355673648326448223956572444944595048952808106413165882424967688302988257332835229651422892728384363094065438370663362237241013242843898967355558977974152917458085812489310623200114007728021151551927660975648884448177346441902806386690751359848832912607313329587047853601875294089502467524598036474193845319703759478494109845743765770254308199331552085163360820459311523382612948322756700518669154345145757700392164795583041949318636
s2 = 147853940073845086740348793965278392144198492906678575722238097853659884813579087132349845941828785238545905768867483183634111847434793587821166882679621234634787376562998606494582491550592596838027522285263597247798608351871499848571767008878373891341861704004755752362146031951465205665840079918938797056361771851047994530311215961536936283541887169156535180878864233663699607369701462321037824218572445283037132205269900255514050653933970174340553425147148993214797622395988788709572605943994223528210919230924346860415844639247799805670459
s3 = 7426988179463569301750073197586782838200202717435911385357661153208197570200804485303362695962843396307030986052311117232622043073376409347836815567322367321085387874196758434280075897513536063432730099103786733447352512984165432175254784494400699821500026196293994318206774720213317148132311223050562359314735977091536842516316149049281012797103790472349557847649282356393682360276814293256129426440381745354969522053841093229320186679875177247919985804406150542514337515002645320320069788390314900121917747534146857716743377658436154645197488134340819076585888700553005062311578963869641978771532330577371974731136
s4 = 10389979373355413148376869524987139791217158307590828693700943753512488757973725227850725013905113587408391654379552713436220790487026223039058296951420273907725324214990441639760825661323514381671141482079783647253661594138658677104054180912818864005556386671430082941396497098166887200556959866845325602873713813206312644590812141400536476615405444030140762980665885244721798105034497461675317071497925846844396796854201566038890503298824928152263774446268093725702310124363765630370263370678902342200494544961012407826314577564991676315451785987248633724138137813024481818431889574317602521878974976264742037227074
output = [s0,s1,s2,s3,s4]
t = []
for i in range(1, len(output)):
    t.append(output[i] - output[i - 1])

T = []
for i in range(1, len(t) - 1):
    T.append(t[i + 1] * t[i - 1] - t[i] ** 2)

m = []
for i in range(len(T) - 1):
    mm = gmpy2.gcd(T[i], T[i + 1])
    if isPrime(mm):
        m.append(int(mm))
    else:
        for i in range(1, 100):
            if isPrime(mm // i):
                mm = mm // i
                m.append(int(mm))
                break

for i in m:
    if isPrime(i):
        a = gmpy2.invert(t[0], i) * t[1] % i
        b = output[1] - a * output[0] % i
        a_ = gmpy2.invert(a, i)
        seed = a_ * (output[0] - b) % i
        print(seed)
#seed=98136663393066487319477131255488756533037186459124433869847045986870213783395243380337142782779765255670853582334927187474123853371504168896312528278296763527266828907487342102002206806408616944398694810398049626860321901229014612541564249969665358849039818103044159048535403863928440335143886672949700153798350

现在已知c,e,n,求flag

e = 2024
c=pow(e, flag, n)
from Crypto.Util.number import *
n = 604805773885048132038788501528078428693141138274580426531445179173412328238102786863592612653315029009606622583856638282837864213048342883583286440071990592001905867027978355755042060684149344414810835371740304319571184567860694439564098306766474576403800046937218588251809179787769286393579687694925268985445059
e = 2024
c = 98136663393066487319477131255488756533037186459124433869847045986870213783395243380337142782779765255670853582334927187474123853371504168896312528278296763527266828907487342102002206806408616944398694810398049626860321901229014612541564249969665358849039818103044159048535403863928440335143886672949700153798350
G=Zmod(n)
e=G(e)
c=G(c)
print(long_to_bytes(discrete_log(c,e)))
#b'H&NCTF{7ecf4c8c-e6a5-45c7-b7de-2fecc31d8511}'

数据处理

我的思路是先用dlp恢复出newflag,再爆破。

c = pow(m, int(new_flag), n)

已知c,m,n,求出newflag,因为n = 2 ** 512,是很好解的。

from Crypto.Util.number import *
n = 2 ** 512
m = 5084057673176634704877325918195984684237263100965172410645544705367004138917087081637515846739933954602106965103289595670550636402101057955537123475521383
c = 2989443482952171039348896269189568991072039347099986172010150242445491605115276953489889364577445582220903996856271544149424805812495293211539024953331399
G=Zmod(n)
m=G(m)
c=G(c)
print(discrete_log(c,m))
#3282248010524512146638712359816289396373430161050484501341123570760619381019795910712610762203934445754701

现在映射表差了7个数字,也就是要爆破5040种情况,如果输出有H&NCTF{,就输出。

from Crypto.Util.number import long_to_bytes
import itertools

# 已知的加密后的数字
new_flag = 3282248010524512146638712359816289396373430161050484501341123570760619381019795910712610762203934445754701

# 已知的部分映射
lowercase = '0123456789'
uppercase = '7***4****5'

# 找出需要填充的位置
fill_positions = [i for i, c in enumerate(uppercase) if c == '*']
available_digits = [d for d in lowercase if d not in uppercase]  # 未使用的数字

# 生成所有可能的排列
permutations = itertools.permutations(available_digits, len(fill_positions))

# 遍历所有可能的排列
for perm in permutations:
    # 构建完整的uppercase映射
    temp_uppercase = list(uppercase)
    for i, pos in enumerate(fill_positions):
        temp_uppercase[pos] = perm[i]
    full_uppercase = ''.join(temp_uppercase)
    
    # 创建映射表
    table = str.maketrans(full_uppercase, lowercase)
    
    # 将数字转换为字符串并应用映射
    encrypted_str = str(new_flag)
    decrypted_str = encrypted_str.translate(table)
    
    try:
        # 尝试将解密后的字符串转换回字节
        decrypted_bytes = long_to_bytes(int(decrypted_str))
        
        # 检查结果是否包含"H&NCTF{"前缀
        if b"H&NCTF{" in decrypted_bytes[:10]:  # 只检查前10个字节
            print(f"找到匹配的映射!")
            print(f"Uppercase: {full_uppercase}")
            print(f"Lowercase: {lowercase}")
            print(f"解密结果: {decrypted_bytes}")
            break
    except ValueError:
        # 如果转换失败,继续尝试下一种排列
        continue
else:
    print("未找到匹配的映射。") 
"""
Uppercase: 7031426985
Lowercase: 0123456789
解密结果: b'H&NCTF{cut_cut_rrioajtfijrwegeriogjiireigji}'
"""

为什么出题人的rsa总是ez

part1

可构造如下式子,构造格去打,和强网杯一题很像

from Crypto.Util.number import *

c=13148687178480196374316468746303529314940770955906554155276099558796308164996908275540972246587924459788286109602343699872884525600948529446071271042497049233796074202353913271513295267105242313572798635502497823862563815696165512523074252855130556615141836416629657088666030382516860597286299687178449351241568084947058615139183249169425517358363928345728230233160550711153414555500038906881581637368920188681358625561539325485686180307359210958952213244628802673969397681634295345372096628997329630862000359069425551673474533426265702926675667531063902318865506356674927615264099404032793467912541801255735763704043

n=13718277507497477508850292481640653320398820265455820215511251843542886373380880887850571647060788265498378060163112689840208264538965960596605641194331300743676780910818492860412739541418029075802834265712602393103809065720527365081016381358333378953245379751008531500896923727040455566953960991908174586311899809864209624888469263612475732913062035036254077225370843701146080145441104733074178115602425412116325647598625157922655504918118208783230138448694045386019901732846478340735331718476554208157393418221315041837392020742062275999319586357229583509788489495876723122993592623230858393165458733055504467513549

h1=6992022576367328281523272055384380182550712894467837916200781058620282657859189270338635886912232754034211897894637971546032107000253692739473463119025570291091085702056938901846349325941043398928197991115231668917435951127329817379935880511925882734157491821315858319170121031835598580384038723788681860763814776365440362143661999054338470989558459179388468943933975861549233231199667742564080001256192881732567616103760815633265325456143601649393547666835326272408622540044065067528568675569233240785553062685974593620235466519632833169291153478793523397788719000334929715524989845012633742964209311952378479134661

h2=16731800146050995761642066586565348732313856101572403535951688869814016691871958158137790504490910445304384109605408840493227057830017039824412834989258703833576252634055087138315434304691218949240382395879124201923060510497916818961571111218224960267593032380037212325935576750663442553781924370849537501656957488833521657563900462052017695599020610911371304659875887924695896434699048696392210066253577839887826292569913713802634067508141124685789817330268562127695548527522031774601654778934513355315628270319037043809972087930951609429846675450469414212384044849089372435124609387061864545559812994515828333828939

brute = 2
for i in range(2^brute):
    for j in range(2^brute):
        L = Matrix(ZZ, [
            [1,0,0,2^brute*h1],
            [0,1,0,2^brute*h2],
            [0,0,2^(1024-brute),h1*i+h2*j-h1*h2],
            [0,0,0,n]
        ])
        L[:,-1:] *= n
        res = L.LLL()[0]

        p = 2^brute*abs(res[0])+i
        if(n % p == 0):
            q=n//p
            phi=(p-1)*(q-1)
            d=inverse(65537,phi)
            print(long_to_bytes(pow(c,d,n)))
#b'flag{e_is_xevaf-cityf-fisof-ketaf-metaf-disef-nuvaf-cysuf-dosuf-getuf-cysuf-dasix,bubbleBabble}\xea\xc7P|OQ\x0f\xbc\xdcL;@-\x04\x9de\xd4\x14\xa7vNN\xa1\xce$T\xfd\x12\xc4\x9b\xfe\xeew'

这里有一个bubbleBabble解密,得到:81733668723981020451323

这个值是第二问e的值。

part2

这个题是Common Prime RSA

套板子:

from sage.groups.generic import bsgs

N=10244621233521168199001177069337072125430662416754674144307553476569744623474797179990380824494968546110022341144527766891662229403969035901337876527595841503498459533492730326942662450786522178313517616168650624224723066308178042783540825899502172432884573844850572330970359712379107318586435848029783774998269247992706770665069866338710349292941829996807892349030660021792813986069535854445874069535737849684959397062724387110903918355074327499675776518032266136930264621047345474782910332154803497103199598761422179303240476950271702406633802957400888398042773978322395227920699611001956973796492459398737390290487
g=2296316201623391483093360819129167852633963112610999269673854449302228853625418585609211427788830598219647604923279054340009043347798635222302374950707
c=7522161394702437062976246147354737122573350166270857493289161875402286558096915490526439656281083416286224205494418845652940140144292045338308479237214749282932144020368779474518032067934302376430305635297260147830918089492765917640581392606559936829974748692299762475615766076425088306609448483657623795178727831373194757182797030376302086360751637238867384469269953187938304369668436238848537646544257504724753333177938997524154486602644412199535102323238852958634746165559537630341890450666170836721803871120344373143081664567068672230842855208267929484000179260292518351155693154372172449820053764896414799137097

nbits = int(N).bit_length()
gamma = 500/nbits   #这边的500对应g的比特位数
cbits = ceil(nbits * (0.5 - 2 * gamma))

M = (N - 1) // (2 * g)
u = M // (2 * g)
v = M - 2 * g * u
GF = Zmod(N)
x = GF.random_element()
y = x ^ (2 * g)
# c的范围大概与N^(0.5-2*gamma)很接近
c = bsgs(y, y ^ u, (2**(cbits-1), 2**(cbits+1)), operation='*')
#(a, b, bounds, operation='*', identity=None, inverse=None, op=None)
ab = u - c
apb = v + 2 * g * c
P.<x> = ZZ[]
f = x ^ 2 - apb * x + ab
a = f.roots()
if a:
    a, b = a[0][0], a[1][0]
    p = 2 * g * a + 1
    q = 2 * g * b + 1
    print(p,q)
    assert p * q == N
#p=114223230692329221233593176873809300402703143063931397822580003361438712054166147412606967205124955861521969519047697209787311806459638088623102779532442176190528211946769436968799761724667716082655997119572158947882963880778970164432326393480858337150525471346874196183962785321409039116916910681846888186947 #q=89689471847596377741222144429998037990667180177357564376140367776414308387012923411995322262858328353318533567758158657166891766790825298883408932478365300323143798943782413227199460096726803837011408747331311614322911225425264615177532865042145570988661750629687056545931523546752474174278821175282246381821

然后就是简单ezrsa

from Crypto.Util.number import long_to_bytes, isPrime
import gmpy2
p=114223230692329221233593176873809300402703143063931397822580003361438712054166147412606967205124955861521969519047697209787311806459638088623102779532442176190528211946769436968799761724667716082655997119572158947882963880778970164432326393480858337150525471346874196183962785321409039116916910681846888186947
q=89689471847596377741222144429998037990667180177357564376140367776414308387012923411995322262858328353318533567758158657166891766790825298883408932478365300323143798943782413227199460096726803837011408747331311614322911225425264615177532865042145570988661750629687056545931523546752474174278821175282246381821
c=7522161394702437062976246147354737122573350166270857493289161875402286558096915490526439656281083416286224205494418845652940140144292045338308479237214749282932144020368779474518032067934302376430305635297260147830918089492765917640581392606559936829974748692299762475615766076425088306609448483657623795178727831373194757182797030376302086360751637238867384469269953187938304369668436238848537646544257504724753333177938997524154486602644412199535102323238852958634746165559537630341890450666170836721803871120344373143081664567068672230842855208267929484000179260292518351155693154372172449820053764896414799137097
n=p*q
e=81733668723981020451323
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
#b'flag{I wish you success in your cryptography career}'

Ez-factor

https://tangcuxiaojikuai.xyz/post/4a67318c.html

这里参考了糖醋鸡块师傅的博客

信息:

  • e=65537
  • 额外给出一个值N,N=kq+r,其中k的取值范围是(2^511,2^512) ,r取值范围是(2^247,2^248)

显然是一个ACD(近似公约数)问题,然而由于只有这两个数据,所以直接造常见的格难以规约出目标向量,因此查找到文献:

ACD.dvi (iacr.org)

经测试,选取参数t=20,k=10,利用上述多项式去构造格,能够规约出的小根上界约为243bit.而这道题的r是248bit,所以只要爆破5bit即可。

from Crypto.Util.number import *
from tqdm import *
from itertools import *
from multiprocessing import Pool

################################################ gen data
e = 65537
N = 155296910351777777627285876776027672037304214686081903889658107735147953235249881743173605221986234177656859035013052546413190754332500394269777193023877978003355429490308124928931570682439681040003000706677272854316717486111569389104048561440718904998206734429111757045421158512642953817797000794436498517023
c = 32491252910483344435013657252642812908631157928805388324401451221153787566144288668394161348411375877874802225033713208225889209706188963141818204000519335320453645771183991984871397145401449116355563131852618397832704991151874545202796217273448326885185155844071725702118012339804747838515195046843936285308
m = 1
rho = 243
a = ["pad"] + [128897771799394706729823046048701824275008016021807110909858536932196768365642942957519868584739269771824527061163774807292614556912712491005558619713483097387272219068456556103195796986984219731534200739471016634325466080225824620962675943991114643524066815621081841013085256358885072412548162291376467189508]


def attack(ii):
    a = ["pad"] + [128897771799394706729823046048701824275008016021807110909858536932196768365642942957519868584739269771824527061163774807292614556912712491005558619713483097387272219068456556103195796986984219731534200739471016634325466080225824620962675943991114643524066815621081841013085256358885072412548162291376467189508 - 2^243*ii]

    ################################################ params
    t,k = 20,10
    R = 2^rho
    indices = []
    for i in product([i for i in range(t+1)] , repeat=m):
        if(sum(list(i)) <= t):
            indices.append(["pad"] + list(i))


    ################################################ attack
    PR = ZZ[tuple(f"X{i}" for i in range(m))]
    X = ["pad"] + list(PR.gens())
    poly = []
    monomials=set()
    for i in indices:
        f = 1
        for ij in range(1,len(i)):
            f *= (X[ij] - a[ij])^i[ij]
        l = max(k-sum(i[1:]),0)
        f *= N^l
        poly.append(f)
        for mono in f.monomials():
            monomials.add(mono)


    ################################################# LLL and resultant to find roots
    L = Matrix(ZZ,len(poly),len(monomials))
    monomials = sorted(monomials)
    for row,shift in enumerate(poly):
        for col,monomial in enumerate(monomials):
            L[row,col] = shift.monomial_coefficient(monomial)*monomial(*([R]*m))


    res = L.LLL()
    vec1 = res[0]

    h = 0
    for idx,monomial in enumerate(monomials):
        h += (vec1[idx] // monomial(*([R]*m))) * monomial
    h = h.change_ring(ZZ)
    res1 = h.monic().roots()

    if(res1 != []):
        print(ii,res1)

lists = [i for i in range(2^5)]
with Pool(64) as pool:
    r = list(pool.imap(attack, lists[::-1]))

得到

23 [(-14715130363255113381654886747829252932896141081004535097780429696917183325, 1)]
22 [(-580353845028038744988506741885904806276269905999583432807580086576225117, 1)]
21 [(13554422673199035891677873264057443320343601269005368232165269523764733091, 1)]

任意取一组都能恢复r,r=2^243*ii+res

hint ≡ r mod p,所以 phint - r 的一个因子。可以用gcd解决

import gmpy2
from Crypto.Util.number import long_to_bytes
N= 155296910351777777627285876776027672037304214686081903889658107735147953235249881743173605221986234177656859035013052546413190754332500394269777193023877978003355429490308124928931570682439681040003000706677272854316717486111569389104048561440718904998206734429111757045421158512642953817797000794436498517023
hint= 128897771799394706729823046048701824275008016021807110909858536932196768365642942957519868584739269771824527061163774807292614556912712491005558619713483097387272219068456556103195796986984219731534200739471016634325466080225824620962675943991114643524066815621081841013085256358885072412548162291376467189508
c=32491252910483344435013657252642812908631157928805388324401451221153787566144288668394161348411375877874802225033713208225889209706188963141818204000519335320453645771183991984871397145401449116355563131852618397832704991151874545202796217273448326885185155844071725702118012339804747838515195046843936285308
ii=23
res=-14715130363255113381654886747829252932896141081004535097780429696917183325
r=ii*(2**243)+res
p=gmpy2.gcd(hint-r,N)
q=N//p
e=65537
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,N)
print(long_to_bytes(m))
#b'H&NCTF{ac354aae-cb6b-4bd1-a9cd-090812b8f93e}'

Ez-factor-pro

一样的分解原理,不过数据要改。243到252要爆破9个bit

from Crypto.Util.number import *
from tqdm import *
from itertools import *
from multiprocessing import Pool

################################################ gen data

N = 133196604547992363575584257705624404667968600447626367604523982016247386106677898877957513177151872429736948168642977575860754686097638795690422242542292618145151312000412007125887631130667228632902437183933840195380816196093162319293698836053406176957297330716990340998802156803899579713165154526610395279999
c = 0x476922b694c764725338cca99d99c7471ec448d6bf60de797eb7cc6e71253221035eb577075f9658ac7f1a40747778ac261787baad21ee567256872fa9400c37
m = 1
rho = 243
a = ["pad"] + [88154421894117450591552142051149160480833170266148800195422578353703847455418496231944089437130332162458102290491849331143073163240148813116171275432632366729218612063176137204570648617681911344674042091585091104687596255488609263266272373788618920171331355912434290259151350333219719321509782517693267379786]


def attack(ii):
    a = ["pad"] + [88154421894117450591552142051149160480833170266148800195422578353703847455418496231944089437130332162458102290491849331143073163240148813116171275432632366729218612063176137204570648617681911344674042091585091104687596255488609263266272373788618920171331355912434290259151350333219719321509782517693267379786 - 2^243*ii]

    ################################################ params
    t,k = 20,10
    R = 2^rho
    indices = []
    for i in product([i for i in range(t+1)] , repeat=m):
        if(sum(list(i)) <= t):
            indices.append(["pad"] + list(i))


    ################################################ attack
    PR = ZZ[tuple(f"X{i}" for i in range(m))]
    X = ["pad"] + list(PR.gens())
    poly = []
    monomials=set()
    for i in indices:
        f = 1
        for ij in range(1,len(i)):
            f *= (X[ij] - a[ij])^i[ij]
        l = max(k-sum(i[1:]),0)
        f *= N^l
        poly.append(f)
        for mono in f.monomials():
            monomials.add(mono)


    ################################################# LLL and resultant to find roots
    L = Matrix(ZZ,len(poly),len(monomials))
    monomials = sorted(monomials)
    for row,shift in enumerate(poly):
        for col,monomial in enumerate(monomials):
            L[row,col] = shift.monomial_coefficient(monomial)*monomial(*([R]*m))


    res = L.LLL()
    vec1 = res[0]

    h = 0
    for idx,monomial in enumerate(monomials):
        h += (vec1[idx] // monomial(*([R]*m))) * monomial
    h = h.change_ring(ZZ)
    res1 = h.monic().roots()

    if(res1 != []):
        print(ii,res1)

lists = [i for i in range(2^9)]
with Pool(64) as pool:
    r = list(pool.imap(attack, lists[::-1]))

得到

507 [(19611044379829562160829201436207338382477210452594451207405391929580461, 1)]
508 [(-14115165473847245074505550804507140788237393964552357213765444218411377747, 1)]
506 [(14154387562606904198827209207379555465002348385457546116180255002270538669, 1)]

老规矩,随便用一组数据恢复r

import gmpy2
from Crypto.Util.number import long_to_bytes
N = 133196604547992363575584257705624404667968600447626367604523982016247386106677898877957513177151872429736948168642977575860754686097638795690422242542292618145151312000412007125887631130667228632902437183933840195380816196093162319293698836053406176957297330716990340998802156803899579713165154526610395279999
hint = 88154421894117450591552142051149160480833170266148800195422578353703847455418496231944089437130332162458102290491849331143073163240148813116171275432632366729218612063176137204570648617681911344674042091585091104687596255488609263266272373788618920171331355912434290259151350333219719321509782517693267379786
c = 0x476922b694c764725338cca99d99c7471ec448d6bf60de797eb7cc6e71253221035eb577075f9658ac7f1a40747778ac261787baad21ee567256872fa9400c37
ii=507
res=19611044379829562160829201436207338382477210452594451207405391929580461
r=ii*(2**243)+res
p=gmpy2.gcd(hint-r,N)
q=N//p
assert N==p*q
print("p=",p)
print("q=",q)
"""
p= 10028729313926419703025256508152026623108338149091078764973884312717908184535793132629646141453659427095349436587466628835078575518082248569520191060305909
q= 13281503606147647246708380767428957306516210204292257132138079387068505557520151605985669600345608943780007813758130736816723511421069886664561045223935011
"""

后面就是解SM4-CBC

from Crypto.Util.number import *
from gmssl.sm4 import CryptSM4, SM4_DECRYPT
from hashlib import sha256
from Crypto.Util.Padding import unpad
# 已知参数
p = 10028729313926419703025256508152026623108338149091078764973884312717908184535793132629646141453659427095349436587466628835078575518082248569520191060305909
q = 13281503606147647246708380767428957306516210204292257132138079387068505557520151605985669600345608943780007813758130736816723511421069886664561045223935011
N = p * q
r = 7166351305785506670352015492214713707534657162937963088592442157834795391917
c = bytes.fromhex("476922b694c764725338cca99d99c7471ec448d6bf60de797eb7cc6e71253221035eb577075f9658ac7f1a40747778ac261787baad21ee567256872fa9400c37")
# 计算 IV
leak = N * r
r_bytes = long_to_bytes(leak)
iv = r_bytes[:16]  # SM4的IV是16字节
# 计算 Key
sum_pqr = p + q + r
key = sha256(str(sum_pqr).encode()).digest()[:16]
# SM4-CBC 解密
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(key, SM4_DECRYPT)
decrypted = crypt_sm4.crypt_cbc(iv, c)
flag = unpad(decrypted, 16)  # 移除填充
print("Flag:", flag.decode())
#Flag: H&NCTF{ac354aae-cb6b-4bd1-a9cd-090812b8f93e}

Three vertical lines

留坑,比赛时我没解出来,不过现在自已已经算出来了,今晚补上

我来填坑啦

可以参考这一篇博客niteCTF 2024 团队 WriteUp | LOV3 -> OV3

这道题就是要从3*p**5+4*q**5=hint中恢复p和q

由于 p 和 q 是 512 位,hint是1282位,p,q远小于 hint,因此 (p,q) 是格中的短向量。

from sage.all import Zmod, ZZ, matrix, PolynomialRing
from functools import reduce
from Crypto.Util.number import inverse, isPrime, long_to_bytes

hint=72063558451087451183203801132459543552092564094711815404066471440396765744526854383117910805713050240067432476705168314622044706081669935956972031037827580519320550326077291392722314265758802332280697884744792689996718961355845963752788234205565249205191648439412084543163083032775054018324646541875754706761793307667356964825613429368358849530455220484128264690354330356861777561511117
c=2864901454060087890623075705953001126417241189889895476561381971868301515757296100356013797346138819690091860054965586977737630238293536281745826901578223
e = 65537

R = Zmod(hint)
x = PolynomialRing(R, 'x').gen()
f = 3*x**5 + 4
root = f.roots()[0][0]
# Build lattice
M = matrix(ZZ, [[1, -root], [0, hint]])
# LLL reduction
L = M.LLL()
p, q = map(abs, L[0])
p, q = int(p), int(q)
print(f"p = {p}\nq = {q}")
print(f"isPrime(p) = {isPrime(p)}, isPrime(q) = {isPrime(q)}")

"""
p = 106939296519048296066609095791824433210081775149307042159537637081687455851889
q = 88318396054969634676003916964315749322940927962528304238128738629965788358867
isPrime(p) = True, isPrime(q) = True
"""

然后ezrsa解决

from Crypto.Util.number import long_to_bytes
import gmpy2
c=2864901454060087890623075705953001126417241189889895476561381971868301515757296100356013797346138819690091860054965586977737630238293536281745826901578223
p = 106939296519048296066609095791824433210081775149307042159537637081687455851889
q = 88318396054969634676003916964315749322940927962528304238128738629965788358867
n = p * q
phi_n = (p - 1) * (q - 1)
e = 65537
d = gmpy2.invert(e, phi_n)
m = pow(c, d, n)
print(long_to_bytes(m))
#b'H&NCTF{You_learned_the_code_well}'

Misc

签到签退问卷

芙宁娜的图片

打开压缩包,里面有一张芙宁娜的图片和txt文件

+++++ +++[- >++++ ++++< ]>+++ +++++ +++++ ++.<+ +++++ [->-- ----< ]>--- --.<+ +++++ [->++ ++++< ]>+++ +.++. ++++. <+++[ ->--- <]>-- ---.< +++++ ++[-> +++++ ++<]> ++++. <++++ +[->- ----< ]>--- ----- -.<++ ++++[ ->--- ---<] >---- -.<++ +++++ +[->+ +++++ ++<]> +++++ .<+++ +[->- ---<] >---- --.<+ ++++[ ->+++ ++<]> +.<++ ++[-> ----< ]>--- -.<++ +[->+ ++<]> ++.-. ----- ---.+ +++++ +.--- --.<+ +++[- >++++ <]>+. <++++ [->-- --<]> ----- .<+++ [->++ +<]>+ ++.<+ +++[- >---- <]>-- .<+++ +[->+ +++<] >++++ +.<++ +[->- --<]> ---.- --.-- ----. <++++ +[->- ----< ]>--- .<+++ +++[- >++++ ++<]> +++++ +++.+ +++++ .---- -.--- ----- .<+++ [->++ +<]>+ +++.< +++++ +++[- >---- ----< ]>--- ----- ----- -.<++ +++++ +[->+ +++++ ++<]> +++++ +++++ ++.<+ +++[- >---- <]>-- --.<+ +++[- >++++ <]>+. +++.- ---.- ----- --.<+ +++++ +[->- ----- -<]>- ----- --.<+ +++++ ++[-> +++++ +++<] >++++ +++++ +++++ +.<

一眼brainfuck编码,解密得到

O&NPTF{Y0u_yepognizeq_the_Couphu's_psog.}

现在就差key了,在图片找。用随波逐流

得到RGB key:H&N2025........

维吉尼亚解密即可

Osint

Chasing Freedom 2

搜图可以得到这篇博客

平潭岛之东痒岛(踩蛇的那天)DAY3-大众点评

较为恶心的是这个字是错别字

H&NCTF{0504-东庠岛灯塔}

Chasing Freedom 3

这个搜索岚庠渡,能找到这个:等一刻轮渡,过一天属于岛屿的生活 - 东庠岛生活画册_码头_海面_渔船

里面有答案,流水码头和岚庠渡3号

H&NCTF{0504-流水码头-岚庠渡3号}

posted @ 2025-06-08 17:57  Mirai_haN  阅读(353)  评论(0)    收藏  举报