Misc

1.灵感菇🍄哩菇哩菇哩哇擦灵感菇灵感菇🍄

获取之后看网页源代码,

然后看github里面的源码看到编码原则:

然后先自己用word处理一遍:(不用ai的原因是因为ai处理很多数据的时候容易吞掉之类的)

然后再让ai三进制解码,然后对应ascii码:

(其实你看这里最后拼接也把ctf换成了cft。。。)

NSSCFT{77d3c459-9c09-4fb5-b098-fa2f395c1a0a}()

2.像素中的航班

这个找了一个小时找不到然后借助小红书的网友找到了航班信息:

我想说的就是网友真牛逼,最后获得flag:LitCTF{CZ8289}

Crypto

1.basic

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

n = 150624321883406825203208223877379141248303098639178939246561016555984711088281599451642401036059677788491845392145185508483430243280649179231349888108649766320961095732400297052274003269230704890949682836396267905946735114062399402918261536249386889450952744142006299684134049634061774475077472062182860181893
e = 65537
c = 22100249806368901850308057097325161014161983862106732664802709096245890583327581696071722502983688651296445646479399181285406901089342035005663657920475988887735917901540796773387868189853248394801754486142362158369380296905537947192318600838652772655597241004568815762683630267295160272813021037399506007505

# 计算私钥d
phi = n - 1 # 因为n是素数,所以欧拉函数φ(n)=n-1
d = inverse(e, phi)

# 解密
m = pow(c, d, n)

# 将解密后的数字转换为字节
flag = long_to_bytes(m)

print(flag.decode())

解题代码:

1
2
3
4
5
6
7
8
9
10
from Crypto.Util.number import *
from gmpy2 import *

c = 22100249806368901850308057097325161014161983862106732664802709096245890583327581696071722502983688651296445646479399181285406901089342035005663657920475988887735917901540796773387868189853248394801754486142362158369380296905537947192318600838652772655597241004568815762683630267295160272813021037399506007505
e=65537
n = 150624321883406825203208223877379141248303098639178939246561016555984711088281599451642401036059677788491845392145185508483430243280649179231349888108649766320961095732400297052274003269230704890949682836396267905946735114062399402918261536249386889450952744142006299684134049634061774475077472062182860181893
d= pow(e,-1,n-1)
m= pow(c,d,n)
flag=long_to_bytes(m)
print(flag)

结果:b'LitCTF{ee2c30dfe684f13a6e6c07b9ec90cc2c}'

2.ez_math

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sage.all import *
from Crypto.Util.number import *
from uuid import uuid4

flag = b'LitCTF{'+ str(uuid4()).encode() + b'}'
flag = bytes_to_long(flag)
len_flag = flag.bit_length()
e = 65537
p = getPrime(512)
P = GF(p)
A = [[flag, getPrime(len_flag)],
[getPrime(len_flag), getPrime(len_flag)]]
A = matrix(P, A)
B = A ** e

print(f"e = {e}")
print(f"p = {p}")
print(f"B = {list(B)}".replace('(', '[').replace(')', ']'))

# e = 65537
# p = 8147594556101158967571180945694180896742294483544853070485096002084187305007965554901340220135102394516080775084644243545680089670612459698730714507241869
# B = [[2155477851953408309667286450183162647077775173298899672730310990871751073331268840697064969968224381692698267285466913831393859280698670494293432275120170, 4113196339199671283644050914377933292797783829068402678379946926727565560805246629977929420627263995348168282358929186302526949449679561299204123214741547], [3652128051559825585352835887172797117251184204957364197630337114276860638429451378581133662832585442502338145987792778148110514594776496633267082169998598, 2475627430652911131017666156879485088601207383028954405788583206976605890994185119936790889665919339591067412273564551745588770370229650653217822472440992]]

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
from sage.all import *
from Crypto.Util.number import *

# 已知参数
e = 65537
p = 8147594556101158967571180945694180896742294483544853070485096002084187305007965554901340220135102394516080775084644243545680089670612459698730714507241869
B_list = [
[2155477851953408309667286450183162647077775173298899672730310990871751073331268840697064969968224381692698267285466913831393859280698670494293432275120170,
4113196339199671283644050914377933292797783829068402678379946926727565560805246629977929420627263995348168282358929186302526949449679561299204123214741547],
[3652128051559825585352835887172797117251184204957364197630337114276860638429451378581133662832585442502338145987792778148110514594776496633267082169998598,
2475627430652911131017666156879485088601207383028954405788583206976605890994185119936790889665919339591067412273564551745588770370229650653217822472440992]
]

# 构造有限域
F = GF(p)
B = Matrix(F, B_list)

# 在有限域中,2x2 矩阵群的阶是 GL(2, p) 的阶
# 阶 = (p^2 - 1)(p^2 - p)
order = (p**2 - 1) * (p**2 - p)

# 求 e 的逆元(模群阶)
d = inverse_mod(e, order)

# 计算矩阵 B 的 d 次幂,得到 A
A = B^d

# 提取 flag
flag_candidate = int(A[0, 0])
try:
flag = long_to_bytes(flag_candidate)
print("Recovered flag:", flag.decode())
except:
print("Raw bytes:", flag)

结果没记下来不想再跑一遍了(sagemath部分用sagemath单独跑,然后结果再拿过来在普通Python里面跑)

3.math

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

