Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5Mobile wallpaper 6
2008 words
10 minutes
PolarCTF网络安全2026夏季个人挑战赛 WriteUp
2026-06-14
统计加载中...

Crypto#

签到#

1.txt

你在一个程序员的电脑里发现了一个名为 ’flag.txt‘ 的文件,里面只有一串神秘数字:
密文:
102 108 97 103 123 112 111 108 97 114 99 116 102 125
提示
计算机的世界里,只有 0 和 1。

转 ascii 码就行。

exp.py

c = "102 108 97 103 123 112 111 108 97 114 99 116 102 125"
for i in c.split():
print(chr(int(i)), end="")
# flag{polarctf}

一封情书#

题目描述.txt

实验室的小王终于鼓起勇气要向小李表白了。为了证明情书真的是自己写的,他决定使用ECDSA数字签名。
他精心选择了一条椭圆曲线(secp256k1,就是比特币用的那条),生成了自己的私钥,然后写了两条消息:
"I love you, Li!"
"Will you be my girlfriend?"
为了确保安全,他对每条消息都进行了签名。
但是,小王犯了一个致命的密码学错误——他在两次签名中使用了相同的随机数k!
你作为旁观者,截获了他的消息和签名。你能帮他找回私钥吗?
提示:私钥就是flag,格式为flag{私钥的十六进制}。

已知条件.txt

已知数据如下:
# 椭圆曲线参数 secp256k1
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
# 两封情书的内容
msg1 = "I love you, Li!"
msg2 = "Will you be my girlfriend?"
# 两封情书的签名 (r, s)
# 注意:r1 == r2,表明使用了相同的随机数k
r1 = 0x2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c
s1 = 0x4c2e1a3b5d7f9e8c6a4b2d1e3f5a7c9b8e6d4f2a1c3e5b7d9f0a2c4e6f8a0b2c
r2 = 0x2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c
s2 = 0x9a8c6e4d2b0f1e3c5a7b9d8e6f4a2c0d1e3f5a7b9c8d6e4f2a0b1c3d5e7f9a8b
print("请根据以上信息恢复私钥d,flag格式为 flag{hex(d)}")

感觉最近见到好多次了,ECDSA 随机数复用问题,可以之前博客找找,这里不赘述了。

exp.py

from hashlib import sha256
from gmpy2 import invert
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
msg1 = b"I love you, Li!"
msg2 = b"Will you be my girlfriend?"
r1 = 0x2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c
s1 = 0x4c2e1a3b5d7f9e8c6a4b2d1e3f5a7c9b8e6d4f2a1c3e5b7d9f0a2c4e6f8a0b2c
r2 = 0x2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c6e8f0a2b4c6d8e0f2a4c
s2 = 0x9a8c6e4d2b0f1e3c5a7b9d8e6f4a2c0d1e3f5a7b9c8d6e4f2a0b1c3d5e7f9a8b
z1 = int.from_bytes(sha256(msg1).digest(), "big")
z2 = int.from_bytes(sha256(msg2).digest(), "big")
k = ((z1 - z2) * invert(s1 - s2, n)) % n
d = ((s1 * k - z1) * invert(r1, n)) % n
print(f"flag{{{hex(d)[2:]}}}")
# flag{734fc83fb33713821e4c3bc3b7c2968d585ec299976e4a19bb94feaa072e0a52}

XOR流密码密钥重用#

题目.txt

某加密系统使用自定义的流密码方案:
1. 用户提供密钥key
2. 系统将key重复扩展至与明文等长
3. 逐字节XOR加密
管理员用同一密钥加密了两个文件:
- 一个英文文章(已知内容,但不知道确切用词)
- 一个包含flag的简短消息(未知)
你能利用密钥重用漏洞恢复flag吗?

output.txt

