window.onload=function(){ /*页面加载完成之后生成博客目录*/ BlogDirectory.createBlogDirectory("cnblogs_post_body","h2","h3",20); }

CTFtime—国外比赛趣题收集(UDCTF 2023)

UDCTF 2023

CRYPTO, BABY

RSA School 5th Grade

Tags: small-e crypto rsa  

This is what we're given:

from Crypto.Util.number import *
msg=b"UDCTF{REDACTED}"
pt=bytes_to_long(msg)
p=getPrime(1024)
q=getPrime(1024)
N=p*q
e=3
ct=pow(pt,e,N)

print(N)
print(e)
print(ct)
#N=19071553514906413228005623880868413172589438760530345745552708038769515697875361787053550188848159274987925247955174211167277615747329764460652862539122337714189780686582390326881171096308885109154336023212767779863472386169665627283720649094479648444588259600544834704143105214853522264311830387911281263299214052701109619722665736303738110883886917231219876629681611411323913511707032906816948757362133848480976586951323342448069343747851239877539085111823678094070778241732994351072251605007909682674187665596109353312252881532685577047967768366217935948525094732268620589271065304471832191222326947334404799847563
#e=3
#ct=270903177796878498388304376598565799121492331770875203351555502784804760985678087802688162298096409297508110557051747972509915173895153270896299567072600809265143377905255294763705268648639628042173298874918538565864469546919085252896111245679898930789

小明文

exp:

import gmpy2
from Crypto.Util.number import long_to_bytes
n=19071553514906413228005623880868413172589438760530345745552708038769515697875361787053550188848159274987925247955174211167277615747329764460652862539122337714189780686582390326881171096308885109154336023212767779863472386169665627283720649094479648444588259600544834704143105214853522264311830387911281263299214052701109619722665736303738110883886917231219876629681611411323913511707032906816948757362133848480976586951323342448069343747851239877539085111823678094070778241732994351072251605007909682674187665596109353312252881532685577047967768366217935948525094732268620589271065304471832191222326947334404799847563
e=3
c=270903177796878498388304376598565799121492331770875203351555502784804760985678087802688162298096409297508110557051747972509915173895153270896299567072600809265143377905255294763705268648639628042173298874918538565864469546919085252896111245679898930789

m = gmpy2.iroot(c, 3)[0]
print(long_to_bytes(m))
#UDCTF{0k_m4yb3_d0nt_u5e_e_3qu4l5_3}

RSA School 4th Grade

This is what we're given:

from Crypto.Util.number import *
e=65537
your_e = getPrime(20)
msg=bytes_to_long(b'UDCTF{REDACTED}')
p=getPrime(512)
q=getPrime(512)
n=p*q
assert(msg < n)
ct=pow(msg, e, n)
your_d = inverse(your_e, (p-1)*(q-1))
print(your_e)
print(your_d)
print(n)
print(e)
print(ct)

Use the provided RSA textbook -- https://bitsdeep.com/posts/attacking-rsa-for-fun-and-ctf-points-part-1/ -- it really helps!(参考这本RSA教科书是真的有帮助的嘿嘿!)

exp:

from Crypto.Util.number import long_to_bytes
your_e=548861
your_d=95173232432571941329231712692828118443780574466702093807146321250099677631827067825710345421542241500117509827717221625523077656554170307232963298108032249257829668442277402436905496971410095631707035128294281318370127935482352287840967522858886054571972660826718745245567014905338023490270530223206547055189
n=128923276994737790032784225847154420815473322545569053376748335367791339027988282369445542202224938698537424444443434684524386629219697192340629226569242894844874718895350330788650992608621499779776079293063355076268941953990983854217613662005027668855183281795022629934463967333582234624036115283306256019477
e=65537
c=101925091511033045433108849975441961999589763870098425244810307722908781911184299892072334641669931066841662878745617845011689451171244453969963211155840837507751273716371760271643490363012983256424608885239953158409708266675819028960222627654995967984657602529298637614235721996131897162063485544360691578861

phi = 0
k = (your_e * your_d - 1) // n
for i in range(1000000):
    if (your_e * your_d - 1) % k == 0:
        # right value of phi found
        phi = (your_e * your_d - 1) // k
        break
    k += 1

d = pow(e, -1 ,phi)
m = pow(c, d, n)
print(long_to_bytes(m))
#UDCTF{m0d_mult1pl1c4tiv3_inv3r5e_nd_57uff}

