Crypto

我和小蓝鲨的秘密

简单阅读代码后发现是将原图片每个像素点的r,g,b值进行加密,加密过程中n的值较小,直接分解即可,简单的rsa解密过程,之后将原始图片的r,g,b还原即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import *
from PIL import Image
import numpy as np
n = 29869349657224745144762606999
p=160216064374859
q=186431677583461
e =65537
phi = (p-1)*(q-1)
d = inverse(e,phi)
def decry(c):
m = pow(c,d,n)
return m
data = np.load(r"encrypted_image.npy",allow_pickle=True)
h = 2065
w = 712
image = Image.new("RGB", (w,h))
for i in range(w):
for j in range(h):
r = decry(data[i, j, 0])
g = decry(data[i, j, 1])
b = decry(data[i, j, 2])
image.putpixel((i, j), (r, g, b))
image.save("custom_rgb_image.png")

ChaCha20-Poly1305

这道题比较简单,只需要知道crypto库的使用以及能看出key?.txt文件中是base92加密的结果即可

1
2
3
4
5
6
7
8
9
10
from Crypto.Cipher import ChaCha20_Poly1305

key = bytes.fromhex("173974535637a5ef30a116b03d00bd2fe751951ca3eaa62daec2b8f5ca5b6135")
Encrypted_Flag = bytes.fromhex("20408b9fc498063ad53a4abb53633a6a15df0ddaf173012d620fa33001794dbb8c038920273464e13170e26d08923aeb")
Tag=bytes.fromhex("70ffcc508bf4519e7616f602123c307b")
Nonce=bytes.fromhex("d8ebeedec812a6d71240cc50")

cipher = ChaCha20_Poly1305.new(key=key, nonce=Nonce)
flag = cipher.decrypt_and_verify(Encrypted_Flag, Tag)
print(flag)

蓝鲨的费马

参考风二西大佬的视频https://www.bilibili.com/video/BV1po4y1E7az/?spm_id_from=333.999.0.0

首先进行推导

leak=(d+(pow(p,q,n)+pow(q,p,n)))leak = (d+(pow(p,q,n)+pow(q,p,n)))

由于p,q均小于n,将

qp1modqpq1modpq^p \equiv 1 \mod q \\ p^q \equiv 1 \mod p

得到

leak=(d+p+q)modnleak = (d + p +q) \mod n

因为

cdm(modn)d=leak(p+q)c^d \equiv m (\mod n)\\ d = leak - (p+q)

所以推得

cl(p+q)m(modn)c^{l-(p+q)} \equiv m (\mod n)

phi=(p1)(q1)phi = (p-1)*(q-1)

推得

phi=n+1(p+q)phi = n+1-(p+q)

根据欧拉定理:

aϕ(m)1(mod)a^{\phi(m)} \equiv 1 (\mod)

所以

cphi1(modn)cn+1(p+q)1(modn)cn+1c(p+q)1(modn)c(n+1)c(p+q)cp+qc(p+q)(modn)c^{phi} \equiv 1(\mod n)\\ c^{n+1-(p+q)} \equiv 1 (\mod n)\\ c^{n+1}*c^{-(p+q)} \equiv 1(\mod n)\\ c^{(n+1)}*c^{-(p+q)}*c^{p+q} \equiv c^{(p+q)}(\mod n)

所以

cn+1cp+qmodncleakc(n+1)mmodncleakc(p+q)mmodncleak(p+q)mmodnc^{n+1} \equiv c^{p+q} \mod n\\ c^{leak}*c^{-(n+1)}\equiv m \mod n\\ c^{leak}*c^{-(p+q)} \equiv m \mod n\\ c^{leak-(p+q)} \equiv m \mod n

搓脚本

1
2
3
4
5
6
7
c= 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n= 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak= 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881
from Crypto.Util.number import *

m = pow(c,leak-n-1,n)
print(long_to_bytes(m))

小蓝鲨的数学题

参考 2020网鼎杯 you raise me up

根据题目条件和提示,我们已知

c=pow(m,flag,p)c = pow(m,flag,p)

利用sagemath解题

1
2
3
4
5
6
m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193
c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
p = 2**512
d=discrete_log(c,mod(m,p))
import libnum
print(libnum.n2s(int(d)))

小蓝鲨的密码

下载附件后发现一个压缩包与类似rabbit/AES密文和图片,经过尝试压缩包密码为图片的名字,打开压缩包后是密码本,观察其中的密码后,根据往年经验,密码应该为blueshark或者isctf2024,前者上一步已经用过,所以尝试密码为isctf2024,发现AES成功解密。

小蓝鲨的方程

题目中生成的p1为

p1=p4+ap_1 = p^4 +a