XOR Stream Cipher Challenge
============================================================
已知明文大致内容:一篇关于 'quick brown fox' 的英文段落
已知明文精确长度:380 字节
密文1 (hex):04c4257bf7daca53b15470dc4041d4e636c3387becdace40a9547dd84a449ab238c96037e7d5da10be1b75800f62d2af238c303ae8c8d151b75471c14142dbaf3edf603ef0cad149fa1877da5b53c8e63fca602feeca8375b4137ec75c5e9aa73cdc283ae4cad710bb0032c24a57c9b270c32e38e3818379ae547bdd0f55d5ab3dc32e37ff8fd643bf1032c840449ab235df3432e8c88344a30477d95d5fcea322df603ae8cb8353b51962db5b53c8e63bc93939e9ced154a95832cf41529aa03fde603fefdcd35cbb0d7bc04816dfbe31c13037e3dc835fbc5474c14142c9e870f8283ea6cac242b61d77dd5b16d1a83fdb2e7be7dfd355bb0673c04c539aa9368c3433efdc8340b20673dd4a16d3b570ca3234eb8fd758bf547ecf5b539aa839c2252fe3cacd44b25471cb4142cfb429826016e7c1da10aa117dde43539aae31da257bf3dcc654fa007ac75c16c9a33ed82535e5ca8344b55462dc4e55ceaf33c9602feecaca42fa1c73c04b41c8af24c52e3ca6dcc859b6186180
Flag密文长度:44 字节
密文2 (hex):36c0213cfdd79342850621db5c53e5ab64c72528d9dcd742e9157ff14c07caae63de1f6ae8dcc653af0677d3
提示:同一密钥被用于加密两段明文