RSA School 3rd Grade

This is what we're given:

from Crypto.Util.number import *
p=getPrime(512)
q=getPrime(512)
n=p*q
e1=71
e2=101
msg=bytes_to_long(b'UDCTF{REDACTED}')
c1 = pow(msg, e1, n)
c2 = pow(msg, e2, n)
print(n)
print(e1)
print(e2)
print(c1)
print(c2)
#n=87587426608653108851564813489752475287019321764561555461700901651463446024854423042554629096780987943450742890279417241231211446818009232077230407281610183609540264821974669679932743621434901779832901512681108061652309435608446510337833028029876549629818957952682516026313018526405972829923620377438164377109
#e1=71
#e2=101
#c1=1421275848974615267320815554113040672023972283807752574007971561416386636110464890632994733734995114229161525885389065244354678964389211537085513310823751266472044865745324866096898051759507738772227296453397678055024824805366251635154522059070310922367078281343183508274450904681187384450253350434931649011
#c2=26097095086985946477598349002260598942399303275420948828501512467473619292573670218058274201990116295246084096584962695127706609264424951086000719935218496250047555039460733768633688410770610612614744411304261153778159881980276162174277085197608466835857196307432992312260307797540746411319330318058866868362

We're given two ciphertexts. According to the given RSA textbook, it seems like we can just solve this by solving Bezout's identity!
This comes from the following proof:
(我们得到了两个密文。根据给定的RSA教科书,我们似乎可以通过求解Bezout的恒等式来解决这个问题!
这来自以下证明:)

If gcd(e1, e2) = 1, then according to Bezout's identity, there exist integers a and b such that a * e1 + b * e2 = 1.
Therefore, we have the following:
c1 = m ^ e1 (mod n) ==> c1 ^ a = m ^ (e1 * a) (mod n)
c2 = m ^ e2 (mod n) ==> c2 ^ b = m ^ (e2 * b) (mod n)
c1 * c2 = m ^ (e1 * a + e2 * b) (mod n) = m ^ 1 (mod n)

Therefore, we just need to solve Bezout's identity to get m. In order to solve Bezout's identity, you can use the extended Euclid algorithm.
https://www.rookieslab.com/posts/extended-euclid-algorithm-to-find-gcd-bezouts-coefficients-python-cpp-code provides the code for the extended Euclid algorithm.

一眼丁真,共模n攻击。

expC:

n=87587426608653108851564813489752475287019321764561555461700901651463446024854423042554629096780987943450742890279417241231211446818009232077230407281610183609540264821974669679932743621434901779832901512681108061652309435608446510337833028029876549629818957952682516026313018526405972829923620377438164377109
e1=71
e2=101
c1=1421275848974615267320815554113040672023972283807752574007971561416386636110464890632994733734995114229161525885389065244354678964389211537085513310823751266472044865745324866096898051759507738772227296453397678055024824805366251635154522059070310922367078281343183508274450904681187384450253350434931649011
c2=26097095086985946477598349002260598942399303275420948828501512467473619292573670218058274201990116295246084096584962695127706609264424951086000719935218496250047555039460733768633688410770610612614744411304261153778159881980276162174277085197608466835857196307432992312260307797540746411319330318058866868362

# 已知两者n相同,e不同,共模攻击
#  c= m^e mod n
import gmpy2
from Crypto.Util.number import isPrime, sieve_base as primes, long_to_bytes

