2023羊城杯密码wp

3-1 Danger_RSA

e e e 为34位数,所以 s s s t t t为17位数,求出 a = 4 a=4 a=4,且 s s s t t t有两种可能

s = 3 * 7 * 7 * 691
t = 19 * 5741
s = 7 * 19 * 691
t = 3 * 7 * 5741

根据 g e t _ k e y ( ) get\_key() get_key():
p = X 1 4 + s q = X 2 4 + t N = ( X 1 ∗ X 2 ) 4 + X 1 4 ∗ t + X 2 4 ∗ s + e p=X_1^4+s\\q=X_2^4+t\\N=(X_1*X_2)^4+X_1^4*t+X_2^4*s+e p=X14+sq=X24+tN=(X1X2)4+X14t+X24s+e
N N N开四次方根得到 X 1 ∗ X 2 X_1*X_2 X1X2,这样我们就有了2元方程组,对两组 s s s t t t分别尝试解方程组,最终求得 X 1 X_1 X1 X 2 X_2 X2的整数解,从而求出 p p p q q q

g c d ( e ,   p − 1 ) = 3   &   g c d ( e ,   q − 1 ) = 7 gcd(e,\ p-1)=3\ \&\ gcd(e,\ q-1)=7 gcd(e, p1)=3 & gcd(e, q1)=7

取那个公因子为 3 3 3的素数进行有限域开方。

from Crypto.Util.number import *
from gmpy2 import iroot

N = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766
a = 4
xx = int(iroot(N, a)[0])

s = 7 * 19 * 691
t = 3 * 7 * 5741
x1, x2 = var('x1 x2')
solve([x1*x2==xx, (x1**4+s)*(x2**4+t)==N],x1,x2, solution_dict=True)
# {x1: 44416071018427916652440592614276227563515579156219730344722242565477265479486, x2: 47783641287938625512681830427927501009821495321018170621907812035456872958654}