根据output.txt得到段落的异或密文和flag的异或密文,通过flag的固定前缀格式flag{异或出key的前缀,再用key的前缀去异或段落发现The q,根据output.txt里的提示quick brown fox猜测段落开头为The quick brown fox,异或得到一段密钥,其中发现有重复,恢复密钥,然后异或解出flag

exp.py

from Crypto.Util.strxor import strxor
c_flag = bytes.fromhex("36c0213cfdd79342850621db5c53e5ab64c72528d9dcd742e9157ff14c07caae63de1f6ae8dcc653af0677d3")
c_letter = bytes.fromhex("04c4257bf7daca53b15470dc4041d4e636c3387becdace40a9547dd84a449ab238c96037e7d5da10be1b75800f62d2af238c303ae8c8d151b75471c14142dbaf3edf603ef0cad149fa1877da5b53c8e63fca602feeca8375b4137ec75c5e9aa73cdc283ae4cad710bb0032c24a57c9b270c32e38e3818379ae547bdd0f55d5ab3dc32e37ff8fd643bf1032c840449ab235df3432e8c88344a30477d95d5fcea322df603ae8cb8353b51962db5b53c8e63bc93939e9ced154a95832cf41529aa03fde603fefdcd35cbb0d7bc04816dfbe31c13037e3dc835fbc5474c14142c9e870f8283ea6cac242b61d77dd5b16d1a83fdb2e7be7dfd355bb0673c04c539aa9368c3433efdc8340b20673dd4a16d3b570ca3234eb8fd758bf547ecf5b539aa839c2252fe3cacd44b25471cb4142cfb429826016e7c1da10aa117dde43539aae31da257bf3dcc654fa007ac75c16c9a33ed82535e5ca8344b55462dc4e55ceaf33c9602feecaca42fa1c73c04b41c8af24c52e3ca6dcc859b6186180")
flag_prefix = b"flag{"
key_prefix = "".join(hex(i)[2:] for i in strxor(c_flag[:5], flag_prefix))
print(strxor(bytes.fromhex(key_prefix), c_letter[:5]).decode())
# The q
# output.txt: quick brown fox
letter_prefix = b"The quick brown fox "
key_ = "".join(hex(i)[2:] for i in strxor(letter_prefix, c_letter[:len(letter_prefix)]))
print(key_)
# 50ac405b86afa330da7412ae2f36bac650ac405b
key = bytes.fromhex("50ac405b86afa330da7412ae2f36bac6")
flag = ""
for i in range(len(c_flag)):
flag += chr(c_flag[i] ^ key[i % len(key)])
print(flag)
# flag{x0r_r3use_m4kes_str3am_c1ph3r_1nsecure}

RSA攻击#

challenge.txt

"""
某公司给两名员工分配了RSA密钥对,
管理员偷懒使用了相同的模数n,只分配了不同的e。
现在截获了两份密文,已知它们加密了相同的明文(即flag)。
请从 output.txt 中恢复flag。
提示:
- 两份密文加密的是同一消息
- gcd(e1, e2) = 1
"""
# output.txt 中包含:
# n, e1, e2, c1, c2
# 你的任务:解密得到flag

output.txt

模数 n = 13812575233672721831586447583537566876653330486388935409787324333890787459392340450466602667504564680439365520897560873428017286096972445000317824251067352767983648512628776119679123400768824503694790917456261015793839979622036029611045745581363369351857864086686963496317673425630514828633413586909763949795187270764002509197362846908721600263590407640239331435797743946639068968182530714992497969629250766233642006666869043197198488505558710080081572718303651084249757629984467851536523131561671672489611342354506102975683280634931335250787164325776630303410430197355308594589794345127372612129749874742848505962957
指数 e1 = 65537
指数 e2 = 17
密文 c1 = 6070418361005764781666022160782201020887766530217726892023574250703991153557153150240365562631823866925399109653692772429273414466157925616984969604480345833056708745589264326707421262501098443511684348192232914773363078866001499635599832817468918612502325969087574855976873314002597693535529314223131401211725375960723298442955172141723469659923837266222074788068850377594521429498262678342651354197024627444164288711810799491130391148471163552225195175015155522706829274469375372001014646432745594081482121724200720169564704735134585990761451469788279800252372582853001296020279841151437121368396563208194238176809
密文 c2 = 10333074300444651393936782269258556921403986428158959194325049613051485082847482400799333224207225002899420584885380779122331681690914097226669296406031455480685880093806047826997202684091610029196843015145312932541842991056212933838748027848354582851989374719190041121737024050736144878626494196879779470357938007923163393755461501521926143809013879106438359634585413111911930506853827052788328813877660360961030885521473428344868672139024952576892377942170827101770540081503574982983989347495232393714702165354007286096839200607023742050117961927827236261835001175781713994427455900056065253089202845028635992697862
提示: 两份密文加密的是相同的明文(flag)

共模攻击,gcdext秒了。

exp.py

from Crypto.Util.number import long_to_bytes
from gmpy2 import gcdext
n = 13812575233672721831586447583537566876653330486388935409787324333890787459392340450466602667504564680439365520897560873428017286096972445000317824251067352767983648512628776119679123400768824503694790917456261015793839979622036029611045745581363369351857864086686963496317673425630514828633413586909763949795187270764002509197362846908721600263590407640239331435797743946639068968182530714992497969629250766233642006666869043197198488505558710080081572718303651084249757629984467851536523131561671672489611342354506102975683280634931335250787164325776630303410430197355308594589794345127372612129749874742848505962957
e1 = 65537
e2 = 17
c1 = 6070418361005764781666022160782201020887766530217726892023574250703991153557153150240365562631823866925399109653692772429273414466157925616984969604480345833056708745589264326707421262501098443511684348192232914773363078866001499635599832817468918612502325969087574855976873314002597693535529314223131401211725375960723298442955172141723469659923837266222074788068850377594521429498262678342651354197024627444164288711810799491130391148471163552225195175015155522706829274469375372001014646432745594081482121724200720169564704735134585990761451469788279800252372582853001296020279841151437121368396563208194238176809
c2 = 10333074300444651393936782269258556921403986428158959194325049613051485082847482400799333224207225002899420584885380779122331681690914097226669296406031455480685880093806047826997202684091610029196843015145312932541842991056212933838748027848354582851989374719190041121737024050736144878626494196879779470357938007923163393755461501521926143809013879106438359634585413111911930506853827052788328813877660360961030885521473428344868672139024952576892377942170827101770540081503574982983989347495232393714702165354007286096839200607023742050117961927827236261835001175781713994427455900056065253089202845028635992697862
g, s1, s2 = gcdext(e1, e2)
m = pow(c1, s1, n) * pow(c2, s2, n) % n
print(long_to_bytes(m).decode())
# flag{c0mm0n_m0dulus_1s_d4ng3r0us}

Shamir#

shamir.py

challenge.py
from Crypto.Util.number import bytes_to_long
import random
p = "XXX"# REDACTED - prime lost
flag = b"flag{...}"
secret = bytes_to_long(flag)
k = 5
n = 11
coeffs = [secret] + [random.randint(1, p-1) for _ in range(k-1)]
shares = []
for i in range(1, n+1):
x = random.randint(1, p-1) # 实际 x 是随机选取的
y = sum(c * pow(x, j, p) for j, c in enumerate(coeffs)) % p
shares.append((x, y))
print(shares)

生成的秘密分片.txt

生成的秘密分片:
[(13825276559652663759456053593154923232020771238254924190105602129554442740903032538098062820337983638666056784818726026705226866679025611690838448584570200, 19012813120561778249910002377121545519300396863416796577430580565668955435109529853661026703963191587511794739652897381447200605465672082042748885989744402), (14989248861487876756545923532577464423717630626792629221618966203158382671849012765703938440292173459828333463382287156647477649833759229415415422006446622, 1656433892597578744823177014342869528132831200379451998967521640131825487494819099422022469838825418150730143438520616267294835254347450196350209174872775), (19193170771688324398963345493388616208257949680877900104979298799760166459827906171423469189582755008620842357080263827095038929588780308148621589260541422, 11420248910634302383712371357580971808319584342845033562709305079257609558334879243688210930475525301635690020652329269939235513202907874912193579010147639), (18777091659417137576603135959549361738394745875776533930983699353415679891339311594674388484175296875080132898946694787449577170540182756514019328107408039, 9704588552249224055741700389530593621449542838333557625043239604844884216427066269916242710825967541084869521646880935759182920024727659925664328119325004), (14287513785577058854224398359692453526128916947865468956393138998889401907577994975977127911557142483281724809006107854288358113197720626510491043303548938, 9770438332979961381243902918934813992264072842817997713173849346168822219848231350591767294014602573834792519783840064045899272301954841421098105680418195), (15119386315728257486056813314318552552131776852359374571135536516700837163067296684378970563219592314591010021093834609706121742207654051417055052071557349, 16692084219568517724580051441903204713362782163474624605007356230785148566081431738623045160758806438045544385291581669748734947320653414449300238328109834), (21639299360306429790518264840030705977452919783601050938080982219887611170051387045460766025557892361751023229841353839566899377685975938928635556686547189, 12343877060822660195641885868676444926185745514478427502000391547786522673431926278446194312565987755982555714259193644278522945366156482829701926440766436), (17403781572025005208843063451017304109237698250797299652792725200086960681154790951373046337507380799261125197889969541906772099793896620488753295096504560, 19150670008423170996379784798328231445600406963296913739761096531018281916219407400122538102243817197525100016408303024079773707274831692716031708315774805), (13712268494862445248911494067355982992182490419234876397649838374491191895372155289722641937870164145755937780023138602530807219076237280105050726711219910, 1791011308314909339397751948386556426199638075952445414959762706679206743326931052440210268620207102528545976021104436487643745311936337923164621066436060), (21991384930267151269802069003579123930799446461196461214557072106672776944086736799413877206434356469442093165424509519266137102480781842658606739163403874, 14963223947878308999984311524851337448763815509922889823520921933718980739751743032849959416282177018557805255468910634606302831448277324417065732420585144), (20641737678873745759238644473878987874377780512320373213801366359879139450580105650792376384552918292291784843752265971609206700166575172878621369499660576, 21115775840010891534972527491920868611647594882864057129786366769672854596717667891296204137876321305451520048412806215332780594549883808548319082816815511)]

题目给出了Shamir Secret Sharing的加密脚本。核心逻辑如下:

secret = bytes_to_long(flag)
k = 5
n = 11
coeffs = [secret] + [random.randint(1, p-1) for _ in range(k-1)]
for i in range(1, n+1):
x = random.randint(1, p-1)
y = sum(c * pow(x, j, p) for j, c in enumerate(coeffs)) % p
shares.append((x, y))

其中secret是多项式的常数项,阈值k = 5,所以多项式次数为 4。题目给出了 11 个分片(x, y),但隐藏了模数p。多项式形式为:

f(x)secret+a1x+a2x2+a3x3+a4x4(modp)f(x)\equiv secret + a_1 * x + a_2 * x^2 + a_3 * x^3 + a_4*x^4 \pmod{p}

目标是恢复secret = f(0)

虽然p被隐藏了,但是所有分片都满足同一个 4 次多项式。对于任意 6 个点,我们都可以构造矩阵:

[1x1x12x13x14y11x2x22x23x24y2...1x6x62x63x64y6]\begin{bmatrix} 1 & x_1 & x_1^2 & x_1^3 & x_1^4 & y_1\\ 1 & x_2 & x_2^2 & x_2^3 & x_2^4 & y_2\\ &&...\\ 1 & x_6 & x_6^2 & x_6^3 & x_6^4 & y_6\\ \end{bmatrix}

由于模p下这些点满足 4 次多项式关系,所以该矩阵在模p下行列式为 0。也就是说,在整数域中计算得到的行列式一定是p的倍数。因此我们可以对多组 6 个点计算行列式,然后取它们的gcd,从而恢复出p的倍数。再分解gcd,找出最大的素因子基本就是p。然后在GF(p)上取任意 5 个点做 Lagrange 插值,取插值多项式在 0 处的值即可得到secret

exp.py

# SageMath 10.7
from itertools import combinations
from math import gcd
from Crypto.Util.number import long_to_bytes
shares = [(13825276559652663759456053593154923232020771238254924190105602129554442740903032538098062820337983638666056784818726026705226866679025611690838448584570200, 19012813120561778249910002377121545519300396863416796577430580565668955435109529853661026703963191587511794739652897381447200605465672082042748885989744402), (14989248861487876756545923532577464423717630626792629221618966203158382671849012765703938440292173459828333463382287156647477649833759229415415422006446622, 1656433892597578744823177014342869528132831200379451998967521640131825487494819099422022469838825418150730143438520616267294835254347450196350209174872775), (19193170771688324398963345493388616208257949680877900104979298799760166459827906171423469189582755008620842357080263827095038929588780308148621589260541422, 11420248910634302383712371357580971808319584342845033562709305079257609558334879243688210930475525301635690020652329269939235513202907874912193579010147639), (18777091659417137576603135959549361738394745875776533930983699353415679891339311594674388484175296875080132898946694787449577170540182756514019328107408039, 9704588552249224055741700389530593621449542838333557625043239604844884216427066269916242710825967541084869521646880935759182920024727659925664328119325004), (14287513785577058854224398359692453526128916947865468956393138998889401907577994975977127911557142483281724809006107854288358113197720626510491043303548938, 9770438332979961381243902918934813992264072842817997713173849346168822219848231350591767294014602573834792519783840064045899272301954841421098105680418195), (15119386315728257486056813314318552552131776852359374571135536516700837163067296684378970563219592314591010021093834609706121742207654051417055052071557349, 16692084219568517724580051441903204713362782163474624605007356230785148566081431738623045160758806438045544385291581669748734947320653414449300238328109834), (21639299360306429790518264840030705977452919783601050938080982219887611170051387045460766025557892361751023229841353839566899377685975938928635556686547189, 12343877060822660195641885868676444926185745514478427502000391547786522673431926278446194312565987755982555714259193644278522945366156482829701926440766436), (17403781572025005208843063451017304109237698250797299652792725200086960681154790951373046337507380799261125197889969541906772099793896620488753295096504560, 19150670008423170996379784798328231445600406963296913739761096531018281916219407400122538102243817197525100016408303024079773707274831692716031708315774805), (13712268494862445248911494067355982992182490419234876397649838374491191895372155289722641937870164145755937780023138602530807219076237280105050726711219910, 1791011308314909339397751948386556426199638075952445414959762706679206743326931052440210268620207102528545976021104436487643745311936337923164621066436060), (21991384930267151269802069003579123930799446461196461214557072106672776944086736799413877206434356469442093165424509519266137102480781842658606739163403874, 14963223947878308999984311524851337448763815509922889823520921933718980739751743032849959416282177018557805255468910634606302831448277324417065732420585144), (20641737678873745759238644473878987874377780512320373213801366359879139450580105650792376384552918292291784843752265971609206700166575172878621369499660576, 21115775840010891534972527491920868611647594882864057129786366769672854596717667891296204137876321305451520048412806215332780594549883808548319082816815511)]
k = 5
deg = k - 1
g = 0
for comb in combinations(shares, deg + 2):
mat = []
for x, y in comb:
mat.append([ZZ(x) ** j for j in range(deg + 1)] + [ZZ(y)])
D = abs(Matrix(ZZ, mat).det())
if D != 0:
g = D if g == 0 else gcd(g, D)
fac = factor(g)
p = max([int(q) for q, e in fac if q.is_prime()])
F = GF(p)
R.<X> = PolynomialRing(F)
points = [(F(x), F(y)) for x, y in shares[:k]]
poly = R.lagrange_polynomial(points)
secret = int(poly(0))
flag = long_to_bytes(secret).decode()
print(flag)
# flag{shamir_p_recovery_test}

RC4#

202606_CRYPTO_中_PolarD&N_CTF_RC4.txt

雨墨很喜欢 RC4,但他觉得普通 RC4 太简单了。于是他做了点小改动……
我们截获了两段密文,看起来和 RC4 有关,但又不太一样。
已知:flag 格式为 flag{...}密钥长度 ≤ 16使用的是 标准 RC4 KSA + PRGA
你能还原出 flag 吗?
c1 = 63dc968e6fbd78425b1aa80deca5dddd5bc2773d4c11bf3a
c2 = 71d89e9a4b8648297043be0de9f0d0a328f228557863db47
key=64327473646C3973646C393361326866626D686949513D3D

RC4 是流密码,加密过程是明文与密钥流异或。如果同一 RC4 密钥流被用于加密两段不同明文,则:

c1=p1ks,c2=p2ksc_1=p_1\oplus ks,c_2=p_2\oplus ks

两段密文异或后:

c1c2=p1p2c_1\oplus c_2=p_1\oplus p_2

密钥流被完全抵消,问题退化为已知明文攻击。

题目给出c1c2key,先处理key字段。对其进行 hex 解码,得到 Base64 字符串,继续 Base64 解码得到wklv_lv_wkh_nhb!,观察可知这是 Caesar +3 编码,向回移 3 位得到this_is_the_key!,该字符串长度为 16,而密文长度为 24,因此将其补零到 24 字节:this_is_the_key!\x00\x00\x00\x00\x00\x00\x00\x00。由于两段密文复用了同一段 RC4 keystream,因此:

flag=c1c2known_plaintextflag=c_1\oplus c_2\oplus known\_plaintext

exp.py

from base64 import b64decode
from Crypto.Util.strxor import strxor
def caesar_alpha(s: bytes, shift: int) -> bytes:
out = bytearray()
for ch in s:
if 65 <= ch <= 90:
out.append((ch - 65 + shift) % 26 + 65)
elif 97 <= ch <= 122:
out.append((ch - 97 + shift) % 26 + 97)
else:
out.append(ch)
return bytes(out)
c1 = bytes.fromhex("63dc968e6fbd78425b1aa80deca5dddd5bc2773d4c11bf3a")
c2 = bytes.fromhex("71d89e9a4b8648297043be0de9f0d0a328f228557863db47")
key_hex = "64327473646C3973646C393361326866626D686949513D3D"
# key 字段:hex -> base64 -> Caesar(-3)
key_b64 = bytes.fromhex(key_hex)
key_rot = b64decode(key_b64)
known = caesar_alpha(key_rot, -3)
# c2 对应明文为 this_is_the_key!,补 0 到密文长度
known_plain = known.ljust(len(c1), b"\x00")
# RC4 同 keystream 复用:c1 ^ c2 = p1 ^ p2
flag = strxor(strxor(c1, c2), known_plain)
print(flag.decode())
# flag{RC4_1s_n0t_s0_h4rd}
PolarCTF网络安全2026夏季个人挑战赛 WriteUp
https://q1uju.cc/posts/polarctf2026summer_writeup/
Author
Q1uJu
Published at
2026-06-14
License
CC BY-NC-SA 4.0

Some information may be outdated