def egcd(a, b):
    if b == 0:
        return a, 0;
    else:
        x, y = egcd(b, a % b)
        return y, x - (a // b) * y  # 扩展欧几里得算法

s = egcd(e1, e2)
s1 = s[0]
s2 = s[1]
print(s[0], s[1])
m = gmpy2.powmod(c1, s1, n) * gmpy2.powmod(c2, s2, n) % n

print(long_to_bytes(m))
#UDCTF{3uc1id_th4_60at}

 expA:

def extended_euclid_gcd(a, b):
    """
    Returns a list `result` of size 3 where:
    Referring to the equation ax + by = gcd(a, b)
        result[0] is gcd(a, b)
        result[1] is x
        result[2] is y
    """
    s = 0; old_s = 1
    t = 1; old_t = 0
    r = b; old_r = a

    while r != 0:
        quotient = old_r//r # In Python, // operator performs integer or floored division
        old_r, r = r, old_r - quotient*r
        old_s, s = s, old_s - quotient*s
        old_t, t = t, old_t - quotient*t
    return [old_r, old_s, old_t]

n=87587426608653108851564813489752475287019321764561555461700901651463446024854423042554629096780987943450742890279417241231211446818009232077230407281610183609540264821974669679932743621434901779832901512681108061652309435608446510337833028029876549629818957952682516026313018526405972829923620377438164377109
e1=71
e2=101
c1=1421275848974615267320815554113040672023972283807752574007971561416386636110464890632994733734995114229161525885389065244354678964389211537085513310823751266472044865745324866096898051759507738772227296453397678055024824805366251635154522059070310922367078281343183508274450904681187384450253350434931649011
c2=26097095086985946477598349002260598942399303275420948828501512467473619292573670218058274201990116295246084096584962695127706609264424951086000719935218496250047555039460733768633688410770610612614744411304261153778159881980276162174277085197608466835857196307432992312260307797540746411319330318058866868362

#ax + by = 1
gcd, x, y = extended_euclid_gcd(e1, e2)
m = (pow(c1, x, n) * pow(c2, y, n)) % n
m = format(m, 'x')
for i in range(0, len(m), 2):
    print(chr(int(m[i:i+2], 16)), end='')
#UDCTF{3uc1id_th4_60at}

RSA School 2nd Grade

from Crypto.Util.number import *
n=166045890368446099470756111654736772731460671003059151938763854196360081247044441029824134260263654537
e=65537
msg=bytes_to_long(b'UDCTF{REDACTED}')
ct=pow(msg,e,n)
print(n)
print(e)
print(ct)   
#166045890368446099470756111654736772731460671003059151938763854196360081247044441029824134260263654537
#65537
#141927379986409920845194703499941262988061316706433242289353776802375074525295688904215113445883589653

直接分解n

exp:

import gmpy2
from Crypto.Util.number import long_to_bytes
c=141927379986409920845194703499941262988061316706433242289353776802375074525295688904215113445883589653
p=51700365364366863879483895851106199085813538441759
q=3211696652397139991266469757475273013994441374637143
e=65537

phi = (p-1) * (q-1)
n = p * q
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(m)
print(long_to_bytes(m))
#UDCTF{pr1m3_f4ct0r_the1f!}

RSA School 1st Grade

from Crypto.Util.number import *
p=getPrime(512)
q=getPrime(512)
n=p*q
e=65537
msg=bytes_to_long(b'UDCTF{REDACTED}')
ct=pow(msg,e,n)
print(p)
print(n)
print(e)
print(ct)
#7009789528005665925389589645247771843738610365138497450285434114825324963561464592190523618045678504210355855286077875965585945664408796837853566415684077
#73061872549912499570368059392056653520123131891860048946474996807859190776947568485365189613739847632132597352816568237525325622321891749472819811314630053648031678826291232292672975634200777457699671848298242827252269004463672931479153540235625891818449660268924228002522141737330313259535617652381070426543
#65537
#8099012654842320180974620472267007973324910863630262955526926760464542904631823196320598910081443799605804614201671967967929893760527002416689993003801924422327762868245291561376910828637706061326005113536536357969201659290874169593264337355365186414719656091960977568710047843815328537885731546232759484717

由q = n // p,解出q即可

exp:

import gmpy2
from Crypto.Util.number import long_to_bytes
c=8099012654842320180974620472267007973324910863630262955526926760464542904631823196320598910081443799605804614201671967967929893760527002416689993003801924422327762868245291561376910828637706061326005113536536357969201659290874169593264337355365186414719656091960977568710047843815328537885731546232759484717
p=7009789528005665925389589645247771843738610365138497450285434114825324963561464592190523618045678504210355855286077875965585945664408796837853566415684077
n=73061872549912499570368059392056653520123131891860048946474996807859190776947568485365189613739847632132597352816568237525325622321891749472819811314630053648031678826291232292672975634200777457699671848298242827252269004463672931479153540235625891818449660268924228002522141737330313259535617652381070426543
q=n//p
e=65537

phi = (p-1) * (q-1)
n = p * q
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(m)
print(long_to_bytes(m))
#UDCTF{y3a_b0i_b4by_RSA!}

Greatest Hits 1 of 4

01001010 01010110 01001100 01010101 00110010 01001110 01000011 01011010 01001011 00110101 01000100 01001000 01010011 01010101 01010011 01000110 01001101 01001101 01011001 01000111 01001001 00110011 01001011 01001111 01001011 01000010 01001010 01000110 01001111 00110010 01000100 01001010 01001101 01001001 01011001 01010101 01010011 01001110 01000011 01011010 01001110 01010110 00110010 01000110 01001101 01010101 00110011 01001101 01001100 01001001 01011001 01000111 01000011 00110010 01010011 01010011 01001010 01001010 01001000 01000101 01001101 01010100 01010100 01011010 01001100 01001010 01001100 01010110 01000101 01010111 01001011 01001110 01000111 01000110 01000010 01000110 01000001 01010100 01001100 01001100 01001110 00110101 00110101 01000110 01000101 00110010 01010011 01000111 01001011 01000010 01000111 01010110 01001111 01010010 01010100 01001111 01001011 01000110 01010110 01000101 01010101 00110110 01001011 01010110 01001110 01001010 01000100 01000101 01010101 01010111 01001011 01011001 01001011 01001010 01010110 01000110 01001111 01010010 00110011 01010001 01001001 01010010 01001001 01010110 01001111 01001111 01001011 01010100 01001011 01010110 01001011 01010101 00110100 01010101 01010100 01000010 01001001 01011010 01001000 01000100 01001001 01010100 01010011 01000110 01001000 01000110 01011001 01000101 00110100 01001101 01010010 01010010 01000111 01000010 01001011 01010111 01010111 01010010 01010100 01010101 01001101 01000110 01001101 01000101 01010101 01010100 01010011 01001110 01001011 01010010 01010101 01000101 01011001 01011001 01011010 01010100 01001111 01000010 01010001 01010101 00110010 00110011 01001011 00110010 01001110 01001110 01001100 01010101 01000011 01010000 01001010 00110101

This just seems like a bunch of nested encodings. Use CyberChef to decode and a cipher identifier for any unknown encodings!

Binary, Base32, Base64, and Base62 should be your encodings :)