m = bytes_to_long(flag)
e = 65537
p,q = getPrime(1024),getPrime(1024)
n = p*q
noise = getPrime(40)
tmp1 = noise*p+noise*q
tmp2 = noise*noise
hint = p*q+tmp1+tmp2
c = pow(m,e,n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"hint = {hint}")
'''
n = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565066224724927142875488372745811265526082952677738164529563954987228906850399133238995317510054164641775620492640261304545177255239344267408541100183257566363663184114386155791750269054370153318333985294770328952530538998873255288249682710758780563400912097941615526239960620378046855974566511497666396320752739097426013141
e = 65537
c = 1443781085228809103260687286964643829663045712724558803386592638665188285978095387180863161962724216167963654290035919557593637853286347618612161170407578261345832596144085802169614820425769327958192208423842665197938979924635782828703591528369967294598450115818251812197323674041438116930949452107918727347915177319686431081596379288639254670818653338903424232605790442382455868513646425376462921686391652158186913416425784854067607352211587156772930311563002832095834548323381414409747899386887578746299577314595641345032692386684834362470575165392266454078129135668153486829723593489194729482511596288603515252196
hint = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565315879035806034866363781260326863226820493638303543900551786806420978685834963920605455531498816171226961859405498825422799670404315599803610007692517859020686506546933013150302023167306580068646104886750772590407299332549746317286972954245335810093049085813683948329319499796034424103981702702886662008367017860043529164
'''

这里引入了噪声(noise),所以先解出噪声:

$ hint=noise^2+(p+q)noise+p·q=(noise+q)(noise+p)

$

$ hint-n=noise(p+q+noise)
$

这就意味着:

$ noise|(hint-n)
$

根据noise = getPrime(40)来看,noise是一个素数,我这里用网站分解了一下:

很容易看到

$ noise=942430120937(因为这个是符合长度的素数)
$

从而可以算出来

$ p + q = \frac{\mathrm{hint} - n - \mathrm{noise}^2}{\mathrm{noise}} $

用解方程的代码解出p、q:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from math import isqrt

s = 264904851121137920947287086482326881385752688705374889409196246630630770102009950641809599308303022933372963797747735183944234823071639906681654992838707159246410571356707755892308435202955680710788529503317217548344168832053609281562447929541166386062570844327209330092595380642976752220867037216961082705142
n = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565066224724927142875488372745811265526082952677738164529563954987228906850399133238995317510054164641775620492640261304545177255239344267408541100183257566363663184114386155791750269054370153318333985294770328952530538998873255288249682710758780563400912097941615526239960620378046855974566511497666396320752739097426013141

# 判别式
Delta = s*s - 4*n
if Delta < 0:
raise ValueError("判别式为负,无法分解。")

r = isqrt(Delta)
if r*r != Delta:
raise ValueError("判别式不是完全平方数,p/q 不是整数解。")

# 求 p, q(可能顺序互换)
p = (s + r) // 2
q = (s - r) // 2

# 验证
assert p*q == n, "校验失败:p*q != n"
assert p + q == s, "校验失败:p+q != s"

print("p =", p)
print("q =", q)
1
2
p = 135792238734020752402738279887728641662483275687137578306012881706639817605483435282163392435044240115684744622670586400181099625735464730483356502221026546220369148578684544694242743301595862672216732669599901182387427975535652315677229160320057058067529240344722506162893596721678195275652905002409883036941
q = 129112612387117168544548806594598239723269413018237311103183364923990952496526515359646206873258782817688219175077148783763135197336175176198298490617680613026041422778023211198065691901359818038571796833717316365956740856517956965885218769221109327995041603982486823929701783921298556945214132214551199668201

接下来就是正常解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Cryptodome.Util.number import *
from Cryptodome.Util.number import long_to_bytes as l2b
n = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565066224724927142875488372745811265526082952677738164529563954987228906850399133238995317510054164641775620492640261304545177255239344267408541100183257566363663184114386155791750269054370153318333985294770328952530538998873255288249682710758780563400912097941615526239960620378046855974566511497666396320752739097426013141
e = 65537
c = 1443781085228809103260687286964643829663045712724558803386592638665188285978095387180863161962724216167963654290035919557593637853286347618612161170407578261345832596144085802169614820425769327958192208423842665197938979924635782828703591528369967294598450115818251812197323674041438116930949452107918727347915177319686431081596379288639254670818653338903424232605790442382455868513646425376462921686391652158186913416425784854067607352211587156772930311563002832095834548323381414409747899386887578746299577314595641345032692386684834362470575165392266454078129135668153486829723593489194729482511596288603515252196
hint = 17532490684844499573962335739488728447047570856216948961588440767955512955473651897333925229174151614695264324340730480776786566348862857891246670588649327068340567882240999607182345833441113636475093894425780004013793034622954182148283517822177334733794951622433597634369648913113258689335969565315879035806034866363781260326863226820493638303543900551786806420978685834963920605455531498816171226961859405498825422799670404315599803610007692517859020686506546933013150302023167306580068646104886750772590407299332549746317286972954245335810093049085813683948329319499796034424103981702702886662008367017860043529164
f=hint-n
print(getPrime(40))
noise=942430120937
pplusq=(hint-n-noise**2)//noise
print("pplusq=",pplusq)
p = 135792238734020752402738279887728641662483275687137578306012881706639817605483435282163392435044240115684744622670586400181099625735464730483356502221026546220369148578684544694242743301595862672216732669599901182387427975535652315677229160320057058067529240344722506162893596721678195275652905002409883036941
q = 129112612387117168544548806594598239723269413018237311103183364923990952496526515359646206873258782817688219175077148783763135197336175176198298490617680613026041422778023211198065691901359818038571796833717316365956740856517956965885218769221109327995041603982486823929701783921298556945214132214551199668201
phi=(p-1)*(q-1)
d=pow(e,-1,phi)
m=pow(c,d,n)
print(l2b(m))

结果:b'LitCTF{db6f52b9265971910b306754b9df8b76}'

明天我再看看有没有更优的解法(用网站查素数分解总有点作弊的感觉。。)