CCTF

复盘咯

WARM-UP

Mic Check

点进去就有

EASY

Klamkin

求一元一次方程的解,给了一组x、y,直接移位就有了

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
from pwn import *
import gmpy2 as gp

context(log_level = 'debug')
io = remote('04.cr.yp.toc.tf', 13777)
io.recvuntil(b'[Q]uit\n')
io.sendline('G')
q = int(io.recvline().split()[-1])
r = int(io.recvline().split()[-1])
s = int(io.recvline().split()[-1])
print(q,r,s)
io.recvuntil(b'[Q]uit\n')
io.sendline('S')
while True:
io.recvuntil(b'that ')
u = io.recvuntil(b' ')[:-1]
io.recvuntil(b'is ')
num = int(io.recvuntil(b'-')[:-1])
io.recvline()
if u == b'x':
inv = (gp.invert(r, q) * s) % q
io.sendline(str(1<<(num - 1)) + ', ' + str((inv * (1<<(num - 1)) % q)))
elif u == b'y':
inv = (gp.invert(s, q) * r) % q
io.sendline(str((inv * (1<<(num - 1)) % q)) + ', ' + str(1<<(num - 1)))
io.recvline()
#CCTF{f1nDin9_In7Eg3R_50Lut1Ons_iZ_in73rEStIn9!}

Baphomet

’CCTF‘爆破key,截前面一部分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
from base64 import b64encode, b64decode
from Crypto.Util.number import bytes_to_long

f = open('flag.enc', 'rb')
c = f.read()
msg = 'CCTF{'
ba = b64encode(msg.encode('utf-8'))

baph = ''
for b in ba.decode('utf-8'):
if b.islower():
baph += b.upper()
else:
baph += b.lower()
baph = baph.encode('utf-8')
print(baph)
key = b''
for i in range(len(baph)):
key += (baph[i] ^ c[i]).to_bytes(1, 'big')
key = key[:6]

flag = b''
for i in range(len(c)):
flag += (c[i] ^ key[i % len(key)]).to_bytes(1, 'big')
msg = ''
for f in flag.decode('utf-8'):
if f.islower():
msg += f.upper()
else:
msg += f.lower()
msg = msg.encode('utf-8')
print(b64decode(msg))
#b'CCTF{UpP3r_0R_lOwER_17Z_tH3_Pr0bL3M}'

MEDIUM-EASY

sots

He who abides far away from his home, is ever longing for the day he shall return.

\[x^2+y^2=n, n已知\]

丢番图方程,可以用在线网站解,也可以调库two_square()

梭了

CCTF{3Xpr3sS_4z_Th3_sUm_oF_7w0_Squ4rE5!}

polyRSA

直接roots

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import *
import gmpy2

e = 31337
n = 44538727182858207226040251762322467288176239968967952269350336889655421753182750730773886813281253762528207970314694060562016861614492626112150259048393048617529867598499261392152098087985858905944606287003243
c = 37578889436345667053409195986387874079577521081198523844555524501835825138236698001996990844798291201187483119265306641889824719989940722147655181198458261772053545832559971159703922610578530282146835945192532

P = PolynomialRing(ZZ, 'k')
k = P.gen()
p = k**6 + 7*k**4 - 40*k**3 + 12*k**2 - 114*k + 31377
q = k**5 - 8*k**4 + 19*k**3 - 313*k**2 - 14*k + 14011
f = p*q -n
x = f.roots()[0][0]
#k = 9291098683758154336
p = p(x)
q = q(x)
phi = (p-1) * (q-1)
d = gmpy2.invert(e,phi)
print(long_to_bytes(pow(c,d,n)))

infinity castle

diamond是平方,triage是立方,summarize是对\[\sqrt{n}\]进行积分,find是计算泰勒级数 \[ summarize返回的值\approx \frac{\sqrt{2}}{2} +\sqrt{3}+\sqrt{4}+···+\frac{\sqrt{n}}{2}\\ 所以是\sqrt{n}从2到n的积分 \]

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
35
36
37
38
from gmpy2  import iroot
from Crypto.Util.number import *