UDCTF{D34r_Cyb3r_Ch3f_Th4nks_f0r_everyth1ng}

RSA School 6th Grade

from Crypto.Util.number import *
msg=b'UDCTF{REDACTED}'
pt=bytes_to_long(msg)
p1=getPrime(512)
q1=getPrime(512)
N1=p1*q1
e=3
ct1=pow(pt,e,N1)
p2=getPrime(512)
q2=getPrime(512)
N2=p2*q2
ct2=pow(pt,e,N2)
p3=getPrime(512)
q3=getPrime(512)
N3=p3*q3
ct3=pow(pt,e,N3)

print(N1)
print(N2)
print(N3)
print(e)
print(ct1)
print(ct2)
print(ct3)
101940404683148314092182537619741343820471969843093690407029610257328675616822058283838769182645366824344399515353353819793130816183060658423485619280610405015820030833852427722839904501250467628712096873390329778269768535928267751268139550847537802558918336829638018104196299204412108446654522040961058235837
74679681433630870500800762600180557065015193875421351446542706780716176492497162177418083881145442405798180136972926938569891311549925115691841878743075457971612412284596645067679716265041006557964732304139958791707676819596277816749996790403481863920999497042537177685582328973044036057708799002206799632839
100573737146541590945636341222262486942630621101299107026796895085532038383427686351121611043174306351150423506465657822449930435454418298186213727217811586553728175753616475183671899770943244241792060489168334224998929407994655190387844505675391919259886074847030882822522665949478946576261271617560351054403
3
97537343779229625148677027056474609247558991142314164186990731381686200271313205873978331513371958006472814729940790278407051941118054050488898727496970346225390695886636503944561906013129123265026309468439899500515120214095795129355317613702699593668666568316953844138511954955909885841485099479889646390930
24576278220067271066994467924629810459250013881000033163294269449098813322523936249035902376053018982711870235427255440433329932427389544039567565669233834485029769359372962513511622515998222609323796238896382805118053092524445414371375283464954274992561033256478865903093200523624090555295195503883373690124
43498624182782877233366661188600199251806006111187593264150806660094635602066978958889784097119800185861182106644332729447880775766543596889805536568073520124279816397528293711624036420976245584445797246515447058638137236091247562611424573156889579663131251891077714114495493898633857254453469780722026012280

低加密指数广播攻击

exp:

from sympy.ntheory.modular import crt
from gmpy2 import iroot
from Crypto.Util.number import *

