basic-mod1
str = '128 63 242 87 151 147 50 369 239 248 205 346 299 73 335 189 105 293 37 214 333 137'
d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
print(''.join([d[int(x) % 37] for x in str.split(' ')]))
basic-mod2
from gmpy2 import *
from sympy import invert
str = '186 249 356 395 303 337 190 393 146 174 446 127 385 400 420 226 76 294 144 90 291 445 137'
d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
print(''.join([d[invert(int(x), 41) - 1] for x in str.split(' ')]))
credstuff
str = 'cvpbPGS{P7e1S_54I35_71Z3}'
d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in range(len(d)):
ans = ''
for x in str:
if x.isalpha():
if x.islower():
x = x.upper()
ans += d[(d.find(x) + i) % len(d)].lower()
else:
ans += d[(d.find(x) + i) % len(d)]
else:
ans += x
if ans.find('picoCTF') != -1:
print(ans)
morse-code
picoCTF{wh47_h47h_90d_w20u9h7}
rail-fence
'''
若知道栏数,则使用decode解密,若不知道,则使用crack_cipher遍历所有可能性
'''
def generate_w(string, n):
'''将字符排列成w型'''
array = [['.'] * len(string) for i in range(n)] #生成初始矩阵
row = 0
upflag = False
for col in range(len(string)): #在矩阵上按w型画出string
array[row][col] = string[col]
if row == n - 1:
upflag = True
if row == 0:
upflag = False
if upflag:
row -= 1
else:
row += 1
return array
def encode(string, n):
'''加密'''
array = generate_w(string, n)
msg = []
for row in range(n): #将每行的字符连起来
for col in range(len(string)):
if array[row][col] != '.':
msg.append(array[row][col])
return array, msg
def decode(string, n):
'''解密'''
array = generate_w(string, n)
sub = 0
for row in range(n): #将w型字符按行的顺序依次替换为string
for col in range(len(string)):
if array[row][col] != '.':
array[row][col] = string[sub]
sub += 1
msg = []
for col in range(len(string)): #以列的顺序依次连接各字符
for row in range(n):
if array[row][col] != '.':
msg.append(array[row][col])
return array, msg
def crack_cipher(string):
'''破解密码'''
for n in range(2, len(string)): #遍历所有可能的栏数
print(str(n) + '栏:' + ''.join(decode(string, n)[1]))
if __name__ == "__main__":
string = "Ta _7N6DDEhlg:W3D_H3C31N__883ef sHR053F38N43D1B i33___ND"
n = 4 #栏数
#若不知道栏数,则遍历所有可能
# crack_cipher(string)
#若知道栏数
array, msg = decode(string, n)
# array,msg = encode(string, n)
for i in array:
print(i)
print(''.join(msg))
# ['T', '.', '.', '.', '.', '.', 'a', '.', '.', '.', '.', '.', ' ', '.', '.', '.', '.', '.', '_', '.', '.', '.', '.', '.', '7', '.', '.', '.', '.', '.', 'N', '.', '.', '.', '.', '.', '6', '.', '.', '.', '.', '.', 'D', '.', '.', '.', '.', '.', 'D', '.', '.', '.', '.', '.', 'E', '.']
# ['.', 'h', '.', '.', '.', 'l', '.', 'g', '.', '.', '.', ':', '.', 'W', '.', '.', '.', '3', '.', 'D', '.', '.', '.', '_', '.', 'H', '.', '.', '.', '3', '.', 'C', '.', '.', '.', '3', '.', '1', '.', '.', '.', 'N', '.', '_', '.', '.', '.', '_', '.', '8', '.', '.', '.', '8', '.', '3']
# ['.', '.', 'e', '.', 'f', '.', '.', '.', ' ', '.', 's', '.', '.', '.', 'H', '.', 'R', '.', '.', '.', '0', '.', '5', '.', '.', '.', '3', '.', 'F', '.', '.', '.', '3', '.', '8', '.', '.', '.', 'N', '.', '4', '.', '.', '.', '3', '.', 'D', '.', '.', '.', '1', '.', 'B', '.', '.', '.']
# ['.', '.', '.', ' ', '.', '.', '.', '.', '.', 'i', '.', '.', '.', '.', '.', '3', '.', '.', '.', '.', '.', '3', '.', '.', '.', '.', '.', '_', '.', '.', '.', '.', '.', '_', '.', '.', '.', '.', '.', '_', '.', '.', '.', '.', '.', 'N', '.', '.', '.', '.', '.', 'D', '.', '.', '.', '.']
# The flag is: WH3R3_D035_7H3_F3NC3_8361N_4ND_3ND_D81DB8E3
substitution0
quipqiup - cryptoquip and cryptogram solver
substitution1
substitution2
记得填上数字
transposition-trial
str = 'heTfl g as iicpCTo{7F4NRP051N5_16_35P3X51N3_VE1A1D3D}B'
ans = ''
# 小于间隔继续
for i in range((len(str) + 3 - 1) // 3):
ans += str[3 * i + 2] + str[3 * i + 0] + str[3 * i + 1]
print(ans)
Vigenere
str = 'rgnoDVD{O0NU_WQ3_G1G3O3T3_A1AH3S_d0db78b8}'
str = str.upper()
key = 'CYLAB'
ans = ''
index = 0
for ch in str:
if ch.isalpha():
ans += chr((ord(ch) - ord(key[index % len(key)]) + 26) % 26 + ord('a'))
index += 1
else:
ans += ch
print(ans)
diffie-hellman
a = 'H98A9W_H6UM8W_6A_9_D6C_5ZCI9C8I_DI9D987F'
b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
ans = ''
for i in a:
if i == '_':
ans += i
else:
ans += (b[(b.find(i) - 5) % len(b)])
print('picoCTF{' + ans.lower() + '}')
Very Smooth
import gmpy2
from Crypto.Util.number import *
def Pollards_p_1(N):
a = 2
n = 2
while True:
a = pow(a, n, N)
res = gmpy2.gcd(a - 1, N)
if res != 1 and res != N:
print('n =', n)
print('p =', res)
return res
n += 1
e = gmpy2.mpz(0x10001)
n = gmpy2.mpz(
0x809fbd8b667d664f01fe1b0387e0b424efe2035e2dec4d249ace30563d0e1a50050020880c2f01bad63b22e21125d780d887cffdb1165268e6be788cd49ad8a9a1d27482f1a8ccbb37adc0deee65d09f312ebaab854782e2411d917181fef63d478b7e25391ac10d0330cafcb5c8d859ee1e403be029ce5dd75f864deabe5a65645b099afb7af4ed84dd75d1e4b966e2a0662ece5409feeacb2a277ddf05b72153ff6f36524f7693cc432269b56bd8ab3d601844aef6a6130eaaec08f92f9816ed0e7781a23a043570364807bef579c1e9175e3fe2b1d8f52356230feea244ce1b88b2342c9e40b25583a1fe558bdfb3a7115a4c71a6f06b706419ce8e21a3e1
)
c = gmpy2.mpz(
0x74ce97c4712bc3827a9f6021089c093a7540a6280330a9ec7c6f446a88093c33a6b9a0a1fdf2cad96e32344970adbf26601d9baf2c4e9892dde435dc994bde4754fddbac47a475b3907a455c6f671484b473b5481080224406b1d48d48da5ba0d9fccdc5732cb64c0f02c32ddc1413f66bd95b8e5a929e5b1f14843bd8f5d4747a4aabcc64217a187db6913facce48f2019b5524633153ee40a4376960b7f669f331da29227fa9a8c09a58a6f3db7453dd89a6093c062ff95502cc7cca5ee497c8ec6265413f5d05d1b720b4eb620875b6f6d2a7958e2391835497a106f4c280cd1ca8b9605bbef5952b54dffc028c160c1495e5cd2957f6f2bbb2e868823b6a
)
p = Pollards_p_1(n)
q = n // p
assert p * q == n
d = gmpy2.invert(e, (p - 1) * (q - 1))
m = pow(c, d, n)
print(long_to_bytes(m))
Sequences
import hashlib
import sys
import functools
from gmpy2 import *
ITERS = int(2e7)
VERIF_KEY = "96cc5f3b460732b442814fd33cf8537c"
ENCRYPTED_FLAG = bytes.fromhex(
"42cbbce1487b443de1acf4834baed794f4bbd0dfe08b5f3b248ef7c32b")
P = mpz(10**10000)
# This will overflow the stack, it will need to be significantly optimized in order to get the answer :)
def m_func(i):
if i == 0: return 1
if i == 1: return 2
if i == 2: return 3
if i == 3: return 4
m = [
[mpz(0), mpz(1), mpz(0), mpz(0)],
[mpz(0), mpz(0), mpz(1), mpz(0)],
[mpz(0), mpz(0), mpz(0), mpz(1)],
[mpz(55692), mpz(-9549), mpz(301),
mpz(21)],
]
m = quickMatrix(m, i - 3)
ans = mpz(0)
for i in range(4):
ans += ((m[3][i] * m_func(i)) % P)
return ans
def mulMatrix(x, y):
ans = [[0 for i in range(4)] for j in range(4)]
for i in range(4):
for j in range(4):
for k in range(4):
ans[i][j] += ((x[i][k] * y[k][j]) % P)
return ans
def quickMatrix(m, n):
ans = [[0 for i in range(4)] for j in range(4)]
for i in range(4):
ans[i][i] = 1
while (n):
if n % 2 != 0:
ans = mulMatrix(ans, m)
m = mulMatrix(m, m)
n >>= 1
return ans
# Decrypt the flag
def decrypt_flag(sol):
sol = sol % (10**10000)
sol = str(sol)
sol_md5 = hashlib.md5(sol.encode()).hexdigest()
if sol_md5 != VERIF_KEY:
print("Incorrect solution")
sys.exit(1)
key = hashlib.sha256(sol.encode()).digest()
flag = bytearray([char ^ key[i]
for i, char in enumerate(ENCRYPTED_FLAG)]).decode()
print(flag)
if __name__ == "__main__":
sol = m_func(ITERS)
decrypt_flag(sol)
Sum-O-Primes
from gmpy2 import *
from Crypto.Util.number import *
e = 65537
x = 0x1603fc8d929cb31edf62bcce2d06794f3efd095accb163e6f2b78941bd8c646d746369636a582aaac77c16a9486881a9e3db26d742e48c4adcc417ef98f310a0c5433ab077dd872530c3c3c77fe0c080d84154bfdb4c920df9617e986999104d9284516c7babc80dc53718d59032aefdf41b9be53957dea3f00a386b2666d446e
n = 0x75302ba292dc4bf47ffd690b8edc70ef1fcca5e148b2b9c1b60227788afcfe77a0097929ed3789fe51ac66f678c558244890a09ae4af3e7d098fd366a1c859edabbff1c9e164d5354968798107ae8518fcaab3743de58a141ffd26c1e16cb09fed1f6b0d68536ec7fba744ed120fea8c3a7ac1ebfa55d664d2f321fb44e814650147a9031f3bfa8f69d87393c7d88976d28d147398a355020bcb8e5613f0b29028b77db710e163ca1019fd3c3a065465ea457adec45243c385d12d3a1de3178f6ca05964be92e8b5bc24d420956de96ccc9ce39e70705660eb6b2f4e675aac7d6d7ba45c84223fc5819b37aa85beff1382f1c2c3b97603150f30c17f7e674441
c = 0x562888c70ce9a5c5ed9a0be1b6196f854ba2efcdb6dd0f79319ee9e1142659f90a6bae67481eb0f635f445d3c9889da84639beb84ff7159dcf4d3a389873dc90163270d80dbb9503cbc32992cb592069ba5b3eb2bbe410a3121d658f18e100f7bd878a25c27ab8c6c15b690fce1ca43288163c544bfce344bcd089a5f4733acc7dc4b6160718e3c627e81a58f650281413bb5bf7bad5c15b00c5a2ef7dbe7a44cce85ed5b1becd5273a26453cb84d327aa04ad8783f46d22d61b96c501515913ca88937475603437067ce9dc10d68efc3da282cd64acaf8f1368c1c09800cb51f70f784bd0f94e067af541ae8d20ab7bfc5569e1213ccdf69d8a81c4746e90c1
phi = n - x + 1
d = invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
NSA Backdoor
使用了 Pohlig-Hellman algorithm
离散对数 - CTF Wiki (ctf-wiki.org)
先用 Very Smooth 的代码分解 n 有
p = 133120514134071565184901374403906104857402594315193452979400334844456988039351029748429497538981454221984106135005043996378098395846705709422658663585864970394230279241392567216599860405945469882804839379543093459226432299183847151658790842646530907008354991523758458009950957111989465047584759069188272154703
q = 107878320716069936845347261730222923402619282584236808136469656719645067255143372538361375857163594280233925663413568686520703251291382637679919197208920902793419007945364505474185442005931731898039583502138819092649272834779913753377381462765827012568092442233669634217190652686190269458879367972776287369087
在 sagemath 上用 discrete_log
就行(这个 discrete_log
包含了好多算法,强强)