CTF's wp
Misc
超级侦探
根据题目提示,Flag为拍摄点背后的停车场电话,flag格式为L3HSEC{}
通过google搜图,对比图片中的关键信息,查找到该位置大概位于日本某博物馆附近
再通过google earth查看近景图,找到附近停车场的信息,找到flag
ft8
题目给出一段循环播放的音频,猜测是音频内容中隐藏信息
根据题目WebSDR - FT8,搜索tf8了解到
FT8是一种专为业余无线电台之间进行快速、准确通信而设计的数字协议,尤其在弱信号条件下表现出色。FT8协议只占用50Hz的带宽,可以解码人耳难以辨别的微弱信号。即使在高楼林立的社区,使用普通的手持天线也可以与欧洲等地进行通信。
再查询ft8解码的工具,使用jtdx进行解码,得到flag
ZipZip
通过WinRAR解压时发现提示信息L3HSEC??????L3HSEC,猜测可能为解码的口令
使用achpr工具尝试强行爆破失败后,利用L3HSEC??????L3HSEC作为掩码进行掩码攻击,
最后在范围为(0-9)之间时成功恢复口令
利用口令打开ZipZip压缩包,里面包含gift.zip和secret.zip两个压缩包,且都需要密钥才能解开
观察到两个压缩包内容相似,且secret.zip内多一个secret.txt文件,猜测flag藏于其中
再次尝试强行爆破secret.zip失败后,考虑到gift.zip可能有有用信息,于是对gitf.zip采用明文攻击,最终得到口令,成功打开secret.zip压缩包
观察secret.txt文件猜测为JSFuck编码
使用在线工具进行JSFuck解码,观察解码猜测为摩斯密码
使用在线工具进行摩斯密码解码后得到与flag高度相似的字符串
最后猜测 flag为L3HSEC{WOW_U@RE_FUCKING_SM4RT!}
你知道Blockchain嘛?
搜索关键词Blockchain得到这是一道区块链的题目,参考bilibili上相关视频
- ncat 119.8.106.225 20000连接服务器
根据选项提示做出决策
首先选择1,题目会给出部署账户(deployer account)和标志身份的信息(token),要求向该账户转入0.001测试币 连接以太坊结点,初始化账户信息
1
2
3
4
5
6
7
8
9
10
11
12from web3 import Web3
from eth_account import Account
# 连接到以太坊节点
infura_url = "http://119.8.106.225:8545"
w3 = Web3(Web3.HTTPProvider(infura_url))
# 生成一个新的账户
account = Account.create()
# 打印账户地址、私钥和公钥
print(f"地址: {account.address}")
print(f"私钥: {account.key.hex()}")使用生成的地址在题目提供的水龙头领取测试币
将自己账户的测试币转移一部分到部署账户完成交易
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# 进行交易
from web3 import Web3
# 连接到 RPC 地址
rpc_url = "http://119.8.106.225:8545"
w3 = Web3(Web3.HTTPProvider(rpc_url))
# 你的测试钱包地址和私钥
eth_address = "0xd506f9E66bD092248Ea48c3709f4Db9A57AFF67e"
private_key = "e899bd263df411b26cff19aec59d4df1b050d47a231c2e774b090142b6076b9c"
# 目标部署账户(deployer account)
deployer_address = "0x6870802A4a17D1D88Dd825ED40f95bb1C9e9D33C"
# 获取链 ID
chain_id = w3.eth.chain_id
# 构建交易
tx = {
'nonce': w3.eth.get_transaction_count(eth_address),
'to': deployer_address,
'value': w3.to_wei(0.001, 'ether'),
'gas': 25000,
'gasPrice': w3.to_wei('50', 'gwei'),
'chainId': chain_id # 添加链 ID
}
# 使用私钥签名交易
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
# 发送交易
tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction)
print(f"交易已发送,交易哈希: {w3.to_hex(tx_hash)}")
# 等待交易确认
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"交易成功!交易哈希: {w3.to_hex(tx_hash)}")返回命令行,输入2,得到合约地址
选择4,查看contract source code ,通过python脚本向合约地址发起攻击
攻击成功,最后在命令行得到flag
什么?注入?真的假的
- ncat 119.8.106.225 20001连接服务器
根据选项提示做出决策
首先选择1,题目会给出部署账户(deployer account)和标志身份的信息(token),要求向该账户转入0.001测试币 - 连接以太坊结点,初始化账户信息
1
2
3
4
5
6
7
8
9
10
11
12from web3 import Web3
from eth_account import Account
# 连接到以太坊节点
infura_url = "http://119.8.106.225:8546"
w3 = Web3(Web3.HTTPProvider(infura_url))
# 生成一个新的账户
account = Account.create()
# 打印账户地址、私钥和公钥
print(f"地址: {account.address}")
print(f"私钥: {account.key.hex()}") - 使用生成的账户地址去水龙头领取测试币
- 完成交易,获取合约地址
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# 进行交易
from web3 import Web3
# 连接到 RPC 地址
rpc_url = "http://119.8.106.225:8546"
w3 = Web3(Web3.HTTPProvider(rpc_url))
# 你的测试钱包地址和私钥
eth_address = "0x9ca6A53A9b47C04dcbca625d55980D46a97Eef70"
private_key = "d78192d532e5a3bde6a8bfbae6ff7f302c318a1e76a35d1bb4d7c2199cd79843"
# 目标部署账户(deployer account)
deployer_address = "0x03CB80078a336E2e08fF48C3036Fa3FC2d7B3e2d"
# 获取链 ID
chain_id = w3.eth.chain_id
# 构建交易
tx = {
'nonce': w3.eth.get_transaction_count(eth_address),
'to': deployer_address,
'value': w3.to_wei(0.001, 'ether'),
'gas': 25000,
'gasPrice': w3.to_wei('50', 'gwei'),
'chainId': chain_id # 添加链 ID
}
# 使用私钥签名交易
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
# 发送交易
tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction)
print(f"交易已发送,交易哈希: {w3.to_hex(tx_hash)}")
# 等待交易确认
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"交易成功!交易哈希: {w3.to_hex(tx_hash)}") - 查看合约码
发现withdraw 函数中存在重入攻击漏洞
通过递归调用 withdraw 函数,反复提取资金,直到余额变为负数,并超过 1000 Ether 的检查条件,从而解锁 isSolved 状态,获取 flag。
最后在命令行返回flag
1 | from web3 import Web3 |
Web
ezphp
由题意得,flag被切分为两段,前一段要求传入参数为L3HSEC,即可返回前半部分flag,后一段要求传入参数为’我是大牛’,且每次传参字符串的长度不得大于1,才会返回后半部分flag
对于前半段考察变量和变量名的知识,在cmd中输入1
curl https://f4721935-26b6-414f-9a62-791cda2b3c30.ctf.l3hsec.com/challenge.php -d "_=a&a=b&b=L3HSEC
对于后半段考察php中字符串拼接问题,一个中文字符通过URL编码后转换为3个UTF-8编码的字符,将’我是大牛’通过URL编码后,再一个字节一个字节地传递参数,php自动拼接后形成’我是大牛’,巧妙解决了字符串长度不大于1的问题
前后拼接后成功得到flag
Reverse
听说你是pvz高手
题目要求收集10000阳光即可获得flag
使用 Cheat Engine (CEx修改器) 找到程序进程,再尝试扫描当前的阳光数,找到阳光所占有的内存,通过修改内存中阳光数,成功得到flag
Crypto
big_math
RSA加密是一种非对称加密算法
RSA加密使用一对密钥:公钥和私钥。公钥用于加密,私钥用于解密
RSA的安全性基于大数分解的困难性,尤其是大素数乘积的分解问题
RSA加密的基本原理
- 密钥生成
为了生成 RSA 密钥,需要进行以下步骤:
- 选择两个大素数 (p) 和 (q):
- 计算模数 (n):
[
n = p \times q
]
模数 (n) 是 RSA 公钥和私钥的核心部分,用于加密和解密。 - 计算欧拉函数 (\phi(n)):
欧拉函数 (\phi(n)) 是在模 (n) 下的可逆整数个数,对于两个素数 (p) 和 (q),欧拉函数的值为:
[
\phi(n) = (p-1) \times (q-1)
] - 选择公钥指数 (e):
选择一个整数 (e),使得 (1 < e < \phi(n)),并且 (e) 与 (\phi(n)) 互质(即 (\gcd(e, \phi(n)) = 1)) - 计算私钥指数 (d):
私钥指数 (d) 是 (e) 在模 (\phi(n)) 下的逆元,即:
[
e \cdot d \equiv 1 \ (\text{mod} \ \phi(n))
]
这个 (d) 通过扩展欧几里得算法计算得到。
加密过程
加密过程使用公钥进行。假设需要加密的消息为 (m)(消息 (m) 是一个整数,且 (0 \leq m < n)),加密公式为:
[
c = m^e \ (\text{mod} \ n)
]
其中,(c) 是加密后的密文。解密过程
解密过程使用私钥进行。解密时,使用加密得到的密文 (c) 通过私钥进行解密,公式为:
[
m = c^d \ (\text{mod} \ n)
]
解密后得到的 (m) 就是原始消息。
Wiener攻击(Wiener’s Attack)是一种针对RSA加密的攻击方法,专门用于破解当RSA私钥 ( d ) 过小的情况。该攻击由密码学家Michael Wiener在1990年提出。它利用了当私钥 ( d ) 较小时,RSA系统的弱点,能够通过特定的数学技术推导出私钥。
Wiener攻击基本原理
Wiener攻击基于连分数逼近理论。攻击的关键是,当私钥 ( d ) 较小时, ( d ) 和 ( e ) 的比值 ( \frac{d}{n} ) 可以通过连分数逼近的方式很好地近似。通过这一逼近,攻击者可以构造一系列候选的私钥,并验证哪个候选私钥能够破解密文。
分析题意1
2
3
4
5
6
7
8m1=bytes_to_long(flag1)
m2=bytes_to_long(flag2)
p=getPrime(1024)
q=getPrime(1024)
r=getPrime(2048)
t=getPrime(2048)
little_n=p*q
n=p*q*r
m1,m2是由flag1和flag2通过bytes_to_long()函数转换成的两个整数
p,q是长度为1024的素数,r,t是长度为2048的素数
little_n和n是模数
解题思路
利用Wiener攻击破解RSA私钥,在 RSA 私钥 d 较小的情况设计的攻击
代码核心是通过连分数逼近的方法,从公钥指数 e 和模数 n 推导出私钥 d
(说实话,该工作主要是由gpt完成,具体核心算法不太了解,不过通过本题对RSA加密方式的了解更深入了)
python程序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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89little_n = 30088545050765530423805361878416507393996570826628516885551767012032821735759756922346729483075999478740890396740180776286577993631294405655843348355472462014506667147244720307627201462475792283412817218766998118873677473067104176849657311706442634062420091828926853184205920237951862265182484069649756691839691357916405847978176837008745046642748094275030779471750959877986668422253281400626795828963573920393088749591612716695564149666681604429837724976821672947402732999481879540771777938480505225596566416091698577609111167970146033914320439938709937337918464176949019458189405542377412201071336990086704695932001
ciphertext_1 = 4437957888497793411974936231134804097124408727940101262533154501417200692919579880947962548717550593697567354996004074082892093231542300979099686519594863569977498876831765076396347598926115862183073685024990864689988238858428295897918744431202362320291015738417428855920053052479809273411609887264443586795095964728239991625582152693909500018661918195404034412467186049173913167545009955896623699305090180468870302233714242619856378640191118517945701566010541415167017293158989288295521065448608130916732093398678710697626416830318362328907904233236575731454083519911431098911284149955444519573629006045554678324518
ciphertext_2 = 78864561424890770405754552496508735565097767299975292698696817263059870704574252767244750339849821607143039860304278377928922953654619860402709334687968551656512266903178248270944553116215521323821491311662555239829301305000772651190496470417476770564428704238037095240110347750439779101856099345785742200533953669469298415538894433163090058251625858567316364473944123076299230135880825507857770277939412860689895530498381163283821263531273538955506316194191926213707241352871080646562627012054391523644091891727237326335520749063659993188231648389392672191093964160488575369753007731166404854380331830984470657441644838342607582333391874996621339432497442777200974041109474972662502438556188363293907320120566021040878727616875785724243592701260771353665329454661067014678384002070808151070358872996829354884423078897260496009237360165626015366112230594958895261737530922455844000526883743056291880281170954068780564714657040355762723448235762641056698958446508680666476759259974921224980623537386361094690459034558856950725634724109009764690331916406889225273702793795808581259336656477575737512000567280203588771895736081353710119074573273205809318278896389561023955187406736051571629668238556317874245476690747300656637355328544
ciphertext_3 = 5725077557808157256430942740990569460773383369554273823636176153068467454512823763515647291612402009313693931982637385545689576303886538569510933702499950531946332354820616178601187839652301529137964554627475349002312246937622569844740649433856363144796146222393078023525987286341880380785409632776930595126924756112630243882589976085512471897027381156120513087172923236464367405811882805821186710490261430865849118334490795875278968965387483397523573061251371457251882441660955274348488917840958718541709618303915977686144557627966423963471317515192738334921562091927856956424998965161634322201369720699676347561471675582403160973419462033935866447730620497674055205496875933173254400413581110627294132729326146351739721506814065623387296595138287209163676622201909074010014848172929614143034759743549710300854100952625823552353762197591658982169029599443577415788436359487959114564852534141669094849830099267923384043803436255468847172967932193132489983957589359087823645662055626662973824314495580206380101750792194329854822007590502007055850504474332004464704128354176720739742561430179525179333961608814112175164504198485752771156978208909885458371099313162881602617458059925830364899254441195137785150763268195094621953852200244632416635894291988860065011405757906072849175293480722258929900953859011925277272123913190894980729598985883765586084558378588241413809751317207241875249125287708228797477309231958728561077734778094562357805705275014499804452986728418351199125822789541623527033144636672210156626415595121581925193962797953221837338303410442520344309906567427785930338516724325132154448559539663325603906087819156754108336818594141014769273579814708171319748396233538472420596261105167186637071032111004322390242211983548088973696618482839305923027150374824593812983183773570950561602855654815750454908029219010408866049545122018834
public_exponent = 18811481222974302204632511369245433479738399576579288811947420564734925886156221373212611102729084374352339031631477899927769759235983596706326584303784559234972552599160858292029188896706945893473255912259624043253888044638166631707857526128138005829891524522002058110222521260201712077964922139704733672451062605244217266782627035293603650126728378938935853574071346654704141663803944530862726643221123184041746714755826882612203166391535425991832801305277555128091105172486311970004713359202828725505765900730826393253715700856299795299501353800751272345390463568402242244426464603165067636889617647460596431388673
from Crypto.Util.number import *
# Rename the variables for clarity
n = little_n
c = ciphertext_1
# Function to convert a rational number x/y to a continued fraction
def rational_to_contfrac(x, y):
a = x // y
pquotients = [a]
while a * y != x:
x, y = y, x - a * y
a = x // y
pquotients.append(a)
return pquotients
# Function to calculate the convergents from a continued fraction
def convergents_from_contfrac(frac):
convs = []
for i in range(len(frac)):
convs.append(contfrac_to_rational(frac[0:i]))
return convs
# Function to convert a continued fraction back to a rational number
def contfrac_to_rational(frac):
if len(frac) == 0:
return (0, 1)
num = frac[-1]
denom = 1
for _ in range(-2, -len(frac) - 1, -1):
num, denom = frac[_] * num + denom, num
return (num, denom)
# Extended Euclidean Algorithm
def extended_gcd(a, b):
if a == 0:
return (b, 0, 1)
g, x, y = extended_gcd(b % a, a)
return (g, y - (b // a) * x, x)
# Modular inverse function
def mod_inv(a, m):
g, x, _ = extended_gcd(a, m)
return (x + m) % m
# Integer square root function
def isqrt(n):
x = n
y = (x + 1) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x
# Function to crack RSA using Wiener's attack
def crack_rsa(e, n):
frac = rational_to_contfrac(e, n)
convergents = convergents_from_contfrac(frac)
for (k, d) in convergents:
if k != 0 and (e * d - 1) % k == 0:
phi = (e * d - 1) // k
s = n - phi + 1
# Check if x^2 - s*x + n = 0 has integer roots
D = s * s - 4 * n
if D >= 0:
sq = isqrt(D)
if sq * sq == D and (s + sq) % 2 == 0:
return d
# Crack the private key
private_exponent = crack_rsa(public_exponent, n)
decrypted_message = pow(c, private_exponent, n)
# Now use the second and third ciphertexts to decrypt further messages
private_key_1 = inverse(public_exponent, decrypted_message - 1)
message_1 = pow(ciphertext_2, private_key_1, decrypted_message)
private_key_2 = inverse(65537, decrypted_message - 1)
message_2 = pow(ciphertext_3, private_key_2, decrypted_message)
# Output the result of the decryption
print(long_to_bytes(message_2))
ezCMA
1 | m1 = bytes_to_long(bytes(flag.encode())) |
分析题目
m1是由flag转换得到的整数,p,q是两个长度为1024的素数,n是模数
其中有一个明显的特点是flag1、flag2、flag3是由 同一个明文(m1) 通过不同的指数e1、e2、e3和相同的模数n生成的,由此联想到共模攻击解出密文
且指数e1、e2、e3之间存在巧妙的联系
- e1 = 993627907847 * 1016231455597
- e2 = 1016231455597 * 902914473557
- e3 = 993627907847 * 902914473557
共模攻击(Common Modulus Attack)是RSA加密中的一种攻击方式,发生在多个用户使用相同的模数 ( n ) 但有不同的公钥 ( e ) 时。由于RSA的安全性依赖于模数 ( n ) 的唯一性,如果两个或多个用户共享相同的模数,而使用不同的公钥,则会使系统容易受到这种攻击。
共模攻击的基本原理
假设有两个用户,Alice 和 Bob,他们的RSA模数 ( n ) 相同,但公钥不同,分别为 ( e_1 ) 和 ( e_2 )。攻击者假设 Alice 和 Bob 都用各自的公钥加密了相同的明文消息 ( m ),得到密文 ( c_1 = m^{e_1} \pmod{n} ) 和 ( c_2 = m^{e_2} \pmod{n} )。
因为 ( c_1 ) 和 ( c_2 ) 都是相同的明文 ( m ) 的幂,且已知 ( e_1 )、( e_2 ) 和 ( n ),攻击者可以通过以下步骤解密消息:
计算扩展欧几里得算法:通过扩展欧几里得算法找到两个整数 ( a ) 和 ( b ),使得 ( a \times e_1 + b \times e_2 = 1 )。
利用 ( a ) 和 ( b ) 构造明文:
- 因为 ( m^{e_1} \equiv c_1 \pmod{n} ) 和 ( m^{e_2} \equiv c_2 \pmod{n} ),可以利用 ( a ) 和 ( b ) 的线性组合得到:
[
m = c_1^a \times c_2^b \pmod{n}
] - 这样就能通过计算复原原始的明文 ( m )。
- 因为 ( m^{e_1} \equiv c_1 \pmod{n} ) 和 ( m^{e_2} \equiv c_2 \pmod{n} ),可以利用 ( a ) 和 ( b ) 的线性组合得到:
整体思想
通过给定的三个加密密文 flag1、flag2 和 flag3,以及与每个密文相关的指数 e1、e2 和 e3,来解密出原始消息 m
- 对 e1 和 e2 进行整除运算,将 e1 和 e2 转化为较小的指数
e1=1009755935113158588369659//1016231455597
e2=917570089742429076148529//1016231455597 - 通过中国剩余定理计算 m1
将 flag1 和 flag2 的幂次分别由 x 和 y 进行组合,得到 m1,即:
m1=pow(c1,x,n)pow(c2,y,n)%n
这是通过扩展欧几里得算法求出 x 和 y(满足 e1x + e2*y = gcd(e1, e2))来完成的 对 e1 和 e3 进行整除运算,将 e1 和 e3 转化为较小的指数
通过与 m1 类似的步骤,使用中国剩余定理计算出 m2,即 m^993627907847 的解。
使用最后的 1016231455597 和 993627907847 作为指数,并使用中国剩余定理和扩展欧几里得算法求出 m
m=pow(m1,x2,n)*pow(m2,y2,n)%n
python程序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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53flag1= 8474478534133750496351258439770439219153979952561642731581390416228867640587693486357078135921546443963283105927150253272336059382390513817706698741025531526550326710611170554397057390714665263299882969421138898580414905289818079694175809121588275768717653289810969178070603654027459939946312773093941446287417784032902650734437554613303784830203578240545070093473942475651339619315817364422284273133164774638578085796267096957347085168021778125470616046598013171354398170377063192357733840050955181584705301456304877682550520037398962644014863486620415201523880999542686731895448726980398631515217315286020437688498
flag2= 3351384523931867313334817228598784440559751009017798910409840467537119821259012274549685345550490291816260612536289106819125192140760817375064269268775476031424892776272822066072079425305661428795671314658531045416112945555811194297108918942072330688307026110408024089214342917098967614776154381488672421957083146560757683623642006092146862507588998409298919637353660377267802188093929938573350202326786505140838600085071746441060977159281922113489848540031614769737591885173161155206855583607310005623436257762906278289722207498226001933784659324565536246902660945534285429590539413563048095506554626251616237676085
flag3= 5985698167580292228103775342057124425925837097208523314550523309415437277838160594697403652576181505738376124206117744930374928505854417093291293722474344968937532770265145298388658073650787591858476178872911073027696260914967170228919432784475518233719515218760252671051270000581279546881292735906936176213503922783551190771955716934727562595180860790040848587585167859997365531513159440802207174497260444085610261175085531334936547028947562016756271409639098566910202260260565739379965380545050237791613249984011652443416356033660746709478575412073746217796066838355640159345205738259110105894918059407651872299890
e1= 1009755935113158588369659
e2= 917570089742429076148529
e3= 897161019325217314301779
n= 11295998674923997915943754979924400482910956167036135115104616066253068788768361485681020525394574700945440467310782667910252047979768627604509086553949220752907396584699810630157139575845491574958788530608310999859562983302417094883322550125648741172503117372394024013743440114452080863483618324236843484216327589328115588675048041658149492207605113019716406368620938899561099206060294485156146873711072426006320715336473956395729172889050029370044109346990187611892568329248392149357401050824185160821078105634351600311316865993926248187857295191981143425250483512228653210803684450509179107949521855027236290889869
from gmpy2 import *
from gmpy2 import gcdext, iroot
from Crypto.Util.number import long_to_bytes
# 新的公钥指数和密文名称
exp1 = 1009755935113158588369659 // 1016231455597
exp2 = 917570089742429076148529 // 1016231455597
cipher1 = flag1
cipher2 = flag2
# 使用扩展欧几里得算法计算 exp1 和 exp2 的最大公约数 gcd,以及贝祖系数 x 和 y
# gcd 是 exp1 和 exp2 的最大公约数,x 和 y 是贝祖系数,使得 gcd = exp1 * x + exp2 * y
gcd1, coeff_x1, coeff_y1 = gcdext(exp1, exp2)
# 解出 intermediate_m1,即 cipher1^x * cipher2^y mod n
# intermediate_m1 相当于 m 的 1016231455597 次幂模 n 的结果
intermediate_m1 = pow(cipher1, coeff_x1, n) * pow(cipher2, coeff_y1, n) % n
# 第二组公钥指数
exp3 = 1009755935113158588369659 // 993627907847
exp4 = 897161019325217314301779 // 993627907847
# 使用扩展欧几里得算法计算 exp3 和 exp4 的最大公约数 gcd2,以及贝祖系数 x2 和 y2
# gcd2 是 exp3 和 exp4 的最大公约数,x2 和 y2 是贝祖系数,使得 gcd2 = exp3 * x2 + exp4 * y2
gcd2, coeff_x2, coeff_y2 = gcdext(exp3, exp4)
# 解出 intermediate_m2,即 cipher1^x2 * flag3^y2 mod n
# intermediate_m2 相当于 m 的 993627907847 次幂模 n 的结果
intermediate_m2 = pow(cipher1, coeff_x2, n) * pow(flag3, coeff_y2, n) % n
# 用于组合两个解密结果的公钥指数
exp_final1 = 1016231455597 # 原来的 eee1
exp_final2 = 993627907847 # 原来的 eee2
# 使用扩展欧几里得算法计算 exp_final1 和 exp_final2 的最大公约数 gcd_final,以及贝祖系数 x_final 和 y_final
# gcd_final 是 exp_final1 和 exp_final2 的最大公约数,x_final 和 y_final 是贝祖系数,使得 gcd_final = exp_final1 * x_final + exp_final2 * y_final
gcd_final, coeff_x_final, coeff_y_final = gcdext(exp_final1, exp_final2)
# 最终解密结果,将 intermediate_m1 和 intermediate_m2 的组合计算得到明文 m
# 这里解密过程使用了 m1 和 m2 的贝祖组合,通过 m1^x_final * m2^y_final mod n 得到 m
final_message = pow(intermediate_m1, coeff_x_final, n) * pow(intermediate_m2, coeff_y_final, n) % n
# 将解密后的整数转换为字符串形式的明文
print(long_to_bytes(final_message))
后记
我问天
天无言
我问佛
佛言自渡有缘人
我:“大师,这开门吗”
大师:“东西是好的,就是不够老”
我:“大师,那怎么办呢”
大师:“下去沉淀吧”