e = 3
N = [101940404683148314092182537619741343820471969843093690407029610257328675616822058283838769182645366824344399515353353819793130816183060658423485619280610405015820030833852427722839904501250467628712096873390329778269768535928267751268139550847537802558918336829638018104196299204412108446654522040961058235837,74679681433630870500800762600180557065015193875421351446542706780716176492497162177418083881145442405798180136972926938569891311549925115691841878743075457971612412284596645067679716265041006557964732304139958791707676819596277816749996790403481863920999497042537177685582328973044036057708799002206799632839,100573737146541590945636341222262486942630621101299107026796895085532038383427686351121611043174306351150423506465657822449930435454418298186213727217811586553728175753616475183671899770943244241792060489168334224998929407994655190387844505675391919259886074847030882822522665949478946576261271617560351054403]
C =  [97537343779229625148677027056474609247558991142314164186990731381686200271313205873978331513371958006472814729940790278407051941118054050488898727496970346225390695886636503944561906013129123265026309468439899500515120214095795129355317613702699593668666568316953844138511954955909885841485099479889646390930,24576278220067271066994467924629810459250013881000033163294269449098813322523936249035902376053018982711870235427255440433329932427389544039567565669233834485029769359372962513511622515998222609323796238896382805118053092524445414371375283464954274992561033256478865903093200523624090555295195503883373690124,43498624182782877233366661188600199251806006111187593264150806660094635602066978958889784097119800185861182106644332729447880775766543596889805536568073520124279816397528293711624036420976245584445797246515447058638137236091247562611424573156889579663131251891077714114495493898633857254453469780722026012280]
resultant, mod = crt(N,C)
value, is_perfect = iroot(resultant,e)
print(long_to_bytes(value))
#UDCTF{ch1n3se_r3m4ind3r_th30r3m_f0r_th4_w1n!}

RSA School 7th Grade

from Crypto.Util.number import *
import sympy.ntheory as nt
import random
p=getPrime(1024)
q=nt.nextprime(p)
for _ in range(random.randint(500,10000)):
    q=nt.nextprime(q)
N=p*q
msg="UDCTF{REDACTED}"
pt=bytes_to_long(msg)
e=65537
ct=pow(pt,e,N)
print(N)
print(e)
print(ct)
17740803753336460891508014077951088945415214329359164945595622460861617151883658129377771074141448545977293824812472806768754107334272113784618671425945265453677763300584120796664192793654787317526905676618168560287204392207536711238413377822113265783504873957094131330620182217422910507867161033695120195691266283498385072573721376398480018719760538723050237163598524153522595496137288270407836138586188296538117138982579560625325815068701431157466298638302885600982291990551448117534677697122276691651611734934147801954625280213769902451417946572231015611006746186167211313556716518863585799128114202130873384852581
65537
7617664236008252568996899627946125782926068188323112773389474654757630578865481085502759186904920518615173703165984894164411436709177950136929724052191922739861682189280802963747906815275683543148623167088950096943169566195634558711652670745197446307315888349532981492405588457559228674864147994684328968321710022127803384848143475788457274558988285904875669797926919759123645348144531804252200718312650929926931919262408975771593313266992606751663814830129337536342634243623652919127335934704778878412649409415730419077839365246227059700689395639431013008985996793686430486195007712091309878718060405038405039494286

我们可以使用费马攻击,因为根据源代码,q 是 p 之后的下一个素数,因此 q - p 非常小。

import gmpy2

n=17740803753336460891508014077951088945415214329359164945595622460861617151883658129377771074141448545977293824812472806768754107334272113784618671425945265453677763300584120796664192793654787317526905676618168560287204392207536711238413377822113265783504873957094131330620182217422910507867161033695120195691266283498385072573721376398480018719760538723050237163598524153522595496137288270407836138586188296538117138982579560625325815068701431157466298638302885600982291990551448117534677697122276691651611734934147801954625280213769902451417946572231015611006746186167211313556716518863585799128114202130873384852581
e=65537
c=7617664236008252568996899627946125782926068188323112773389474654757630578865481085502759186904920518615173703165984894164411436709177950136929724052191922739861682189280802963747906815275683543148623167088950096943169566195634558711652670745197446307315888349532981492405588457559228674864147994684328968321710022127803384848143475788457274558988285904875669797926919759123645348144531804252200718312650929926931919262408975771593313266992606751663814830129337536342634243623652919127335934704778878412649409415730419077839365246227059700689395639431013008985996793686430486195007712091309878718060405038405039494286

