1.一眼就解密

ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30=
base64解码

flag{THE_FLAG_OF_THIS_STRING}
2.MD5

MD5在线解密就行

flag{admin1}
3.Url编码


flag{and 1=1}
4.看我回旋踢

Rot13解密

flag{5cd1004d-86a5-46d8-b720-beb5ba0417e1}
5.摩丝

摩斯解密

flag{ILOVEYOU}
6.password

弱密码一共是九位那么就是名字+生日就行
flag{zs19900315}
7.变异凯撒


flag{Caesar_variation}
8.Quoted-Printable

Quoted-Printable编码解码就行

flag{那你也很棒哦}
9.篱笆墙的影子

古典密码的栅栏位移式密码
普通型13栏就出来

flag{wethinkwehavetheflag}
10.Rabbit
Rabbit解密,没有密钥


flag{Cute_Rabbit}
11.RSA

RSA 原理
RSA 算法中:
- n=p×qn=p×q
- φ(n)=(p−1)×(q−1)φ(n)=(p−1)×(q−1)
- 公钥对:(e,n)(e,n),其中 1<e<φ(n)1<e<φ(n) 且 gcd(e,φ(n))=1gcd(e,φ(n))=1
- 私钥 dd 满足:e×d≡1(modφ(n))e×d≡1(modφ(n))
- 即:d=e−1 mod φ(n)d=e−1modφ(n)
逐步计算
1:计算 φ(n)φ(n)
φ(n)=(p−1)×(q−1)φ(n)=(p−1)×(q−1)
步 2使用扩展欧几里得算法求 dd
解方程:e×d+k×φ(n)=1e×d+k×φ(n)=1,求 dd
3:出结果并格式化
py3脚本
#!/usr/bin/env python3
"""
RSA 私钥参数 d 计算脚本
题目:
p = 473398607161
q = 4511491
e = 17
求 d
"""
def extended_gcd(a, b):
"""扩展欧几里得算法
返回 (gcd, x, y) 使得 ax + by = gcd(a, b)
"""
if b == 0:
return a, 1, 0
else:
gcd, x1, y1 = extended_gcd(b, a % b)
x = y1
y = x1 - (a // b) * y1
return gcd, x, y
def mod_inverse(e, phi):
"""计算模逆元 d = e^(-1) mod phi"""
gcd, x, y = extended_gcd(e, phi)
if gcd != 1:
raise ValueError("e 和 phi 不互质,无法计算逆元")
# 确保 d 为正数
d = x % phi
return d
def main():
# 已知参数
p = 473398607161
q = 4511491
e = 17
print("[+] 已知参数:")
print(f" p = {p}")
print(f" q = {q}")
print(f" e = {e}")
print()
# 计算 n 和 phi(n)
n = p * q
phi_n = (p - 1) * (q - 1)
print("[+] 计算中间值:")
print(f" n = p × q = {n}")
print(f" φ(n) = (p-1) × (q-1) = {phi_n}")
print()
# 验证 e 与 phi(n) 是否互质
import math
gcd = math.gcd(e, phi_n)
print(f"[+] 验证 gcd(e, φ(n)) = gcd({e}, {phi_n}) = {gcd}")
if gcd != 1:
print("[-] e 和 φ(n) 不互质,无法计算逆元!")
return
print("[√] e 和 φ(n) 互质,可以计算逆元")
print()
# 计算 d = e^(-1) mod φ(n)
d = mod_inverse(e, phi_n)
print("[+] 计算结果:")
print(f" d = e^(-1) mod φ(n) = {d}")
print()
# 验证结果
verification = (e * d) % phi_n
print(f"[+] 验证: (e × d) mod φ(n) = ({e} × {d}) mod {phi_n}")
print(f" = {e * d} mod {phi_n}")
print(f" = {verification}")
if verification == 1:
print("[√] 验证成功!")
else:
print("[-] 验证失败!")
print()
# 输出 flag 格式
print("[+] Flag 格式:")
print(f" noxCTF{{{d}}}")
print(f" 提交时替换为: flag{{{d}}}")
if __name__ == "__main__":
main()

flag{125631357777427553}
12.丢失的MD5

- 代码暴力枚举三个未知字符(ASCII 32-126),将
TASC{chr(i)}O3RJMV{chr(j)}WDJKX{chr(k)}ZM进行MD5加密 - 搜索条件:要求MD5哈希值同时包含:
- 子串
e9032 - 子串
da - 子串
911513
- 子串
- 暴力破解:三層循环遍历所有可能组合(95^3 ≈ 857,375种)
py3脚本呈现
import hashlib
for i in range(32, 127):
for j in range(32, 127):
for k in range(32, 127):
s = f'TASC{chr(i)}O3RJMV{chr(j)}WDJKX{chr(k)}ZM'
md5_hash = hashlib.md5(s.encode()).hexdigest()
if 'e9032' in md5_hash and 'da' in md5_hash and '911513' in md5_hash:
print(f"字符串: {s}")
print(f"MD5: {md5_hash}")
print(f"flag: flag{{{md5_hash}}}")
exit()

flag{e9032994dabac08080091151380478a2}
13.Alice与Bob

分析
- 给定数字: 98554799767
- 要求:
- 分解为两个素数(质因数)
- 按小到大顺序连接成新数字
- 计算新数字的MD5 32位小写哈希值
- 输出格式: flag{md5_hash}
解题:
分解质因数
- 大整数:98554799767
- 试除法找到因子:101999 和 966233
- 验证:101999 × 966233 = 98554799767
- 两个因子均为素数
合成新数字
- 较小素数:101999
- 较大素数:966233
- 连接:101999966233
计算MD5哈希
- 输入:101999966233 输出md5 就是这个flag
py3脚本呈现:
import hashlib
import math
def is_prime(n: int) -> bool:
"""检查一个数是否为素数"""
if n < 2:
return False
# 只需检查到 sqrt(n)
for i in range(2, int(math.isqrt(n)) + 1):
if n % i == 0:
return False
return True
def factorize(n: int):
"""分解大整数为两个素数因子"""
# 试除法查找因子
for i in range(2, int(math.isqrt(n)) + 1):
if n % i == 0: # 找到因子
j = n // i
# 检查两个因子是否都是素数
if is_prime(i) and is_prime(j):
return sorted([i, j]) # 返回排序后的因子
return None
def main():
# 给定的大整数
n = 98554799767
# 分解质因数
factors = factorize(n)
if not factors:
print("分解失败")
return
p, q = factors # p是较小素数,q是较大素数
print(f"分解结果: {p} × {q} = {n}")
# 合成新数字: 小的放前面,大的放后面
new_num = int(str(p) + str(q))
print(f"合成数字: {new_num}")
# 计算MD5哈希
md5_hash = hashlib.md5(str(new_num).encode()).hexdigest()
print(f"MD5哈希: {md5_hash}")
# 输出flag
print(f"flag{{{md5_hash}}}")
if __name__ == "__main__":
main()

flag{d450209323a847c8d01c6be47c81811a}
14.大帝的密码武器

密文:ComeChina
先解密这个:FRPHEVGL
当移位量=13(ROT13):解出的单词有意义

SECURITY 安全
我们已经知道偏移量了直接解密文

flag{PbzrPuvan}
15.rsarsa

解密
1:计算模数n
n=p×qn=p×q 计算得2048位大整数
2:计算欧拉函数φ(n) φ(n)=(p−1)×(q−1)φ(n)=(p−1)×(q−1)
3:计算私钥d
使用扩展欧几里得算法:d=e−1mod φ(n)d=e−1modφ(n) 解方程:e×d≡1(modφ(n))e×d≡1(modφ(n))
4:解密消息
m=cdmod nm=*c*dmodn 使用模幂运算快速计算
py3脚本
# RSA参数
p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
# 计算n和φ(n)
n = p * q
phi_n = (p-1) * (q-1)
# 扩展欧几里得求模逆元d
def mod_inverse(a, m):
def egcd(a, b):
if b == 0:
return (1, 0, a)
x, y, g = egcd(b, a % b)
return (y, x - (a // b) * y, g)
x, y, g = egcd(a, m)
if g != 1:
raise ValueError('逆元不存在')
return x % m
# 计算私钥d
d = mod_inverse(e, phi_n)
# RSA解密 m = c^d mod n
m = pow(c, d, n)
print(f"解密后的数字m: {m}")
print(f"flag格式: flag{{{m}}}")

flag{5577446633554466577768879988}
16.Windows系统密码

格式分析
这是 Windows SAM 数据库格式(LM:NTLM):
用户名:RID:LM-Hash:NTLM-Hash:::
Administrator:500:...– 管理员账户ctf:1002:...– 用户账户- 格式:
LM:NTLM(aad3b435b51404eeaad3b435b51404ee表示空LM Hash)
只有ctf这个用户有密码解出就行
Guest和Administrator是空密码—>31d6cfe0d16ae931b73c59d7e0c089c0
解出这个就行
a7fcb22a88038f35a8f39d503e7f0062

flag{good-luck}
17.信息化时代的步伐


中文电报解码


flag{计算机要从娃娃抓起}
18.凯撒?替换?呵呵!

凯撒密码替换,MTHJ=flag
quipqiup – cryptoquip and cryptogram solver

flag{substitutioncipherdecryptionisalwayseasyjustlikeapieceofcake}
19.萌萌哒的八戒

猪圈替换式密码

对照就行 小写
flag{whenthepigwanttoeat}
20.权限获得第一步


解出windows密码
结构分析如下:Administrator:500:806EDC27AA52E314AAD3B435B51404EE:F4AD50F57683D4260DFD48AA351A17A8:::
- 用户: Administrator
- RID: 500
- LM Hash:
806EDC27AA52E314AAD3B435B51404EE - NT Hash (通常存放 NTLM 哈希的位置):
F4AD50F57683D4260DFD48AA351A17A8
F4AD50F57683D4260DFD48AA351A17A8
解密这个就行

flag{3617656}
21.RSA1

- 已知 RSA-CRT 参数:
p, q, dp, dq, c。 - 计算
m1 = c^dp mod p和m2 = c^dq mod q。 - 计算
q_inv = q^{-1} mod p。 - 利用中国剩余定理(CRT)公式:
m = m2 + ((m1 - m2) * q_inv mod p) * q。 - 将得到的整数
m转换为字节串,即为 flag。
py3脚本
import binascii
p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852
# 计算 n
n = p * q
# 计算 m1 和 m2
m1 = pow(c, dp, p)
m2 = pow(c, dq, q)
# 计算 q 关于 p 的模逆
q_inv = pow(q, -1, p)
# 使用 CRT 计算明文 m
h = (q_inv * (m1 - m2)) % p
m = m2 + h * q
# 将整数转换为字节串(flag)
flag_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')
print(flag_bytes.decode())

flag{W31c0m3_70_Ch1n470wn}
22.传统知识+古典密码

根据干支序列和“+甲子”的提示,将每个干支转换为六十甲子中的序号(从1开始),得到序列 [28, 30, 23, 8, 17, 10, 16, 30]。由于“甲子”代表一个60年的周期,将每个序号加上60,得到 [88, 90, 83, 68, 77, 70, 76, 90],对应ASCII字符 X, Z, S, D, M, F, L, Z,组合后得到字符串 XZSDMFLZ
gan = ['甲','乙','丙','丁','戊','己','庚','辛','壬','癸']
zhi = ['子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥']
jiazi = [gan[i%10]+zhi[i%12] for i in range(60)]
given = ['辛卯','癸巳','丙戌','辛未','庚辰','癸酉','己卯','癸巳']
indices = [jiazi.index(g)+1 for g in given]
flag = ''.join(chr(i+60) for i in indices)
print(f'CTF{{{flag}}}')
XZSDMFLZ 在进行解密
栅栏密码解密
栏数为 2

XMZFSLDZ
凯撒解密
当位移量为 5 解出有意义的字符串

Key值为:
CTF{SHUANGYU}
flag{SHUANGYU}
23.世上无难事
VIZZB IFIUOJBWO NVXAP OBC XZZ UKHVN IFIUOJBWO HB XVIXW XAW VXFI X QIXN VBD KQ IFIUOJBWO WBKAH NBWXO VBD XJBCN NKG QLKEIU DI XUI VIUI DKNV QNCWIANQ XN DXPIMKIZW VKHV QEVBBZ KA XUZKAHNBA FKUHKAKX XAW DI VXFI HBN QNCWIANQ NCAKAH KA MUBG XZZ XEUBQQ XGIUKEX MUBG PKAWIUHXUNIA NVUBCHV 12NV HUXWI XAW DI XUI SCQN QB HZXW NVXN XZZ EBCZW SBKA CQ NBWXO XAW DI DXAN NB NVXAP DXPIMKIZW MBU JIKAH QCEV XA BCNQNXAWKAH VBQN HKFI OBCUQIZFIQ X JKH UBCAW BM XLLZXCQI XAW NVI PIO KQ 640I11012805M211J0XJ24MM02X1IW09
密文分析
观察密文 VIZZB IFIUOJBWO...,它的词长分布和标点符号非常符合英语句子的特征。由于提示提到“毫无规律”,通常指的是单表替换密码(Monoalphabetic Substitution Cipher),即字母表中的每个字母都被替换成了另一个固定的字母。
密文开头的 VIZZB IFIUOJBWO 看起来像是一个问候语。
尝试猜测:VIZZB = HELLOIFIUOJBWO = EVERYBODY
根据题目描述“某国现任总统外发的一段指令”,搜索 HELLO EVERYBODY 开头的总统演讲,可以发现这是 美国前总统奥巴马(Barack Obama) 在 2009 年弗吉尼亚州韦克菲尔德高中(Wakefield High School)做的开学演讲。
对照原文和密文,我们可以推导出完整的替换表。
原文片段:
“Hello everybody. Thank you. Thank you all. Right. Everybody go ahead and have a seat. How is everybody doing today? … and the key is …”
密文对应部分:
VIZZB IFIUOJBWO NVXAP OBC XZZ UKHVN ... XAW NVI PIO KQ ...
密文 明文 助记单词 (密文$to$明文)
A N XAW $to$ AND
B O VIZZB $to$ HELLO
C U OBC $to$ YOU
D W VBD $to$ HOW
E C XEUBQQ $to$ ACROSS
F V IFIUOJBWO $to$ EVERYBODY
G M MUBG $to$ FROM
H G HB $to$ GO
I E ★ 用于Flag (VIZZB $to$ HELLO)
J B ★ 用于Flag (IFIUOJBWO $to$ EVERYBODY)
K I KQ $to$ IS
L P QLKEIU $to$ SPIDER
M F ★ 用于Flag (MUBG $to$ FROM)
N T NVXAP $to$ THANK
O Y OBC $to$ YOU
P K NVXAP $to$ THANK
Q S QIXN $to$ SEAT
S J SCQN $to$ JUST
U R IFIUOJBWO $to$ EVERYBODY
V H VIZZB $to$ HELLO
W D ★ 用于Flag (XABW $to$ AND)
X A ★ 用于Flag (XZZ $to$ ALL)
Z L VIZZB $to$ HELLO
我们可以确认映射关系是正确的,特别是最后一句:
密文:XAW NVI PIO KQ
明文:AND THE KEY IS
解密 Key 值
密文的最后给出了 Key 的加密字符串:640I11012805M211J0XJ24MM02X1IW09
根据题目要求(32位,包含小写字母),我们需要用同样的替换表将这个字符串中的大写字母解密还原为小写字母。
替换过程:640I11012805M211J0X J24M M02X1I W09640e11012805f211b0a b24f f02a1e d09
flag{640e11012805f211b0ab24ff02a1ed09}
先转换成小写
vizzb ifiuojbwo nvxap obc xzz ukhvn ifiuojbwo hb xvixw xaw vxfi x qixn vbd kq ifiuojbwo wbkah nbwxo vbd xjbcn nkg qlkeiu di xui viui dknv qncwianq xn dxpimkizw vkhv qevbbz ka xuzkahnba fkuhkakx xaw di vxfi hbn qncwianq ncakah ka mubg xzz ebczw sbka cq nbwxo xaw di dxan nb nvxap dxpimkizw mbu jikah qcev xa bcqnqxawkah vbqn hkfi obcuqizfiq x jkh ubciaw bm xllzxcqi xaw nvi pio kq 640i11012805m211j0xj24mm02x1iw09
可以用https://quipqiup.com/ 暴力破解

直接出来了
flag{640e11012805f211b0ab24ff02a1ed09}
24.Unencode

UUencode解码

flag{dsdasdsa99877LLLKK}
25.[AFCTF2018]Morse
-..../.----/-..../-..../-..../...--/--.../....-/-..../-..../--.../-.../...--/.----/--.../...--/..---/--.../--.../....-/...../..-./--.../...--/...--/-----/...../..-./...--/...--/...--/....-/...--/...../--.../----./--.../-..
摩斯解码

61666374667B317327745F73305F333435797D
十六进制转ASCII

flag{1s't_s0_345y}
26.old-fashion
又是一个单表替换的密码题目
单表替换密码(Monoalphabetic Substitution Cipher)题目,但包含了一个陷阱:密文在第一句分号之后更换了替换表(密钥)**。

quipqiup – cryptoquip and cryptogram solver 直接出

flag{n1_2hen-d3_hu1-mi-ma_a}
27.RSA3

典型的RSA共模攻击(Common Modulus Attack)场景:
- 两个密文c1和c2使用相同的模数n,但不同的公钥指数e1和e2加密
- e1和e2互质(gcd(e1, e2) = 1)
- 由于s·e1 + t·e2 = 1,我们可以计算 m = (c1^s · c2^t) mod n 恢复原始明文
RSA加密原理
选择两个大质数p, q,计算n = p·q
选择公钥指数e,使gcd(e, φ(n)) = 1,其中φ(n) = (p-1)(q-1)
密文c = m^e mod n,其中m是原始明文
共模攻击原理
当同一明文m用相同模数n,但不同指数e1和e2加密:
- c1 = m^e1 mod n
- c2 = m^e2 mod n
若gcd(e1, e2) = 1,可用扩展欧几里得算法找到s和t,使得s·e1 + t·e2 = 1
通过计算 m = (c1^s · c2^t) mod n 恢复原始明文:
m = m^(s·e1+t·e2) = (m^e1)^s · (m^e2)^t = c1^s · c2^t (mod n)
负指数处理
当s或t为负时,无法直接计算c^s mod n
需先计算模逆元:若s < 0,计算c1_inv = c1^(-1) mod n
然后计算c1_inv^(-s) mod n 替代 c1^s mod n
py3解密脚本
import math
from Crypto.Util.number import long_to_bytes
# 参数
n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e1 = 11187289
e2 = 9647291
# 验证e1和e2互质
if math.gcd(e1, e2) != 1:
exit()
# 扩展欧几里得算法
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
g, s, t = egcd(e1, e2)
# 计算明文
part1 = pow(c1, s, n) if s >= 0 else pow(pow(c1, -1, n), -s, n)
part2 = pow(c2, t, n) if t >= 0 else pow(pow(c2, -1, n), -t, n)
m = (part1 * part2) % n
print(f"Flag: {long_to_bytes(m).decode()}")

flag{49d91077a1abcb14f1a9d546c80be9ef}
28.RSA2

已知dp攻击
为什么dp会泄露导致RSA被破解?
在RSA中:
dp = d mod (p-1)- 由RSA性质:
e·d ≡ 1 mod φ(n),其中φ(n) = (p-1)(q-1) - 因此:
e·dp ≡ 1 mod (p-1),即e·dp - 1 = k·(p-1)
攻击步骤:
- 计算
temp = e·dp - 1(它是p-1的倍数) - 随机选择整数g,计算
x = g^temp mod n - 由于temp是p-1的倍数,根据费马小定理:
x ≡ 1 mod p - 计算
p = gcd(x-1, n)得到p - 通过
q = n/p计算q - 恢复私钥d并解密:
m = c^d mod n
py3解题脚本
import math
import random
from Crypto.Util.number import long_to_bytes
# 题目给定参数
e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
# 1. 利用dp恢复p
temp = e * dp - 1
for i in range(10): # 通常几次尝试就能成功
g = random.randint(2, n-1)
x = pow(g, temp, n)
p = math.gcd(x - 1, n)
if 1 < p < n: # 找到正确的p
q = n // p
break
# 2. 计算私钥d并解密
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
m = pow(c, d, n)
# 3. 转换为flag
flag = long_to_bytes(m).decode()
print(f"Flag: {flag}")

flag{wow_leaking_dp_breaks_rsa?_98924743502}
29.还原大师

题目分析
神秘字符串:`TASC?O3RJMV?WDJKX?ZM`(3个问号是未知大写字母)
已知该字符串的32位MD5:`E903???4DAB????08?????51?80??8A?`(部分字符已知)
目标:找出原始字符串,并提交其完整MD5值作为flag
解题思路
有3个未知大写字母,总共有 26³ = 17,576 种可能组合
通过暴力枚举所有可能的组合
对每个组合计算MD5值,检查是否与已知模式匹配
找到匹配的字符串,获取其完整MD5值
py脚本
import hashlib
import itertools
import string
# 基础字符串模板
base_str = "TASC{}O3RJMV{}WDJKX{}ZM"
# MD5模式(大写)
md5_pattern = "E903???4DAB????08?????51?80??8A?"
def matches_pattern(computed_md5, pattern):
"""检查计算的MD5是否匹配给定模式"""
if len(computed_md5) != len(pattern):
return False
for c1, c2 in zip(computed_md5, pattern):
if c2 != '?' and c1 != c2:
return False
return True
# 枚举所有可能的大写字母组合
for combo in itertools.product(string.ascii_uppercase, repeat=3):
test_str = base_str.format(combo[0], combo[1], combo[2])
md5_hash = hashlib.md5(test_str.encode()).hexdigest().upper()
if matches_pattern(md5_hash, md5_pattern):
print(f"原始字符串: {test_str}")
print(f"完整MD5: {md5_hash}")
print(f"flag{{ {md5_hash} }}") # 提交答案格式
break

flag{E9032994DABAC08080091151380478A2}
30.异性相吸
key:asadsasdasdasdasdasdasdasdasdasdqwesqf
密文:ܟࠄቕ̐员䭜塊噓䑒̈́ɘ䘆呇Ֆ䝗䐒嵊ᐛ
有两个文件:key.txt 和 密文.txt
两者内容均为:`asadsasdasdasdasdasdasdasdasdasdqwesqf`
题目要求证明"异性相吸"的正确性
在密码学中,"异性相吸"常指XOR(异或)操作的特性:0和1(异性)进行XOR运算会得到1(相吸)
题目暗示使用XOR(异或)操作进行解密在XOR加密中,明文 XOR 密钥 = 密文因此,密文 XOR 密钥 = 明文,虽然两个文件内容相同,但实际挑战中它们应该是不同的编写一个通用XOR解密脚本
XOR(异或)操作:当两个位不同时结果为1(异性相吸),相同时结果为0
XOR特性:(A XOR B) XOR B = A,这使其成为完美的加密/解密操作
实际应用:在本题中,密文与密钥进行XOR操作,恢复原始明文
"异性相吸"的科学性:在物理学中,异性电荷相吸是基本规律,正如XOR操作中0和1的"吸引"特
py3脚本
# 读取密钥和密文
with open('key.txt', 'r') as f:
key = f.read().strip()
with open('密文.txt', 'r') as f:
ciphertext = f.read().strip()
# 将字符串转换为字节
key_bytes = key.encode('utf-8')
cipher_bytes = ciphertext.encode('utf-8')
# 确保密钥长度与密文相同(重复密钥)
key_bytes = (key_bytes * (len(cipher_bytes) // len(key_bytes) + 1))[:len(cipher_bytes)]
# 执行XOR操作解密
plaintext_bytes = bytes([cipher_bytes[i] ^ key_bytes[i] for i in range(len(cipher_bytes))])
plaintext = plaintext_bytes.decode('utf-8', errors='ignore')
print(f"解密结果: {plaintext}")
print(f"flag{{{plaintext}}}")

flag{ea1bc0988992276b7f95b54a7435e89e}
31.RSA
公钥(Public Key)经过解析后,可以发现其模数 $N$ 非常小。
- 算法: RSA
- 模数 ($N$) 长度: 256 位 (Bits)
- 安全隐患: 现代 RSA 通常使用 2048 位或 4096 位。256 位的 RSA 密钥在现代计算机上可以在几秒钟内完成因数分解,从而算出私钥。
提取公钥信息: 从 PEM 字符串中提取模数 $N$ 和指数 $e$。
分解模数 $N$: 使用工具(如 factordb)将 $N$ 分解为两个素数 $p$ 和 $q$。
计算私钥 $d$: 根据公式 $d equiv e^{-1} pmod{(p-1)(q-1)}$ 计算私钥。
解密: 读取 `flag.enc`,将其转换为整数,使用私钥进行解密运算 $m equiv c^d pmod N$,最后转回文本。
import base64
from Crypto.PublicKey import RSA
from Crypto.Util.number import bytes_to_long, long_to_bytes, inverse
import requests
import re
# 1. 设置公钥和密文文件
pub_key_pem = """-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+
/AvKr1rzQczdAgMBAAE=
-----END PUBLIC KEY-----"""
filename = "flag.enc"
def solve():
print("[*] 正在解析公钥...")
key = RSA.importKey(pub_key_pem)
n = key.n
e = key.e
print(f" n = {n}")
print(f" e = {e}")
print(f" n 的位数为: {n.bit_length()} (256位是非常容易破解的)")
# 2. 分解 N (使用 factordb API)
print("n[*] 正在查询 FactorDB 分解 N...")
try:
api_url = f"http://factordb.com/api?query={n}"
response = requests.get(api_url)
data = response.json()
# 检查是否分解成功 (status 'FF' 表示完全分解)
if data['status'] != 'FF' and data['status'] != 'CF':
print("[-] FactorDB 未找到现成因子,可能需要使用 yafu 本地跑一下。")
print(f"请手动分解这个数字: {n}")
return
factors = data['factors']
# factordb 返回的是 [因子, 次数],我们需要提取 p 和 q
# 对于 RSA,通常是两个素数,所以列表应该包含两个不同的素数,或者一个素数出现两次
prime_factors = []
for f in factors:
val = int(f[0])
count = int(f[1])
for _ in range(count):
prime_factors.append(val)
if len(prime_factors) != 2:
print("[-] 因子数量异常,不是标准的 p * q RSA。")
return
p = prime_factors[0]
q = prime_factors[1]
print(f" p = {p}")
print(f" q = {q}")
except Exception as err:
print(f"[-] 网络查询失败: {err}")
print("请手动使用工具分解 N。")
return
# 3. 计算私钥 d
print("n[*] 计算私钥 d...")
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
print(f" d = {d}")
# 4. 解密文件
print("n[*] 正在解密 flag.enc ...")
try:
with open(filename, "rb") as f:
ciphertext = f.read()
c_int = bytes_to_long(ciphertext)
# RSA 解密公式: m = c^d mod n
m_int = pow(c_int, d, n)
flag = long_to_bytes(m_int)
print("n" + "="*30)
print(f"FLAG: {flag.decode('utf-8', errors='ignore')}")
print("="*30 + "n")
except FileNotFoundError:
print(f"[-] 错误: 找不到文件 {filename},请确保它在当前目录下。")
except Exception as e:
print(f"[-] 解密过程中出错: {e}")
if __name__ == "__main__":
solve()

flag{decrypt_256}
32.RSAROLL
data.txt
{920139713,19}
704796792
752211152
274704164
18414022
368270835
483295235
263072905
459788476
483295235
459788476
663551792
475206804
459788476
428313374
475206804
459788476
425392137
704796792
458265677
341524652
483295235
534149509
425392137
428313374
425392137
341524652
458265677
263072905
483295235
828509797
341524652
425392137
475206804
428313374
483295235
475206804
459788476
306220148
题目.txt
RSA roll!roll!roll!
Only number and a-z
(don't use editor
which MS provide)
密钥生成:
选择两个大素数 p 和 q
计算 n = p × q
计算 φ(n) = (p-1)(q-1)
选择 e(1<e<φ(n),且与 φ(n) 互质)
计算 d ≡ e⁻¹ mod φ(n)
已知参数: n=920139713,e=19,密文列表
分解 n: n = 18443 × 49891(p=18443,q=49891)
计算 φ(n): φ(n) = 18442 × 49890 = 920071380
求私钥 d: d ≡ 19⁻¹ mod φ(n) = 96849619
解密运算: 对每个密文 c 计算 c⁹⁶⁸⁴⁹⁶¹⁹ mod 920139713
转字符: 将解密结果作为 ASCII 码转为字符
py3解题脚本
import sys
# 扩展欧几里得算法求模逆
def egcd(a, b):
if b == 0:
return (1, 0, a)
else:
x, y, g = egcd(b, a % b)
return (y, x - (a // b) * y, g)
# RSA 解密函数
def rsa_decrypt(ciphertext, d, n):
return pow(ciphertext, d, n)
def main():
# 读取文件
with open('data.txt', 'r') as f:
lines = f.readlines()
# 解析第一行获取 N 和 e
first_line = lines[0].strip()
# 去除花括号
first_line = first_line.strip('{}')
n_str, e_str = first_line.split(',')
n = int(n_str)
e = int(e_str)
# 已知的质因数 p 和 q(通过分解 N 得到)
p = 18443
q = 49891
# 验证 p*q 是否等于 N
if p * q != n:
print("错误:p*q 不等于 N")
sys.exit(1)
# 计算 φ(N)
phi = (p - 1) * (q - 1)
# 计算私钥 d(e 模 φ(N) 的逆元)
# 使用扩展欧几里得算法
d, _, g = egcd(e, phi)
if g != 1:
print("错误:e 和 φ(N) 不互质")
sys.exit(1)
# 确保 d 是正数
d = d % phi
if d < 0:
d += phi
# 读取密文(从第二行开始)
ciphertexts = []
for line in lines[1:]:
line = line.strip()
if line: # 跳过空行
ciphertexts.append(int(line))
# 解密每个密文
plaintext_chars = []
for ct in ciphertexts:
# RSA 解密
pt_num = rsa_decrypt(ct, d, n)
# 将解密后的数字转换为 ASCII 字符
# 注意:每个解密结果应该是一个字节(0-255)
if pt_num < 0 or pt_num > 255:
print(f"警告:解密后的值 {pt_num} 超出 ASCII 范围")
else:
plaintext_chars.append(chr(pt_num))
# 拼接所有字符得到 flag
flag = ''.join(plaintext_chars)
print("解密后的 flag 为:")
print(flag)
if __name__ == "__main__":
main()

flag{13212je2ue28fy71w8u87y31r78eu1e2}