a只有777为,对其开4次方后只有5,位数较小,所以可以在对p1开4次方之后递减得到p,之后根据欧拉函数得到phi,算出s的值,之后通过二项式定理以及数论推导,搓脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436
n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111
p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553
e=65537
from Crypto.Util.number import *
from gmpy2 import *
p_ = iroot(p1,4)[0]
while True:
q_ = n // p_
if p_ * q_ == n:
p = int(p_)
q = int((iroot(q_,4))[0])
break
p_ -= 1
phi = (p-1)*(q**4-q**3)
d = inverse(e,phi)
s = pow(c1,d,n)
print(s)
m1 = (c-1)//(s**3)
print(long_to_bytes(m1))

蓝鲨的RSA

查看hint后发现,是维纳定理

根据连分数定理

acd<12d2\left| a- \frac{c}{d} \right|< \frac{1}{2*d^2}

可得c/d是a的一个连分数近似

推导:

leak=8HP116PP=8HP16PP116PP=H2P116PPleak=\frac{8*H*P-1}{16*P*P}=\frac{8*H*P}{16*P*P}- \frac{1}{16*P*P}=\frac{H}{2*P}-\frac{1}{16*P*P}

给leak*2得到

leak2=HP18PPleak2HP=18PP<12PPleak*2 = \frac{H}{P}-\frac{1}{8*P*P}\\ \left|leak*2-\frac{H}{P} \right|= \frac{1}{8*P*P}<\frac{1}{2*P*P}

计算leak*2的连分数即可得到h,p

下一步是基本的格密码

已知

h=f1g(modp)hfg(modp)g=hfkph = f^{-1}*g (\mod p)\\ h*f \equiv g (\mod p)\\ g = hf-kp

于是构造格

(fk)(1h0p)=(fg)\begin{pmatrix} f&-k \end{pmatrix}* \begin{pmatrix} 1&h\\ 0&p \end{pmatrix} = \begin{pmatrix} f&g \end{pmatrix}

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
c = 587245179027322480379581200283415189810421958968516831191660631552695197401940961725169763339428980298128692606951200581483431566182271569207988054537414289564013883171160614196522169980339024564884190765084419167938640701193928669
hint = 0.2427542737153618793334900104191212626446625872340179613972610728976081994921862517310186626304527115125924716035632505287111236596234811779375148657365336957626454491865164520834975233144235103885081268955448330597818844340656652982593545877449810282619387305007246499089258519062093814083383071737897364213169497762760797899310673216754376885295598952272100016962368762532805864796748393317534908268379601445004775495237901072144236328105526403608646831124542336002540011176406194984370372589752234640498423911217119220030242197564695880261480071310815379681250975672935544404797155655708441222387631967447088319826137200280810029390387418159394276760100487636516708987579464183208860911063948902432948269805493252899815187044807603000344378890835564906163242023600624338694473573763088471321731611077227112205396909637906507673367598721218000123789690455125909411309668615810240938664264212370815385282488986625554704015828254539339719586211726300858711328516487805251366293457402531199532556110786048074755505680210260049
n = 839799159583571337450826982895478997157381520448790705455708438948150905361244823725400304016136863419723271227616684280477524669207590477657886623628732394537008838314015048569652202355464477680540884654473950183135276735347866051
e = 65537
hint = hint *2
from Crypto.Util.number import *
cf = continued_fraction(hint)
for i in range(1000):
k = cf.numerator(i)
x = cf.denominator(i)
if isPrime(x) and x.bit_length()==512:
print(k,x)
h,p = k,x
Ge = Matrix(ZZ,[[1,h],[0,p]])
print(Ge.LLL())
f,g = Ge.LLL()[0]
f,g = abs(f),abs(g)
print(f,g)
q = n //f
phi = (f-1)*(q-1)
d = inverse(e,phi)
print(long_to_bytes(pow(c,d,n)))

ezmath

根据题目给出的代码,是需要计算gamma函数当x取值为5/2时,使用在线计算器计算出的结果不是需要的key,但是应该差别不大,所以我们进行一个爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
key = 3293403881791372
ke1 = 3293403881738537
ke2 = 3293403881791370
s = b"n2SQK64JMsXstCtZurBiz81pMr3ZmgMjhuyL67hssm3shqJGYGfS/mWubINeE5HZ"
import random
from hashlib import md5
import base64
from Crypto.Cipher import AES
import tqdm

def pad(data):
data = data.encode('utf8')
while len(data) % 16 != 0:
data += b'\x00'
return data

def decode(key, enc_data):
mode = AES.MODE_ECB
aes = AES.new(pad(key), mode)
enc_data = base64.decodebytes(enc_data)
decrypted_data = aes.decrypt(enc_data)
return decrypted_data



for key in tqdm.trange(329340360000000,329340399999999):
key1 = key
random.seed(key1)
new_key = md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
en_m = decode(new_key, s)
if b'ISCTF' in en_m:
print(en_m)
print(new_key)
break

最后根据提示发现应该是修改好代码后计算出来的key取前15位