a = gmpy2.iroot(n, 2)[0] + 1
b = a*a - n
while not gmpy2.iroot(b, 2)[1]:
    print(b)
    b = a*a - n
    a += 1

p = a - gmpy2.iroot(b, 2)[0]
q = n // p
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
m = pow(c, d, n)
m = format(m, 'x')
for i in range(0, len(m), 2):
    print(chr(int(m[i:i+2], 16)), end='')
#UDCTF{F3rma7_c4n_sur3_fac70r!}

RSA School 8th Grade

from sympy import *
from Crypto.Util.number import *
import random
p=getPrime(512)
q = nextprime(p + random.randint(10**9,10**10))
N=p*q
msg=b'UDCTF{REDACTED}'
pt = bytes_to_long(msg)
e = 65537
ct = pow(pt, e, N)
print(N)
print(e)
print(ct)
150459385706485253914441877113384979120500190162060302508541299821944089329499694790524295291567135320851306118878915105907451588623958757693847782920309145753994837129247899050065917279292484317798035721308006529470560777407483024961882645653400385816416526996027114542480513056100444908809723540145733606413
65537
2307423154990120835718508986514267143655326830191633946685219656220840494132925634069678170936781595742873539412034460586639622885239343246714559828497111273868089182257159904851948098861145910137615097694560608874412798124055642460363270612990137075678106724613406247492210136960473648165963598137216228495

看起来本题与7年级非常相似。只是 10^9 和 10^10 之间的一些数字被添加到 p 中。这真的足以阻止我们使用相同的攻击吗? 毕竟,由于我们每次都对 a 进行平方,因此此操作的时间复杂度降低到 10^5 最坏情况。那绝对应该及时运行!

因此,只需复制 7 年级的代码即可获得flag!

exp:

import gmpy2

n=150459385706485253914441877113384979120500190162060302508541299821944089329499694790524295291567135320851306118878915105907451588623958757693847782920309145753994837129247899050065917279292484317798035721308006529470560777407483024961882645653400385816416526996027114542480513056100444908809723540145733606413
e=65537
c=2307423154990120835718508986514267143655326830191633946685219656220840494132925634069678170936781595742873539412034460586639622885239343246714559828497111273868089182257159904851948098861145910137615097694560608874412798124055642460363270612990137075678106724613406247492210136960473648165963598137216228495

a = gmpy2.iroot(n, 2)[0] + 1
b = a*a - n
while not gmpy2.iroot(b, 2)[1]:
    print(b)
    b = a*a - n
    a += 1

p = a - gmpy2.iroot(b, 2)[0]
q = n // p
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
m = pow(c, d, n)
m = format(m, 'x')
for i in range(0, len(m), 2):
    print(chr(int(m[i:i+2], 16)), end='')
#UDCTF{4n_RSA_5ch0ol_gr4dua73!!}

Greatest Hits 2 of 4

from Crypto.Util.number import *
p=getPrime(1024)
q=getPrime(1024)
n=p*q
e1=32
e2=94
msg=bytes_to_long("REDACTED")
assert(pow(msg,2) < n)
c1 = pow(msg, e1, n)
c2 = pow(msg, e2, n)
print(n)
print(e1)
print(e2)
print(c1)
print(c2)

这与前面的题3年级 RSA 非常相似,只是e1 和 e2 的 GCD 不为 1,看这个代码: assert(pow(msg,2) < n),

消息的平方小于 2。那么,如果我们找到 m^2 然后取它的平方根不就行了?

注意,我们可以将 Bezout 的身份稍微修改为以下内容:

2ax + 2by = 2

如果我们将 e1 和 e2 同除以 2,则得到 a = 16 和 b = 47,它们彼此互为互质数。 因此,我们可以做一些数学来证明我们可以得到 m^2

c1 = (m ^ e1) % n, c2 = (m ^ e2) % n
[(c1 ^ x) % n] * [(c2 ^ y) % n] = (m ^ (e1 * x + e2 * y)) % n = (m ^ (2a * x + 2b * y)) % n = (m ^ 2) % n

因此,便得到 m^2!为了从中找到 m,我们可以使用 gmpy2 的 iroot 函数来获得整数平方根。

exp