def xor(cip, key):
repeation = 1 + (len(cip) // len(key))
key = key * repeation
key = key[:len(cip)]

msg = bytes([c ^^ k for c, k in zip(cip, key)])
return msg

def diamond(num): #平方
return num ** 2

def triage(num):#立方
return num ** 3

def summarize(b):
return 2/3 * b**(3/2) - 2/3 * 2**(3/2)

c0 = 194487778980461745865921475300460852453586088781074246328543689440168930873549359227127363759885970436167330043371627413542337857082400024590112412164095470165662281502211335756288082198009158469871465280749846525326701136380764079685636158337203211609233704905784093776008350120607841177268965738426317288541638374141671346404729428158104872411498098187946543666987926130124245185069569476433120128275581891425551325847219504501925282012199947834686225770246801353666030075146469275695499044424390475398423700504158154044180028733800154044746648133536737830623670383925046006108348861714435567006327619892239876863209887013290251890513192375749866675256952802329688897844132157098061758362137357387787072005860610663777569670198971946904157425377235056152628515775755249828721767845990597859165193162537676147173896835503209596955703313430433124688537275895468076469102220355973904702901083642275544954262724054693167603475188412046722656788470695566949847884250306735314144182029335732280420629131990311054229665691517003924788583771265625694414774865289407885678238795596912006567817508035434074250123869676396153982762032750080222602796273083162627489526255501643913672882350236497429678928099868244687228703074267962827621792960
c1 = 102325064080381160170299055162846304227217463467232681115953623386548494169967745781550171804781503102663445039561476870208178139548389771866145006535051362059443515034504958703659546162037904784821960707630188600064568878674788077706711506213779443920430038560373854184526850365974450688458342413544179732143225845085164110594063440979455274250021370090572731855665413325275414458572412561502408983107820534723804225765540316307539962199024757378469001612921489902325166003841336027940632451584642359132723894801946906069322200784708303615779699081247051006259449466759863245508473429631466831174013498995506423210088549372249221415401309493511477847517923201080509933268996867995533386571564898914042844521373220497356837599443280354679778455765441375957556266205953496871475611269965949025704864246188576674107448587696941054123618319505271195780178776338475090463487960063464172195337956577785477587755181298859587398321270677790915227557908728226236404532915215698698185501562405374498053670694387354757252731874312411228777004316623425843477845333936913444143768519959591070492639650368662529749434618783626718975406802741753688956961837855306815380844030665696781685152837849982159679122660714556706669865596780528277684800454866433826417980212164051043504955615794706595412705883261111953152250227679858538249797999044336210905975316421254442221408945203647754303635775048438188044803368249944201671941949138202928389951227347433255867504906597772044398973241425387514239164853656233776024571606159378910745571588836981735827902305330330946219857271646498602227088657739442867033212012876837654750348578740516798444734534291467314881324902354425889448102902750077077381896216130734894767553834949561471219923459897244690006643798812989271282475503126962274052192342840870308710338336817452628324667507548265612892611100350882163205858101959976
enc = 122235247669762131006183252122503937958296387791525458429403709404875223067116491817728568224832483391622109986550732469556761300197133827976956875865159629512476600711420561872409721582387803219651736262581445978042694384374119142613277808898398213602093802571586386354257378956087240174787723503606671543195193114158641301908622673736098768829071270132073818245595918660134745516367731595853832524328488074054536278197115937409643221809577554866060292157239061557708159310445977052686561229611117673473208278176118561352693319461471419694590218295911647368543698198762827636021268989705079848502749837879584394379300566277359149621932579222865430374652678738198451655509408564586496375811666876030847654260305392984710580761255795785508407844683687773983669843744274915862335181251050775093896006210092665809300090715190088851654138383362259256212093670748527819287681468901379286722214112321906917311154811516336259463356911326393701445497605365038857575515541024824906818473933597129846235905072394148879079996812146836910199111439031562946495046766063326815863624262541346543552652673629442370320109404700346028639853707278295255350982238521659924641921142615894039995513480511108116053798143154593343124822462519555715118822045
e = 0x10001
pandq = iroot(c1,3)[0]
assert c0 % pandq == 0
p_q = c0 // pandq
p = (pandq + p_q) // 2
q = pandq - p
assert c1 == (p + q) ** 3
n = int(p * q)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
xor_key = long_to_bytes(int(summarize(n)))
enc = long_to_bytes(pow(enc, d, n))
flag = xor(enc, xor_key)
print(flag)
#CCTF{Mix1ng_c4lcUluS_w17h_Numb3r_The0Rry_S33ms_s7r0ng_cRyp70_Sch3m4!!}

keydream

给两头的copper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import long_to_bytes, bytes_to_long

n = 23087202318856030774680571525957068827041569782431397956837104908189620961469336659300387982516148407611623358654041246574100274275974799587138270853364165853708786079644741407579091918180874935364024818882648063256767259283714592098555858095373381673229188828791636142379379969143042636324982275996627729079
c = 3621516728616736303019716820373078604485184090642291670706733720518953475684497936351864366709813094154736213978864841551795776449242009307288704109630747654430068522939150168228783644831299534766861590666590062361030323441362406214182358585821009335369275098938212859113101297279381840308568293108965668609
e = 65537

p_high = bytes_to_long(b'CCTF{it_is_fake_flag_')
p_low = bytes_to_long(b'_90OD_luCk___!!}')
PR.<x> = PolynomialRing(Zmod(n))
f = p_high * 2^(43*8) + x * 2^(16*8) + p_low
roots = f.monic().small_roots(X = 2^(27*8), beta = 0.4)
p = int(f(roots[0]))
assert n%p == 0
q = n//p
d = inverse_mod(e, (p - 1) * (q - 1))
m = pow(c, d, n)
print(long_to_bytes(m))
#b'Congratz, the flag is: CCTF{h0M3_m4dE_k3Y_Dr1vEn_CrYp7O_5ySTeM!}'

jeksign

\[ 1337(z^4 - x^2) = 31337(y^2 - z^4)\\ a(z^4 - x^2) = b(y^2 - z^4)\\ \therefore (a+b)z^4 = ax^2+by^2\\ 令x=y=z^2,得到恒等式 \]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *
from random import randint

context(log_level = 'debug')
nc = remote('02.cr.yp.toc.tf', 17113)
x = 30
nc.recvuntil(b'-bit: \n')
for i in range(60):
z = randint(2 ** (x-1), 2 ** x)
print(z)
nc.sendline(str(z**2)+','+str(z**2) + ',' + str(z))
x += 1
nc.recvline()
#CCTF{4_diOpH4nT1nE_3Qua7i0n__8Y__Jekuthiel_Ginsbur!!}

volgo

明文密文一一对应,直接爆破

下面的exp是苏氨酸师傅的:

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
import requests
from string import ascii_uppercase

ct = 'NUYXA FATCL LJSVD KOLWM NWZUG JZDPY JGOSL CBRGO BAMKL BXDZR BLXDU KUNQE CWEUO SPOZR VOJMM POXCR RPNXX SGVHW TGOWJ BDOGF AHVWF WPZGR UQKUE HASEF GKFFA QOPNQ TESLZ FACTJ JPSPL DNZYN CXSFZ'.replace(' ', '')
print(ct)


def rua(c, i):
pre = "A" * i

for ch in ascii_uppercase:
cipher = requests.post("http://03.cr.yp.toc.tf:11117/m209/encipher",
data={
"plain": pre + ch
}).json()["cipher"]

cipher = cipher.replace(" ", "")[10:-10] # remove head and tail
print(cipher)
if cipher[i] == c:
print('flag[i] is', ch)
return ch


flag = ""

for i, c in enumerate(ct):
flag += rua(c, i)
print(flag)

这个是发现了规律的

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
import requests
import json

def get_ciphertext(s):
url = "http://03.cr.yp.toc.tf:11117/m209/encipher"
data = { "plain": s }
res = requests.post(url, data)
return json.loads(res.text)["cipher"]

st = "IISNJ IFFAA TYPMO WDJHA ZMNBD LKUAY TYPVD UGAYU OQMOO YRVUS SLFZI IXKVW LYUGT JWTYV XNEYU HLQVV IXUMJ BKNUQ WMLQT QKIWV UXOCA CVSPG UKJQG XCSFI RJEKU BWLBM AVRFW DMOPT VFXTD VROND XSEHF ZLWEJ VOVSX IISNJ IFFAA"

en = "A" * 155
en = get_ciphertext(en)

print(len(st))
print(len(en))
res = b""
for i in range(len(st)):
if st[i] == en[i] and st[i] == " ":
continue
cc = bytes([(ord(en[i]) - ord(st[i])) % 26 + ord('A')])
if b"Z" == cc:
res += b" "
else:
res += cc
print(res)

CCTF{OOJMPMDDIXCLNNWFTEJUMFXKBRVVMOPSLSSLUTXVDVNDMYYPHPWFJRNJBVBOMUYR}

MEDIUM

Aniely

key = passphrase^flag

enc = passphrase ^ E(key)^rand

rand = urandom(2) * 16

flag开头两字节为'CC'

因此rand可求

Diploma

Oak land

Cantilever

Side step

Faonsa

Resign

DBB

Fiercest

Mino

Starter ECC

MEDIUM-HARD

Watery soup

313 Loyal

Soda

Sparse

Larisa

Shaim

Lagima

Versace

HARD

Persian cat

NLCS

GSDP