LOADING

加载过慢请开启缓存 浏览器默认开启

PolarCTF2025春季赛-个人WP

beginner

suffix_str = '16732186163543403522711798960598469149029861032300263763941636254755451456334507142958574415880945599253440468447483752611840'
suffix = int(suffix_str)

mod_2_125 = 2 ** 125
if suffix % mod_2_125 != 0:
    print("No solution")
else:
    mod5_125 = 5 ** 125
    a = pow(2, 10000, mod5_125)
    inv_a = pow(a, -1, mod5_125)
    x0 = (suffix * inv_a) % mod5_125

    # Convert to bytes
    try:
        flag_bytes = x0.to_bytes((x0.bit_length() + 7) // 8, byteorder='big')
        flag = flag_bytes.decode('utf-8')
        print(flag)
    except UnicodeDecodeError:
        print("Valid flag not found. Ensure correct decoding and padding.")

lcg

from Crypto.Util.number import *
import gmpy2
a =  156506070439514915241840745761803504236863873655854161309517219593159285490218416513868431750791509039364033002042672969954633160268127141912185884526880436614313300761314810148356686577662643452299620703125833160716418003026915719584690230453993382155777985020586206612864299316237848416232290650753975103343
b =  99238154412252510462155206432285862925162164007834452250464130686978914370223020006347851539449419633688760095534852514797292083351953228730558335170313299274579966373474363445106224340638196799329142279344558612634392675992734275683700752827665429269516389277374408716314038483357418130704741371183923688601
c=  46154227430594568448486764587707836676441274677362557668215680998009402508945237578201692757688901737765923819819981974561807236454825684824157481322486008937560337004555948283870920377643907746645702190355761172293685309340938249454686807948964629553755585562990983237480387614548526918576791297250747752579
n=  94993804003827679355988952056520996247311128806455111011781585397953533782675757682874584547665028872979112598462143541626190903596606261782592703863749024490737374603789002750194481545579020929239629410573307193150780522563772690101754723829224534622557370960012364614566294197235191962517037441643656951249

Ani = gmpy2.invert(a,n)
seed = c
for i in range(10):
    seed = Ani*(seed-b) % n
print(long_to_bytes(seed))

Ununicast

task.py

import libnum
import gmpy2
import random
from flag import *

m = libnum.s2n(flag) 

n_list = []
c_list = []
q_list = []
p_list = []

for i in range(1, 6):  
    p = libnum.generate_prime(1024) 
    q = libnum.generate_prime(1024)  
    n = p * q * (i + 1)  

    p_list.append(p)  
    q_list.append(q)  
    n_list.append(n)  

while True:
    e = random.randint(10, 30)  

    if gmpy2.is_prime(e):  
        break

for index in range(len(n_list)):
    c = pow(m, e, n_list[index])  
    c_list.append(c_list.append(c * (index + 1)))  
    print("n" + str(index + 1) + " =", n_list[index])  
    print("c" + str(index + 1) + " =", c_list[index])

一眼看就是低加密指数广播攻击,但注意这里的模数不互素。还有列表里面的c有倍数关系。要把它们除掉

,开始还以为用扩展中国剩余定理

然后套个ctt脚本就可以解决

exp

from Crypto.Util.number import long_to_bytes
import gmpy2
def Get_Mi(m_list,m):               #求衍数
    M_list = []
    for mi in m_list:
        M_list.append(m // mi)
    return M_list

def Get_resMi(M_list,m_list):       #求乘率
    resM_list = []
    for i in range(len(M_list)):
        resM_list.append(gmpy2.invert(M_list[i],m_list[i]))
    return resM_list

def Get_result(a_list):
    M_list = Get_Mi(m_list,m)
    resM_list = Get_resMi(M_list,m_list)
    result = 0
    for i in range(len(M_list)):
        result += M_list[i]*resM_list[i]*a_list[i]
    result %= m
    return result
n1 = 22103870455568232891149694305142888751834308614394265111616851946569600408214771004642537180847811632101335684526571461971168013515137837024900824805617026937904594229522094231161022911739124543737188196687483192656237801622618078066399259928261566545087643719410735482610730976575506701177108423445928193645406926842010985319473171710362525271971508507747952666476652082985675013329629912123828667561346609223913700779782291638584038925201698832368301491167548373412290987271213331940429281040520028261848410995501268272516219976073764836056701179000719299634048587399330114683369803481960168019956231748933059575086
c1 = 11932229075145446680509155897048554062128427256365407597246250504495581359308426337230014475362231568192824606320775755785288148002607456528824047021370456983795336102290050703706457189838464034831160081682076095173411617546158489572376376884672473947738113750437924641752734999601688973523833305072494573210602790160977994408649942476416234572187935125916149727341802693373659080702112924850348826357976589797895053949499171267826718541148026541242636886850084012913015158312606367900952240929619627369492395483334316329627526281924799100659188037308919177852074431004118744919974806767580700568542188744931220106105
n2 = 75527641277099990800438920440041058388427571492243099817050670120985557789492014161535482889418153237600686779752008243731659250445079816272020155052679163716181164111466120389153470493389801068487079484957125572093805976995390398541806299511780722297642464948545911633969882049338027366168822259177038560221615245305724815740962661657512543487558774545803259821939839314547049519064559274668861232108875651136746020639698802437427698294031084596199751751480045337605111284980409927684686225365555725770862339970487179511801140925931587981761559129421142486178642732741442537609122284807214875446647952010067400441059
c2 = 124027357006179169026958610630330051622067042499828335143384044470302479154098199844981110929954078399392164965842575040140695741764719533745054315027041147434320473103634538090232615962998187567447484128103678001361703834076345621055674269048895730502155866761233018172058631071676397257894588728272913258599692996320058955017804506826897453939809574483310935927402899939042162496213745140970798253433830063777555869660983592646174581212241911650074643983280676238861065129884340834318081282521338654119292893592735294429956139729060770783817702837759047833794757601190967753969500822631312988106678317432186105038268
n3 = 67087501562139943813249584173215038264768218519355997619681399311361081244680048116472803745503996059873261361695629103578075388683394265112338602330356608572716276538183020643625652731722917269342461918246200053767885270359910155650804090015847462552469649420213346519159991670579334968778366255234963922378971680452094795318028353408405313888877068259282684640458674087251102468714734787171166396014144021959441774122328495595094512659302451021226956296868717965902597097040721193168373568780684532295504916946312087113872338693404258549907349353138009767393388073227204853717415106619739522003848121147803734511476
c3 = 34907142326483502918854711671956997110565154361385230791804714287500927140885225814711150443792832759398271249995064551044140838772959358268339105708186456545576271462167016667528764892342067422814982959975071847067493078241698635502292984200940132917130864956317815578073656622172241742542237740221147402449228459532782232518010610903660510875077798419046748683570340175197592449547071220020985311569095928938768945219762563190314531483012532595972282105394784611117089120803198848347397871670119847470687912177591609360741114570213377874848453859418234331921560384819899391157666714587396643397702710016410117040255
n4 = 107655225342909323493747650996643964780949305458547565103531987767712606044684527447631280423897684091717655597473336978923442425477823322239803312759244627308704521511743542550831030718035257133033470431042111429555597381959609892666206716219532081847930970282959800999825630713834546858387640307817593411764905032303294057112362597297253851687870254992314351948709124427458348128204263663881362955482132512838054738519685384575921373737470245719421223898475756247409282692966862335515090757754459242168056461013405091180148696649963461602177212697836496306046456138474445624214914814699390257673835554848791003397055
c4 = 260074379614284795599484546451240257157763532480505168853160303924952553177325935242853666448209970957052626857104522597130316456316378917529016900063473199051496246209878864043477905068893003923546332891289993179385753129868269775271722630762054161951558359984426822705582509592976962739279251035941138103001411061238095611738024433238447078804016593599525582868080696498271912174235479368671466666819582104245707176341268617126063957318342864903403961673418935623112290599738566078566393961145470677825235949530460449737989243772214379341818676279908757907698136648847166264635580606733816599243489965651372128251328
n5 = 70199621485671842359044641866403168058670803503736686351887502686934276983786039926002198676793045683182125769300687612734657616494815167750772182403321230734527784596550124329071164871143795929191396166096178482901122962656943854107741654772981259089537233024363295465966490361367216383217631330482253245796203648485653095242684462412133029510769320566443165990471527944889669809129572843754832577807509454633886982402256837076791468127186325307925886447397529190962280905611709973103713165872442266384750885343667064502988575278416037070011939869923447549518023420261237007329747290577829325263253564790709373901618
c5 = 207467685064436795719671032825183115862587233648672449925340580227825675452627031507906214773278665727530027025673966750973641715014217092820995216768554881760711270444952703291126925400881160114713107315867759288572987159233984669439942981888636828978580980986834342715153361271280814208437227309185682033733871844684874967978852089340054449142896831217885786745795842561143568848428620959961049292832772489885193639646881909425599177539209159664137785111991625129191354004990699226809474030005545318219197509201907072684957499981194498761673049651408375607248956494019809957851295451628144493493011699904221882421955
n1=n1//2
n2=n2//3
n3=n3//4
n4=n4//5
n5=n5//6

c2=c2//2
c3=c3//3
c4=c4//4
c5=c5//5
m_list=[n1,n2,n3,n4,n5]
a_list=[c1,c2,c3,c4,c5]
m = 1
for i in m_list:
    m *= i
result = Get_result(a_list)
for e in range(10,30):
    m = gmpy2.iroot(result,e)
    if m[1]:
        print(long_to_bytes(m[0]))

RSA-1

task.py

import os
from Crypto.Util.number import *
from typing import Union
from flag import flag

bits = 512


def polar(msg: Union[bytes, bytearray], length: int) -> bytes:
    assert length > len(msg), "指定的长度必须大于原始消息长度加 1。"
    return bytes(msg) + b'\x00' + os.urandom(length - len(msg) - 1)


def unpolar(msg: Union[bytes, bytearray]) -> bytes:
    msg = bytes(msg)
    assert b'\x00' in msg, "输入的字节串中不包含分隔符。"
    return msg.split(b'\x00')[0]


def getflag1(m):
    result = []
    for i in range(2):
        result.append(getPrime(bits))
    p, q = result
    if p <= q:
        p, q = q, p
    e = 0x10001
    n = p * q
    c = pow(m, e, n)
    hint = pow(2024 * p + 2025, q, n)
    print('---------- getflag 1 ----------')
    print(f'{c = }')
    print(f'{n = }')
    print(f'{hint = }')


def getflag2(m):
    result = []
    for i in range(2):
        result.append(getPrime(bits))
    p, q = result
    n = p * q
    hint1 = pow(m, p, n)
    hint2 = pow(m, q, n)
    print('---------- getflag 2 ----------')
    print(f'{hint1 = }')
    print(f'{hint2 = }')
    print(f'{n = }')



def getflag3(m):
    result = []
    for i in range(2):
        result.append(getPrime(bits))
    p, q = result
    e = 0x10001
    n = p * q
    g = 20242025
    hint = pow(g + p * 1111, e, n)
    c = pow(m, e, n)
    print('---------- getflag 3 ----------')
    print(f'{c = }')
    print(f'{n = }')
    print(f'{hint = }')


assert len(flag) == 42
mm = []
for i in range(0, 42, 14):
    mm.append(bytes_to_long(polar(flag[i:i + 14], bits // 4 - 1)))

m1, m2, m3 = mm
getflag1(m1)
getflag2(m2)
getflag3(m3)

基本的数论关系,在RSA部分题型收集 | DexterJie’Blog都可以找到

但是在处理flag2的时候

from Crypto.Util.number import *
x = 54970781924019595863484530626735693712920476619483230578277656430455790362335041922354389265430681573039703011001631761902508906456609398108389457140693872973125229844737616298484143628327833079090999615173264817695407599821875528027430069058944656983590302062976047694462479290647389958480266319059751445182
y = 80980259919808074704372134146767866092949512532096534576106851289748846005248116120680155543668224921613789932208624456370489831230478815466334144780133065025062986201532876895224101781697909762258725545339404197634465901767246731955823620770784243939730616060814584918359635917314703766496053543724484797173
n = 99517070479321715054584809647801078099246408970263686466424530637818701832562120579305425855216653939240321111911361599565693184872902069364547154817279854814534957350288095457061287301409197137152708536099357243361609267071166651650163387054480968146813088675351466317148500854487952501075120046716531779527
R.<m> = PolynomialRing(Zmod(n))
f = x*y - m^2 - m*(x - m + y - m)
f = f.monic()
root = f.small_roots(X=2^1018,beta=0.4)
if root != []:
    print(long_to_bytes(int(root[0])))

这样子为什么出不来?

换一种方法

p=gcd(pow(hint1,n,n)-hint2,n)

这样就可以了

knock_knock

古典密码的敲击码,根据这个名字推断到

前景:Rowrow always takes the lead, but Colcol isn't happy about it. This time, he wants to walk ahead of Rowrow. Rowrow agrees, so he lets him go first.


(44 32 42 34)(42 34)(45 43 54 24)(31 32 11 23 53 42 43 33)











hint :32位小写MD5加密

注意是先看列再看行

THIS IS YOUR CHAMPION

playstreamone

task.py

from Flag import flag
assert flag.startswith("flag{")
assert flag.endswith("}")
assert len(flag) == 24


def LFSR(R, mask):
    output = (R << 1) & 0xffffff
    i = (R & mask) & 0xffffff
    lastbit = 0
    while i != 0:
        lastbit ^= (i & 1)
        i = i >> 1
    output ^= lastbit
    return output, lastbit



def Fx1x2x3(R1, R1_mask, R2, R2_mask, R3, R3_mask):
    R1_NEW, x1 = LFSR(R1, R1_mask)
    R2_NEW, x2 = LFSR(R2, R2_mask)
    R3_NEW, x3 = LFSR(R3, R3_mask)

    output = (x1 * x2) ^ ((x2 ^ 1) * x3)

    return R1_NEW, R2_NEW, R3_NEW, output



R1 = int(flag[5:11], 16)
R2 = int(flag[11:17], 16)
R3 = int(flag[17:23], 16)


assert len(bin(R1)[2:]) == 21
assert len(bin(R2)[2:]) == 22
assert len(bin(R3)[2:]) == 21

R1_mask = 0x20010
R2_mask = 0x8002c
R3_mask = 0x200004

for fi in range(1024):
    print(f"Processing file {fi}")
    tmp1mb = bytearray()

    for i in range(1024):
        tmp1kb = bytearray()

        for j in range(1024):
            tmp = 0

            for k in range(8):
                R1, R2, R3, out = Fx1x2x3(R1, R1_mask, R2, R2_mask, R3, R3_mask)
                tmp = (tmp << 1) ^ out

            tmp1kb.append(tmp)

        tmp1mb.extend(tmp1kb)

    with open(f"./output/{fi}", "ab") as f:
        f.write(tmp1mb)

    print(f"File {fi} written successfully.")

没解出来,后续更新