import gmpy2
from Crypto.Util.number import long_to_bytes
def extended_euclid_gcd(a, b):
    """
    Returns a list `result` of size 3 where:
    Referring to the equation ax + by = gcd(a, b)
        result[0] is gcd(a, b)
        result[1] is x
        result[2] is y
    """
    s = 0; old_s = 1
    t = 1; old_t = 0
    r = b; old_r = a

    while r != 0:
        quotient = old_r//r # In Python, // operator performs integer or floored division
        old_r, r = r, old_r - quotient*r
        old_s, s = s, old_s - quotient*s
        old_t, t = t, old_t - quotient*t
    return [old_r, old_s, old_t]

n = 15144989296069059933372368453196092175005161975349151110345314566785160131088640293080496647831336241835434081246752372095089223274410617149601529995353586979709767320781773241635911841825135157128620635284850556358212336804356913383250552153118005157608892746468253056994929497147176358510660250974046147584489593314250043332900225627695013699452589204281775937461626931870469970564649337891804670484615877731064389199146553155645996166903057997780769847954473558252319887360004797752922471164238094762917170732419058459198871816368754874928563582062094607146743861963241102686280889624636580265012154494857871226911
e1=32
e2=94
c1=517413713703886999866857886363089094585257050613499021392236739949207714015445698823055234855661713319078211477553629447153099784179447532323740595057178898139959674381355432131055787089201673781698752057672521217038516832753572594045829378268006522196608125682968252235804171902500675561571516482830716057356093346644739755000641419389456649384154636696468100735075639775740773984117668523785494430624107703773927953688140653884319491595701619752757483259322185639861570200460175036940484201361523531829151771132059047908439112074722779866239565825707838090161372153338024174748440497243107864663782108641727771659
c2=7627448403143228380990811828784190441589966806784538493012623116575366382931836531487460665746937844089811800210162413422176546183916362252942569359187329261606901744873414894672206518833504277712248120517227097337821671357183002903689123275299969496743046843235865472598002895668376113637844709030956945481612135136663699655327584977008477587437014970931004029432308882904616641276931607404737262279319635052041442201857436898171408177118684300765925831306704477989772422231625570934627171304088385754161129883791893955034648200851254688716049371226939666530556140959866437156338956068301001303202802889970914365861

