Skip to content

极客大挑战2024

约 1357 字大约 5 分钟

crypto

2024-12-29

凯撒加密

对比YEI与SYC得到key组合

m='YEI{CKRIUSK_ZU_2024_MKKQ_INGRRKTMK}'
l=[6,-20]


for i in range(len(m)):
    if 'A'<=m[i]<='Z':
        s=chr((ord(m[i])-l[i%2]-ord('A'))%26+ord('A'))
    else:
        s=m[i]
    print(s,end='')
    #SYC{WELCOME_TO_2024_GEEK_CHALLENGE}

xor

from Crypto.Util.number import *
from pwn import xor

key = b'...'
flag = b'...'
assert len(key)==4

enc = bytes_to_long(xor(flag,key))

f1 = 4585958212176920650644941909171976689111990
f2 = 3062959364761961602614252587049328627114908
e1 = enc^f1
e2 = e1^f2
print(e2)

"""
10706859949950921239354880312196039515724907
"""

对比SYC{与long_to_bytes(enc)的前4位得到key=b'><0R'

from Crypto.Util.number import *

def xor(key, data):
    key_length = len(key)
    result = bytearray(len(data))
    for i in range(len(data)):
        result[i] = data[i] ^ key[i % key_length]
    return bytes(result)

e2 = 10706859949950921239354880312196039515724907
f1 = 4585958212176920650644941909171976689111990
f2 = 3062959364761961602614252587049328627114908
enc = e2^f2^f1
data = long_to_bytes(enc)

#data = b'mes)_c@3LHobXchblA'
#key = b'><0R'

print(xor(b'><0R', data))
#b'SYC{a_part_0f_X0R}'

dp

from Crypto.Util.number import getPrime,bytes_to_long

p,q = getPrime(512),getPrime(512)
n = p * q
e = 65537
d = pow(e,-1,(p-1) * (q-1))
dp = d % (p-1)
m = bytes_to_long(flag)
c = pow(m, e, n)


print("c = ",c)
print("n = ",n)
print("e = ",e)
print("dp = ",dp)

'''
c =  127916287434936224964530288403657504450134210781148845328357237956681373722556447001247137686758965891751380034827824922625307521221598031789165449134994998397717982461775225812413476283147124013667777578827293691666320739053915493782515447112364470583788127477537555786778672970196314874316507098162498135060
n =  157667866005866043809675592336288962106125998780791920007920833145068421861029354497045918471672956655205541928071253023208751202980457919399456984628429198438149779785543371372206661553180051432786094530268099696823142821724314197245158942206348670703497441629288741715352106143317909146546420870645633338871
e =  65537
dp =  2509050304161548479367108202753097217949816106531036020623500808413533337006939302155166063392071003278307018323129989037561756887882853296553118973548769
'''

直接攻击就好。

链接:dp泄露攻击_CSDN

from Crypto.Util.number import *

c =  127916287434936224964530288403657504450134210781148845328357237956681373722556447001247137686758965891751380034827824922625307521221598031789165449134994998397717982461775225812413476283147124013667777578827293691666320739053915493782515447112364470583788127477537555786778672970196314874316507098162498135060
n =  157667866005866043809675592336288962106125998780791920007920833145068421861029354497045918471672956655205541928071253023208751202980457919399456984628429198438149779785543371372206661553180051432786094530268099696823142821724314197245158942206348670703497441629288741715352106143317909146546420870645633338871
e =  65537
dp =  2509050304161548479367108202753097217949816106531036020623500808413533337006939302155166063392071003278307018323129989037561756887882853296553118973548769

def attack(c, n, e, dp):
    for i in range(1,e):
        if(dp*e-1)%i == 0:
            if n % (((dp * e - 1) // i) + 1) == 0:
                p = ((dp * e - 1) // i) + 1
                q = n // (((dp * e - 1) // i) + 1)
                phi = (q - 1) * (p - 1)
                d = inverse(e, phi)
                return long_to_bytes(pow(c, d, n))
    return None

print(attack(c, n, e, dp))
#b'SYC{welcome_to_crypto}'

共模攻击

from Crypto.Util.number import *
from secret import flag
p,q = [getPrime(1024) for _ in range(2)]
n = p*q
e = [getPrime(10) for _ in range(2)]

m = bytes_to_long(flag)

c = [pow(m, e[i], n) for i in range(2)]
print(f'n = {n}')
print(f'e1 = {e[0]}')
print(f'e2 = {e[1]}')
print(f'c1 = {c[0]}')
print(f'c2 = {c[1]}')
'''
n = 19742875423645690846073637620470497648804310111201409901059297083827103813674034450200432098143959078292346910591785265323563248781526393718834491458926162514713269984791730816121181307827624489725923763353393879316510062227511469438742429290073999388690825732236465647396755899136346150862848924231619666069528077790933176798057396704758072769660663756346237040909579775389576227450505746914753205890194457812893098491264392293949768193694560954874603451253079446652049592976605414438411872223250039782381259212718733455588477129910357095186014496957765297934289263536712574572533650393220492870445376144568199077767
e1 = 911
e2 = 967
c1 = 18676091924461946809127036439355116782539894105245796626898495935702348484076501694838877829307466429933623102626122909782775514926293363853121828819237500456062111805212209491398720528499589486241208820804465599279152640624618194425740368495072591471531868392274503936869225072123214869399971636428177516761675388589238329574042518038702529606188240859751459632643230538522947412931990009143731829484941397093509641320264169403755707495153433568106934850283614529793695266717330769019091782929139589939928210818515744604847453929432990185347112319971445630830477574679898503825626294542336195240055995445217249602983
c2 = 4229417863231092939788858229435938841085459330992709019823280977891432565586698228613770964563920779991584732527715378842621171338649745186081520176123907689669636473919678398014317024138622949923292787095400632018991311254591786179660603414693984024161009444842277220189315861986306573182865656366278782315864366857374874763243428496061153290565891942968876789905670073321426112497113145141539289020571684634406829272902118484670099097148727072718299512735637087933649345419433312872607209633402427461708181971718804026293074540519907755129917132236240606834816534369171888633588190859475764799895410284484045429152
'''

主要是通过拓展欧几里得原理配凑出:e1s1+e2s2=1e_1*s_1+e_2*s_2=1,从而直接通过c1和c2恢复m(注意mod n)

from Crypto.Util.number import *
n = 19742875423645690846073637620470497648804310111201409901059297083827103813674034450200432098143959078292346910591785265323563248781526393718834491458926162514713269984791730816121181307827624489725923763353393879316510062227511469438742429290073999388690825732236465647396755899136346150862848924231619666069528077790933176798057396704758072769660663756346237040909579775389576227450505746914753205890194457812893098491264392293949768193694560954874603451253079446652049592976605414438411872223250039782381259212718733455588477129910357095186014496957765297934289263536712574572533650393220492870445376144568199077767
e1 = 911
e2 = 967
c1 = 18676091924461946809127036439355116782539894105245796626898495935702348484076501694838877829307466429933623102626122909782775514926293363853121828819237500456062111805212209491398720528499589486241208820804465599279152640624618194425740368495072591471531868392274503936869225072123214869399971636428177516761675388589238329574042518038702529606188240859751459632643230538522947412931990009143731829484941397093509641320264169403755707495153433568106934850283614529793695266717330769019091782929139589939928210818515744604847453929432990185347112319971445630830477574679898503825626294542336195240055995445217249602983
c2 = 4229417863231092939788858229435938841085459330992709019823280977891432565586698228613770964563920779991584732527715378842621171338649745186081520176123907689669636473919678398014317024138622949923292787095400632018991311254591786179660603414693984024161009444842277220189315861986306573182865656366278782315864366857374874763243428496061153290565891942968876789905670073321426112497113145141539289020571684634406829272902118484670099097148727072718299512735637087933649345419433312872607209633402427461708181971718804026293074540519907755129917132236240606834816534369171888633588190859475764799895410284484045429152

def ext_gcd(a, b):
    if b == 0:
        return (1, 0, a)
    else:
        x, y, d = ext_gcd(b, a % b)
        return (y, x - (a // b) * y, d)

s1,s2,_ = ext_gcd(e1, e2)

print(long_to_bytes((pow(c1,s1,n)*pow(c2,s2,n))%n))
#b'SYC{U_can_really_attack}'

RSA

from Crypto.Util.number import bytes_to_long, getPrime
from secret import flag
p = getPrime(128)
q = getPrime(128)
n = p*q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f"n = {n}")
print(f"p = {p}")
print(f"q = {q}")
print(f"c = {c}")

'''
n = 33108009203593648507706487693709965711774665216872550007309537128959455938833
p = 192173332221883349384646293941837353967
q = 172282016556631997385463935089230918399
c = 5366332878961364744687912786162467698377615956518615197391990327680664213847
'''
from Crypto.Util.number import *

n = 33108009203593648507706487693709965711774665216872550007309537128959455938833
p = 192173332221883349384646293941837353967
q = 172282016556631997385463935089230918399
c = 5366332878961364744687912786162467698377615956518615197391990327680664213847
e = 65537

d = inverse(e, (p-1)*(q-1))
print(long_to_bytes(pow(c, d, n)))
#b'SYC{RSA_is_easy}'

nc

from hashlib import sha256
import socketserver
import os
import signal
import string
import random

flag = "SYC{...}"

class Task(socketserver.BaseRequestHandler):

    ctry = 0

    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass

    def recv(self, prompt=b'[-] '):
        self.send(prompt, newline=False)
        return self._recvall()

    def proof_of_work(self):
        random.seed(os.urandom(8))
        proof = ''.join(
            [random.choice(string.ascii_letters+string.digits) for _ in range(20)])
        _hexdigest = sha256(proof.encode()).hexdigest()
        self.send(f"[+] sha256(XXXX+{proof[4:]}) == {_hexdigest}".encode())
        x = self.recv(prompt=b'[+] Plz tell me XXXX: ')
        if len(x) != 4 or sha256(x+proof[4:].encode()).hexdigest() != _hexdigest:
            return False
        return True

    def handle(self):
        signal.alarm(60)
        try:
            if not self.proof_of_work():
                self.send(b'[!] Wrong!')
                self.send(b'[*] Maybe you need a little force, right?')
                return
            else:
                self.send(b'[*] HEY, MY NEW FRIENDDD, YOUUUUUU FIND THE RIGHT WAAAAAAY!')
                self.send(b'[*] Or even more complex?')
                self.send(b'[*] Maybe these details are not important. See below :D')

            signal.alarm(400)
            self.send(b'[+] ')
            while self.ctry < 35:
                data = self.recv().decode()
                f = self.oraicle(data)
                self.send(f)
                self.ctry += 1

        except TimeoutError:
            self.send(b'[!] Ohhehe, Timeout!')

    def oraicle(self,a):

        if a.isdigit() and int(a)<33 and int(a)>0:
            a = int(a)-1
            return b'[+] ' + flag[a].encode()

        return  b'[!] Invalid Member!'


class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass


if __name__ == "__main__":
    HOST,PORT = '0.0.0.0',12321
    server = ForkedServer((HOST,PORT),Task)
    server.allow_reuse_address = True
    print(HOST, PORT)
    server.serve_forever()

根据附件,nc链接上之后,一方面要找到一个四位字符串满足sha256,同时又知通过输入数字,获取对应位置的FLAG:

from hashlib import sha256

list_s=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']

for a in list_s:
    for b in list_s:
        for c in list_s:
            for d in list_s:
                ss=a+b+c+d+'7S5UQluQWcjGBS9D'
                if(sha256(ss.encode()).hexdigest()=='cbd4cde204335bb748133041cb3b8e572371baf7614271268b2a65545ef94aed'):
                    print(a+b+c+d)
                    break
#gN1R
[-] 1
[+] S
[-] 2
[+] Y
[-] 3
[+] C
[-] 4
[+] {
[-] 5
[+] M
[-] 6
[+] A
[-] 7
[+] Y
[-] 8
[+] B
[-] 9
[+] 3
[-] 10
[+] _
[-] 11
[+] Y
[-] 12
[+] 0
[-] 13
[+] U
[-] 14
[+] _
[-] 15
[+] K
[-] 16
[+] N
[-] 17
[+] 0
[-] 18
[+] W
[-] 19
[+] _
[-] 20
[+] A
[-] 21
[+] 1
[-] 22
[+] A
[-] 23
[+] N
[-] 24
[+] -
[-] 25
[+] B
[-] 26
[+] 3
[-] 27
[+] <
[-] 28
[+] K
[-] 29
[+] 3
[-] 30
[+] R
[-] 31
[+] ?
[-] 32
[+] }

处理此串:

a='[-] 1\
[+] S\
[-] 2\
[+] Y\
[-] 3\
[+] C\
[-] 4\
[+] {\
[-] 5\
[+] M\
[-] 6\
[+] A\
[-] 7\
[+] Y\
[-] 8\
[+] B\
[-] 9\
[+] 3\
[-] 10\
[+] _\
[-] 11\
[+] Y\
[-] 12\
[+] 0\
[-] 13\
[+] U\
[-] 14\
[+] _\
[-] 15\
[+] K\
[-] 16\
[+] N\
[-] 17\
[+] 0\
[-] 18\
[+] W\
[-] 19\
[+] _\
[-] 20\
[+] A\
[-] 21\
[+] 1\
[-] 22\
[+] A\
[-] 23\
[+] N\
[-] 24\
[+] -\
[-] 25\
[+] B\
[-] 26\
[+] 3\
[-] 27\
[+] <\
[-] 28\
[+] K\
[-] 29\
[+] 3\
[-] 30\
[+] R\
[-] 31\
[+] ?\
[-] 32\
[+] }'
for i in range(len(a)):
    if a[i]=='+':
        print(a[i+3],end='')
        
#SYC{MAYB3_Y0U_KN0W_A1AN-B3<K3R?}

ezRSA

from Crypto.Util.number import *
from secret import flag
m = bytes_to_long(flag)
assert m.bit_length()<500

p = getPrime(512)
q = getPrime(512)
n = p*q
e = 3
c = pow(m, e, n)
bits = 150
m = (m >> bits) << bits
h = (2024*m-2023) % n

print('n =',n)
print('c =',c)
print('h =',h)
n = 98776098002891477120992675696155328927086322526307976337988006606436135336004472363084175941067711391936982491358233723506086793155908108571814951698009309071244571404116817767749308434991695075517682979438837852005396491907180020541510210086588426719828012276157990720969176680296088209573781988504138607511
c = 9379399412697943604731810117788765980709097637865795846842608472521416662350816995261599566999896411508374352899659705171307916591351157861393506101348972544843696221631571188094524310759046142743046919075577350821523746192424192386688583922197969461446371843309934880019670502610876840610213491163201385965
h = 111518648179416351438603824560360041496706848494616308866057817087295675324528913254309319829895222661760009533326673551072163865

由h的得出方式求m:

from Crypto.Util.number import *
n = 98776098002891477120992675696155328927086322526307976337988006606436135336004472363084175941067711391936982491358233723506086793155908108571814951698009309071244571404116817767749308434991695075517682979438837852005396491907180020541510210086588426719828012276157990720969176680296088209573781988504138607511
h = 111518648179416351438603824560360041496706848494616308866057817087295675324528913254309319829895222661760009533326673551072163865

for k in range(10000):
    mm=(h+k*n+2023)%2024
    if mm==0 and mm.bit_length()<500:
        print((h+k*n+2023)//2024)
        break

由题目中的m和h知道这是高位泄露,并且余位152*3<1024符合comppersmith攻击的界(题中是150位的归零操作,但是一个字节8bits,故找一个大于150且是8的整数倍的最小值作为目标,即152bits)

from Crypto.Util.number import *
from sage.all import *

n = 98776098002891477120992675696155328927086322526307976337988006606436135336004472363084175941067711391936982491358233723506086793155908108571814951698009309071244571404116817767749308434991695075517682979438837852005396491907180020541510210086588426719828012276157990720969176680296088209573781988504138607511
c = 9379399412697943604731810117788765980709097637865795846842608472521416662350816995261599566999896411508374352899659705171307916591351157861393506101348972544843696221631571188094524310759046142743046919075577350821523746192424192386688583922197969461446371843309934880019670502610876840610213491163201385965
e=3

pad=bytes_to_long(b'SYC{crypto_is_very_interesting_wh')

P.<x> = PolynomialRing(Zmod(n))
f =((x+pad*2**152)^e - c).monic()

print(long_to_bytes(pad*2**152+int(f.small_roots(X=2**152,beta=0.4)[0])))
#b'SYC{crypto_is_very_interesting_why_dont_you_join_us}'