p = 44416071018427916652440592614276227563515579156219730344722242565477265479486**4+s
q = N // p
assert gcd(e, q-1) == 3
d = inverse(e//3, q-1)
c = int(pow(c, d, q))

PR.<x> = Zmod(q)[]
f = x^3 - c
res = f.roots()
for i in res:
    print(long_to_bytes(int(i[0])))
# b'DASCTF{C0nsTruct!n9_Techn1qUe2_f0r_RSA_Pr1me_EnC2ypt10N}'

3-2 Easy_3L

c = ( s ∗ h + m s g )   %   p = > − s ∗ h + c − k ∗ p = m s g c = (s * h + msg)\ \%\ p\\=>-s*h +c-k*p=msg c=(sh+msg) % p=>sh+ckp=msg

构造格子
[ 1 0 − h 0 2 512 c 0 0 p ] \left [ \begin{matrix} 1& 0& -h \\ 0& 2^{512}& c\\ 0&0&p\\ \end{matrix} \right ] 100025120hcp

格基规约求出 S 3 S_3 S3 L C G LCG LCG恢复 n , a , b n,a,b n,a,b,最后求出 f l a g flag flag

from Crypto.Util.number import *
from math import gcd

from sage.all import GF
from sage.all import is_prime_power


def attack(y, m=None, a=None, c=None):
    """
    Recovers the parameters from a linear congruential generator.
    If no modulus is provided, attempts to recover the modulus from the outputs (may require many outputs).
    If no multiplier is provided, attempts to recover the multiplier from the outputs (requires at least 3 outputs).
    If no increment is provided, attempts to recover the increment from the outputs (requires at least 2 outputs).
    :param y: the sequential output values obtained from the LCG
    :param m: the modulus of the LCG (can be None)
    :param a: the multiplier of the LCG (can be None)
    :param c: the increment of the LCG (can be None)
    :return: a tuple containing the modulus, multiplier, and the increment
    """
    if m is None:
        assert len(y) >= 4, "At least 4 outputs are required to recover the modulus"
        for i in range(len(y) - 3):
            d0 = y[i + 1] - y[i]
            d1 = y[i + 2] - y[i + 1]
            d2 = y[i + 3] - y[i + 2]
            g = d2 * d0 - d1 * d1
            m = g if m is None else gcd(g, m)
        assert is_prime_power(m), "Modulus must be a prime power, try providing more outputs"

    gf = GF(m)
    if a is None:
        assert len(y) >= 3, "At least 3 outputs are required to recover the multiplier"
        x0 = gf(y[0])
        x1 = gf(y[1])
        x2 = gf(y[2])
        a = int((x2 - x1) / (x1 - x0))

    if c is None:
        assert len(y) >= 2, "At least 2 outputs are required to recover the multiplier"
        x0 = gf(y[0])
        x1 = gf(y[1])
        c = int(x1 - a * x0)

    return m, a, c
S1 = 28572152986082018877402362001567466234043851789360735202177142484311397443337910028526704343260845684960897697228636991096551426116049875141
S2 = 1267231041216362976881495706209012999926322160351147349200659893781191687605978675590209327810284956626443266982499935032073788984220619657447889609681888
S4 = 9739918644806242673966205531575183334306589742344399829232076845951304871478438938119813187502023845332528267974698273405630514228632721928260463654612997
S5 = 9755668823764800147393276745829186812540710004256163127825800861195296361046987938775181398489372822667854079119037446327498475937494635853074634666112736
p = 25886434964719448194352673440525701654705794467884891063997131230558866479588298264578120588832128279435501897537203249743883076992668855905005985050222145380285378634993563571078034923112985724204131887907198503097115380966366598622251191576354831935118147880783949022370177789175320661630501595157946150891275992785113199863734714343650596491139321990230671901990010723398037081693145723605154355325074739107535905777351
h = 2332673914418001018316159191702497430320194762477685969994411366563846498561222483921873160125818295447435796015251682805613716554577537183122368080760105458908517619529332931042168173262127728892648742025494771751133664547888267249802368767396121189473647263861691578834674578112521646941677994097088669110583465311980605508259404858000937372665500663077299603396786862387710064061811000146453852819607311367850587534711
c = 20329058681057003355767546524327270876901063126285410163862577312957425318547938475645814390088863577141554443432653658287774537679738768993301095388221262144278253212238975358868925761055407920504398004143126310247822585095611305912801250788531962681592054588938446210412897150782558115114462054815460318533279921722893020563472010279486838372516063331845966834180751724227249589463408168677246991839581459878242111459287
M = matrix(ZZ, [[1, 0, -h], [0, 2**512, c], [0, 0, p]])
res = M.LLL()
S3 = int(res[0][2])
# S3 = 10700695166096094995375972320865971168959897437299342068124161538902514000691034236758289037664275323635047529647532200693311709347984126070052011571264606
n, a, b = attack([S1, S2, S3, S4, S5])
m = (S1-b) * inverse(a, n) % n
print(long_to_bytes(m))
# b'DASCTF{NTRU_L0G_a6e_S1mpLe}'

3-3 SigninCrypto

K1 = key
hint1 = os.urandom(2) * 8
xor =bytes_to_long(hint1)^bytes_to_long(K1)
print(xor)
# xor = 334648638865560142973669981316964458403

x o r xor xor转字节,发现有重复字节b'\xfb\xc2',确定 h i n t 1 hint1 hint1,从而求出 K 1 K1 K1

from Crypto.Util.strxor import strxor
xor = 334648638865560142973669981316964458403
xor = long_to_bytes(xor)
# b'\xfb\xc2\xfb\xc2\xfb\xc2\xfb\xc2\x9f\xa3\x88\xa1\x8f\xa4\x9f\xa3'
hint1 = xor[:2]*8
K1 = strxor(xor, hint1).strip(b'\x00')
print(K1)
# b'dasctfda'

K 2 K2 K2是预测随机数。 L i s t 1 List1 List1 624 624 624 g e t r a n d b i t s ( 16 ) getrandbits(16) getrandbits(16) L i s t 2 List2 List2 312 312 312 ( r a n d 64   &   0 x f f f f )   ∣   ( ( r a n d 64   > >   32 )   &   0 x f f f f )   < <   16 (rand64\ \&\ 0xffff)\ |\ ((rand64\ >>\ 32)\ \&\ 0xffff)\ <<\ 16 (rand64 & 0xffff)  ((rand64 >> 32) & 0xffff) << 16

同一个 s e e d seed seed

from random import *
seed(0)
a = getrandbits(16)
b = getrandbits(16)
seed(0)
c = getrandbits(32)
d = getrandbits(32)
seed(0)
e = getrandbits(64)

rand64 = e
x = (rand64 & 0xffff) | ((rand64 >> 32) & 0xffff) << 16
assert a == c >> 16 and b == d >> 16
assert c | d << 32 == e
assert (b << 48) | (x >> 16 << 32) | (a << 16) | (x & 0xffff) == e

这样就还原 312 312 312 g e t r a n d b i t s ( 64 ) getrandbits(64) getrandbits(64),即可准确预测下一个 g e t r a n d b i t s ( 64 ) getrandbits(64) getrandbits(64)

K 3 K3 K3已知前一个字符为 D A S C T F { DASCTF\{ DASCTF{,最后再爆破一个即可。

I V IV IV类似 K 1 K1 K1求法,给出了 d i g e s t digest digest h i n t 2 hint2 hint2,发现 d i g e s t digest digest前后两段一致,所以有 I V 1 = = I V 2 IV1==IV2 IV1==IV2

h i n t 2 hint2 hint2直接转字节,直接有了四个字节的部分 I V IV IV h i n t 2 hint2 hint2 96 96 96位,其中包含了左移的 32 32 32位和原来的 64 64 64位的 I V IV IV,所以 I V 1 IV1 IV1 I V 2 IV2 IV2各占 32 32 32位,即 4 4 4个字节,所以 h i n t 2 hint2 hint2给出的四个字节的 I V IV IV就是 I V 1 IV1 IV1

from Crypto.Cipher import DES3
from Crypto.Util.number import *
from Crypto.Util.strxor import strxor

xor = 334648638865560142973669981316964458403
digest = 0x62343937373634656339396239663236643437363738396663393438316230353665353733303939613830616662663633326463626431643139323130616333363363326631363235313661656632636265396134336361623833636165373964343533666537663934646239396462323666316236396232303539336438336234393737363465633939623966323664343736373839666339343831623035366535373330393961383061666266363332646362643164313932313061633336336332663136323531366165663263626539613433636162383363616537396434353366653766393464623939646232366631623639623230353933643833
hint2 = 22078953819177294945130027344
ciphertext = 'a6546bd93bced0a8533a5039545a54d1fee647007df106612ba643ffae850e201e711f6e193f15d2124ab23b250bd6e1'

xor = long_to_bytes(xor)
hint1 = xor[:2] * 8
K1 = strxor(xor, hint1).strip(b'\x00')

List1 = []
List2 = []
with open('task.txt', 'r') as f:
    datas = f.readlines()
    for i in range(624):
        List1.append(eval(datas[i].strip('\n')))
    for i in range(624, 624 + 312):
        List2.append(eval(datas[i].strip('\n')))
import mt19937predictor

pre = mt19937predictor.MT19937Predictor()
for i in range(312):
    pre.setrandbits((List1[2 * i + 1] << 48) | (List2[i] >> 16 << 32) | (List1[2 * i] << 16) | (List2[i] & 0xffff), 64)
K2 = long_to_bytes(pre.getrandbits(64))
K3 = b'DASCTF{'
KEY = K1 + K2 + K3
IV = long_to_bytes(hint2)[:4] * 2

mode = DES3.MODE_CBC
for i in range(256):
    KEY0 = KEY + long_to_bytes(i)
    des3 = DES3.new(KEY0, mode, IV)
    plaintxt = des3.decrypt(bytes.fromhex(ciphertext))
    if b'DASCTF' in plaintxt:
        print(plaintxt)
        break
# b'DASCTF{8e5ee461-f4e1-4af2-8632-c9d62f4dc073}\x04\x04\x04\x04'

3-4 esyRSA

常规的 R S A RSA RSA,给了 n n n d d d, 没给 e e e,注意给的 n n n是重复的(附件的问题),最后要我们求 p + q p+q p+q

e e e最简单的就是直接维纳攻击套脚本,但我选择构造格
e ∗ d = k ∗ n − k ∗ ( p + q − 1 ) + 1 [ − e k ] ∗ [ 2 512 d 0 n ] = [ − e ∗ 2 512 k ∗ ( p + q − 1 ) − 1 ] e*d = k*n -k*(p+q-1)+1\\ \left [ \begin{matrix} -e& k \\ \end{matrix} \right ] * \left [ \begin{matrix} 2^{512}& d \\ 0& n\\ \end{matrix} \right ]= \left [ \begin{matrix} -e*2^{512}& k*(p+q-1)-1 \end{matrix} \right ] ed=knk(p+q1)+1[ek][25120dn]=[e2512k(p+q1)1]
格基规约后求的 e e e k = g c d ( e ∗ d − 1 , k ∗ ( p + q − 1 ) − 1 + 1 ) k=gcd(e*d-1, k*(p+q-1)-1+1) k=gcd(ed1,k(p+q1)1+1)

最后可求出 p + q p+q p+q

from hashlib import md5

n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
m = matrix(ZZ, [[2**512, d], [0, n]])
res = m.LLL()[0]
e = -res[0]//2**512
k = gcd(e*d - 1, res[1]+1)
p_q = res[1] + 1 // k + 1
print("Flag: DASCTF{%s}" %md5(str(p_q).encode()).hexdigest())
# Flag: DASCTF{4ae33bea90f030bfddb7ac4d9222ef8f}

3-5 MCeorpkpleer

已知 p p p的高位, c o p p e r s m i t h coppersmith coppersmith即可

背包密码恢复 e e e

from Crypto.Util.number import *

p = 139540788452365306201344680691061363403552933527922544113532931871057569249632300961012384092481349965600565669315386312075890938848151802133991344036696488204791984307057923179655351110456639347861739783538289295071556484465877192913103980697449775104351723521120185802327587352171892429135110880845830815744
n = 22687275367292715121023165106670108853938361902298846206862771935407158965874027802803638281495587478289987884478175402963651345721058971675312390474130344896656045501040131613951749912121302307319667377206302623735461295814304029815569792081676250351680394603150988291840152045153821466137945680377288968814340125983972875343193067740301088120701811835603840224481300390881804176310419837493233326574694092344562954466888826931087463507145512465506577802975542167456635224555763956520133324723112741833090389521889638959417580386320644108693480886579608925996338215190459826993010122431767343984393826487197759618771
c = 156879727064293983713540449709354153986555741467040286464656817265584766312996642691830194777204718013294370729900795379967954637233360644687807499775502507899321601376211142933572536311131955278039722631021587570212889988642265055045777870448827343999745781892044969377246509539272350727171791700388478710290244365826497917791913803035343900620641430005143841479362493138179077146820182826098057144121231954895739989984846588790277051812053349488382941698352320246217038444944941841831556417341663611407424355426767987304941762716818718024107781873815837487744195004393262412593608463400216124753724777502286239464
pubkey = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 601827224419797931380408071500, 1805481673259393794141224214500, 893952418336266652976851386463, 2681857255008799958930554159389, 3523079163584485147344841221130, 1524252287869625983140881149316, 50264262166963219975822190911, 150792786500889659927466572733, 452378359502668979782399718199, 1357135078508006939347199154597, 4071405235524020818041597463791, 3169230503688232995231149877299, 462706308180869526799807117823, 1388118924542608580399421353469, 4164356773627825741198264060407, 3448085117999647764701149667147, 1299270151115113835209806487367, 3897810453345341505629419462101, 2648446157152195057994615872229, 3422845870014670444537026359650, 1223552407160181874717436564876, 3670657221480545624152309694628, 1966986461557807413563286569810, 1378466783231507511243038452393, 4135400349694522533729115357179, 3361215846199738142293703557463, 1038662335715384967987468158315, 3115987007146154903962404474945, 302975818554635252993570910761, 908927455663905758980712732283, 2726782366991717276942138196849, 3657854499533237101379593333510, 1928578295715881845245137486456, 1263242285705730806288591202331, 3789726857117192418865773606993, 2324195368467747797703678306905, 2450093503961328663664213663678, 2827787910442071261545819733997, 3960871129884299055190637944954, 2837628186769067706678271320788]
en_e = 31087054322877663244023458448558

PR.<x> = Zmod(n)[]
f = x + p
p = int(p + f.small_roots(2^435, beta = 0.4)[0])
q = n // p

ns = len(pubkey)
d = ns / log(max(pubkey))
N = ceil(1 / 2 * sqrt(n))
assert d < 0.9408, f"Density should be less than 0.9408 but was {d}."

L = matrix(QQ, ns + 1, ns + 1)
for i in range(ns):
    L[i, i] = 1
    L[i, ns] = N * pubkey[i]

L[ns] = [1 / 2] * ns + [N * en_e]
res = L.LLL()
for v in res:
    s_ = 0
    e = []
    for i in range(ns):
        ei = 1 - (v[i] + 1 / 2)
        if ei != 0 and ei != 1:
            break

        ei = int(ei)
        s_ += ei * pubkey[i]
        e.append(ei)

    if s_ == en_e:
        break
e = [str(i) for i in e]
e = int(''.join(e), 2)

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
print(long_to_bytes(int(pow(c, d, n))))
# b'DASCTF{T81I_tPPS_6r7g_xlPi_OO3M_6vyV_Rkba}'

3-6 XOR贯穿始终

自由和谐和谐富强公正友善爱国公正法治法治文明和谐自由法治自由法治平等公正友善公正公正民主法治自由公正敬业和谐富强公正友善爱国和谐平等平等友善敬业法治敬业和谐富强法治平等平等友善敬业公正公正公正友善敬业法治平等平等诚信自由公正自由平等友善敬业公正友善法治和谐和谐

社会主义核心价值观编码,解码一下得到压缩包密码,且在后面用于异或。

C0ngr4tulati0n5_y0u_fou^d_m3

给了pri.pem文件,其中给出了公钥 n , e n,e n,e,私钥 d d d,以及 p p p q q q

MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALmtMy+2uH1ZtbIL
SuiAukFthyQRH5mp7UmLyzZQkdg9zEP9/5tgffikQ7ytx5kHySHnazgAO1sOzmYE
N4Axlev6uafiP8B1Eij97v5VkYJ1I9e3mtBNheTbXKoT8op+ASQ1fQaF4A8UzLuW
eZeZI8JTH/SH+bolAK3kiZXDFdkTAgMBAAECgYEAl067LaC7Cvs2A5cMPhfYsESv
IgcKN1CwW4Sd3u8dSphhgu7TgyzIuvwxbuo2g1BC6WwKhaI6vGN+csfw6nh98GEn
/p3D0huNroAYvf/DRRB9UnHdttX7wB+Mv3P0RBDWHgBiCDVvHFuFUV78cIs0tnbn
jxjU07aPV2XRC3AfA2ECQQDqWUNPVg3i6vTyHCL7EGkbeUheYpAAfcKCQrxjc5+5
X6A+XtgHAA1JHwykPlCpHUOmlA85DJF1ejuoImzlgRLJAkEAytTCnQF+MN2r1gaA
UETZyj5qMYT7Th8zKEVVVJjDawLnuX4usJ2FyRnjCkk86U75QSJhw5mMc0QnG25u
Gz3++w==

b a s e 64 base64 base64编码再转成 16 16 16进制

30 82 02 77 02 01 00 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 04 82 02 61 30 82 02 5d 02 01 00 02 81 81 00 b9 ad 33 2f b6 b8 7d 59 b5 b2 0b 4a e8 80 ba 41 6d 87 24 11 1f 99 a9 ed 49 8b cb 36 50 91 d8 3d cc 43 fd ff 9b 60 7d f8 a4 43 bc ad c7 99 07 c9 21 e7 6b 38 00 3b 5b 0e ce 66 04 37 80 31 95 eb fa b9 a7 e2 3f c0 75 12 28 fd ee fe 55 91 82 75 23 d7 b7 9a d0 4d 85 e4 db 5c aa 13 f2 8a 7e 01 24 35 7d 06 85 e0 0f 14 cc bb 96 79 97 99 23 c2 53 1f f4 87 f9 ba 25 00 ad e4 89 95 c3 15 d9 13 02 03 01 00 01 02 81 81 00 97 4e bb 2d a0 bb 0a fb 36 03 97 0c 3e 17 d8 b0 44 af 22 07 0a 37 50 b0 5b 84 9d de ef 1d 4a 98 61 82 ee d3 83 2c c8 ba fc 31 6e ea 36 83 50 42 e9 6c 0a 85 a2 3a bc 63 7e 72 c7 f0 ea 78 7d f0 61 27 fe 9d c3 d2 1b 8d ae 80 18 bd ff c3 45 10 7d 52 71 dd b6 d5 fb c0 1f 8c bf 73 f4 44 10 d6 1e 00 62 08 35 6f 1c 5b 85 51 5e fc 70 8b 34 b6 76 e7 8f 18 d4 d3 b6 8f 57 65 d1 0b 70 1f 03 61 02 41 00 ea 59 43 4f 56 0d e2 ea f4 f2 1c 22 fb 10 69 1b 79 48 5e 62 90 00 7d c2 82 42 bc 63 73 9f b9 5f a0 3e 5e d8 07 00 0d 49 1f 0c a4 3e 50 a9 1d 43 a6 94 0f 39 0c 91 75 7a 3b a8 22 6c e5 81 12 c9 02 41 00 ca d4 c2 9d 01 7e 30 dd ab d6 06 80 50 44 d9 ca 3e 6a 31 84 fb 4e 1f 33 28 45 55 54 98 c3 6b 02 e7 b9 7e 2e b0 9d 85 c9 19 e3 0a 49 3c e9 4e f9 41 22 61 c3 99 8c 73 44 27 1b 6e 6e 1b 3d fe fb

参考以下信息,来自RSA | Lazzaro (lazzzaro.github.io),分别找到对应的 n , e , d , p , q n,e,d,p,q n,e,d,p,q 16 16 16进制

3082025d  	# Begin Sequence: len=0x025d
0201  		# Version: (len=0x01)
00
028181		# n: (len=0x81)
0203		# e: (len=0x03)
010001
028180		# d: (len=0x80)
0241		# p: (len=0x41)
0241		# q: (len=0x41)
0240		# d mod (p-1): (len=0x40)
0241		# d mod (q-1): (len=0x41)
0241		# (inverse of q) mod p: (len=0x41)		
			# End Sequence

根据 r s a rsa rsa求出 m m m m m m 40 40 40字节,前 12 12 12字节无误,但后 28 28 28字节乱码,需要和前面的C0ngr4tulati0n5_y0u_fou^d_m3(正好 28 28 28字节)进行异或得到最终 f l a g flag flag

from Crypto.Util.number import *
from Crypto.Util.strxor import strxor

d = 0x974ebb2da0bb0afb3603970c3e17d8b044af22070a3750b05b849ddeef1d4a986182eed3832cc8bafc316eea36835042e96c0a85a23abc637e72c7f0ea787df06127fe9dc3d21b8dae8018bdffc345107d5271ddb6d5fbc01f8cbf73f44410d61e006208356f1c5b85515efc708b34b676e78f18d4d3b68f5765d10b701f0361
n = 0xb9ad332fb6b87d59b5b20b4ae880ba416d8724111f99a9ed498bcb365091d83dcc43fdff9b607df8a443bcadc79907c921e76b38003b5b0ece660437803195ebfab9a7e23fc0751228fdeefe5591827523d7b79ad04d85e4db5caa13f28a7e0124357d0685e00f14ccbb9679979923c2531ff487f9ba2500ade48995c315d913
e = 0x10001
c = 91817924748361493215143897386603397612753451291462468066632608541316135642691873237492166541761504834463859351830616117238028454453831120079998631107520871612398404926417683282285787231775479511469825932022611941912754602165499500350038397852503264709127650106856760043956604644700201911063515109074933378818
p = 0xea59434f560de2eaf4f21c22fb10691b79485e6290007dc28242bc63739fb95fa03e5ed807000d491f0ca43e50a91d43a6940f390c91757a3ba8226ce58112c9
q = 0xcad4c29d017e30ddabd606805044d9ca3e6a3184fb4e1f332845555498c36b02e7b97e2eb09d85c919e30a493ce94ef9412261c3998c7344271b6e6e1b3dfefb
phi = (p - 1) * (q - 1)
key = b'C0ngr4tulati0n5_y0u_fou^d_m3'
m = long_to_bytes(pow(c, d, n))

print(m[:len(m) - len(key)] + strxor(m[len(m) - len(key):], key))
# b'DASCTF{0e2874af5e422482378640e61d919e9a}'

你可能感兴趣的:(CTF,python,安全)