# ax + by = 1
gcd, x, y = extended_euclid_gcd(e1//2, e2//2)
m = (pow(c1, x, n) * pow(c2, y, n)) % n
m = gmpy2.iroot(m, 2)[0]
print(long_to_bytes(m))

Appetizers

knapsack.py

#Subset Sum Problem
#https://imgs.xkcd.com/comics/np_complete.png
import random
choices = list(set([random.randint(100000,1000000000) for _ in range(30)]))
random.shuffle(choices)
winners = choices[:15]
target = sum(winners)
winners.sort()
flag = "UDCTF{%s}" % ("_".join(map(str,winners)))
#print(flag)
choices.sort()
print(choices)
print(target)

output.txt

[19728964, 30673077, 137289540, 195938621, 207242611, 237735979, 298141799, 302597011, 387047012, 405520686, 424852916, 461998372, 463977415, 528505766, 557896298, 603269308, 613528675, 621228168, 654758801, 670668388, 741571487, 753993381, 763314787, 770263388, 806543382, 864409584, 875042623, 875651556, 918697500, 946831967]
7627676296

提供的代码生成一个包含 30 个随机整数的列表,对它们进行洗牌,选择其中 15 个作为获胜者,并计算它们的总和,然后打印所有整数和目标总和的排序列表。在这种情况下,目标总和为 7627676296。

代码顶部的注释提到了子集总问题,这是计算机科学和数学中的经典问题。问题可以表述如下:给定一组正整数和一个目标整数,给定集合中是否有一个子集加起来就是目标整数?

在本例中,正整数集是 30 个随机生成的整数的列表,目标整数为 7627676296。挑战在于找到 30 个整数中的一个子集,这些子集加起来就是目标整数。

有多种算法可以解决子集求和问题,包括动态规划和回溯。解决此特定问题的一种方法是使用回溯算法,该算法尝试不同的整数组合,以查看其中是否有任何一个与目标相加。

在这个问题中,我们得到了一组整数(选择列表)和一个目标总和(目标变量)。目标是在选项列表中查找总和相等的整数子集。

exp

def subset_sum(numbers, target, partial=[]):
    s = sum(partial)

    # If the sum of the current subset equals the target, print the flag
    if s == target:
        flag = "UDCTF{%s}" % ("_".join(map(str, partial)))
        print("Flag:", flag)
    
    # If the sum of the current subset exceeds the target, stop exploring this path
    if s >= target:
        return
    
    # Recursively try including and excluding elements from the subset
    for i in range(len(numbers)):
        remaining = numbers[i+1:]
        subset_sum(remaining, target, partial + [numbers[i]])

# List of numbers and target sum
choices = [19728964, 30673077, 137289540, 195938621, 207242611, 237735979, 298141799, 302597011, 387047012, 405520686, 424852916, 461998372, 463977415, 528505766, 557896298, 603269308, 613528675, 621228168, 654758801, 670668388, 741571487, 753993381, 763314787, 770263388, 806543382, 864409584, 875042623, 875651556, 918697500, 946831967]
target = 7627676296

# Call the subset_sum function to find and print the flag
subset_sum(choices, target)
Flag: UDCTF{19728964_30673077_137289540_195938621_237735979_302597011_463977415_603269308_654758801_670668388_763314787_806543382_875651556_918697500_946831967}

MISC

Hide n Seek

音频打开一眼摩斯

解码得到密码:

GIVEMETHEFLAGLOL

然后使用steghide解码,但输入密码并不能解出来,思路应该没错误啊?仔细分析提示:LET HIM COOOOK!! read everything you can carefully

“仔细阅读所有内容”,wav 文件称为 LOLisCapatlized.wav,因此它暗示我们解码的莫斯实际上应该是 givemetheflagLOL,LOL 大写。将其用作图像STEG_O_SAURS.jpeg上带有steghide的密码这样才对。

steghide extract -sf 2222.jpeg
Enter passphrase:
wrote extracted data to "flaglol.txt".

打开得到

UDCTF{01111001 01000000 01010101 01011111 01100011 01000001 01011110 01101110 01011111 01101000 00100001 01100100 00110011 00111111 01011111 01101100 01001111 01101100 01011111 01110011 01010100 00110011 01000111 01101111}

Big JPG

这个图本身就是一个提示哈哈,使用7-zip打开图片发现里面有两个图片

其中key.png如下,圈出 8 个螺丝头中的最后一个螺丝头,发现它也恰好是最小的。难道这意味着最低有效位隐写术?

查看一下0通道还确实有隐写。。

提取一下数据发现密码,秒懂!带密码的steghide隐写

steghide直接解:

steghide extract -sf flag.jpg
Enter passphrase:
wrote extracted data to "flag.txt".

打开文本得到

UDCTF{lay3r5_0n_lay3r5}

Least Significant Color

提示:I can't decide which color is the least significant... red xor green?

看到此图,我们需要想到两件事:最低有效位 (LSB) 和图像的表示。

对于图像

图像基本上是 2 个值的元组(R = 红色、G = 绿色、B = 蓝色)的 3D 列表。 元组定义一个从 0 到 255 的数字,定义每种颜色的强度

图像的宽度定义了每行的元组数。 图像的高度定义了行数。

最低有效位

最低有效位是字节的最后一位。它在stego中用于隐藏文本或其他。 因此,我们可以获取多个字节并编辑每个字节的 LSB,因此如果我们连接每个字节的 LSB,我们就会得到一条消息。

正如描述告诉我们的那样,用绿色元组的红色值进行异形或变,并迭代它 30 个字符 = 30 字节 = 30*8 LSB = 240 像素 = 240 个元组。

使用带有 PIL 模块的 python 脚本进行经过一些研究后发现的图像处理。

from PIL import Image

flag = Image.open('encoded.png')

lsb = []

b = ""

pixels = list(flag.getdata())

for c,p in enumerate(pixels):

    b+=bin(p[1]^p[0])[-1]
    
    if len(b) == 8:
        lsb.append(int(b, 2))
        b=""
    if c == 240:
        break
        
for char in (lsb):
    print(chr(char), end="")
  1. 红色与绿色的异或,并将最低有效位附加到 b
  2. 如果 b 为 8 位,则在“lsb”列表中清空它的值
  3. 对于 lsb[] 中的每个字节,打印其 ascii 值

清洗后输出结果 : .UDCTF{y0u_R_1mag3_wizZarD}

 

posted @ 2023-11-06 08:44  Kicky_Mu  阅读(96)  评论(0编辑  收藏  举报