Description
What if d
is too small? Connect with nc mercury.picoctf.net 58978
.
🎯 Challenge Overview
🧩 You connect to a remote service with netcat
and are presented with an RSA encryption challenge. You are given the RSA public parameters (e
, n
) and a ciphertext c
. Because e
is unusually large and the key is vulnerable, you can solve it with a Wiener attack to recover the private exponent d
, decrypt c
, and reveal the flag.
🔧 Step 1 — Connect to the service (netcat)
💬 Command / Action:
$ nc mercury.picoctf.net 36463
📌 What happens:
The service prints the RSA parameters e
, n
, and the ciphertext c
.
💡 Explanation:nc
(netcat) opens a TCP connection to the host and port. It prints the server’s output. You now have the public key and ciphertext needed to attempt cryptanalysis.
🧠 Step 2 — Identify vulnerability (large e
)
💬 Observation:e
is extremely large. For some RSA keypairs where the private exponent d
is relatively small, Wiener’s attack can recover d
from (e, n)
.
💡 Explanation:
Wiener’s attack works when d
is small compared to n
. Many CTF challenges intentionally use this vulnerability to teach cryptanalysis. If d
is small enough, continued fraction approximations can efficiently find it.
💻 Step 3 — Write Python script to perform the attack
📝 Script:
import owiener def long_to_bytes(x: int) -> bytes: return x.to_bytes((x.bit_length() + 7) // 8, 'big') def main(): e = <large number> n = <large number> c = <large number> d = owiener.attack(e, n) print('d =', d) m = pow(c, d, n) flag = long_to_bytes(m).decode() print(flag) if __name__ == '__main__': main()
💡 Explanation:
The script calls owiener.attack(e, n)
to obtain d
. Then it computes m = c^d mod n
(RSA decryption) and converts the resulting integer to bytes to read the flag text.
📦 Step 4 — Install / obtain owiener
library
💬 Attempted command:
pip install owiener
⚠️ Problem:
Failed to install via pip
.
✅ Workaround:
curl -O https://raw.githubusercontent.com/orisano/owiener/master/owiener.py
💡 Explanation:
When pip
fails, downloading the Python module directly allows you to import it locally. This is a practical CTF workaround.
🚩 Step 5 — Run Python script to get the flag
💬 Command:
python script.py
💡 Explanation:
The script performs the Wiener attack, decrypts the ciphertext, and prints the flag.
🏳️🌈 Capture the Flag
🎉 Flag:
picoCTF{proving_wiener_2635457}
📋 Summary
Step | Command / Action | Purpose | Key Result |
---|---|---|---|
1 | nc mercury.picoctf.net 36463 | Fetch RSA parameters e , n , c | Received e , n , c |
2 | Analyze e | Recognize vulnerability | Wiener attack applicable |
3 | Python script using owiener.attack | Recover d and decrypt c | Decrypted message → readable flag |
4 | pip install owiener (failed) → curl -O .../owiener.py | Obtain owiener implementation | owiener available locally |
5 | python script.py | Execute attack | picoCTF{proving_wiener_2635457} |
🌱 Beginner Tips
- 🧾 Copy
e
,n
, andc
exactly; one digit error breaks everything. - 🛠 If
pip install
fails, download the module source directly. - 🔐 Recognize common RSA vulnerabilities: small
d
, low exponente
, common modulus. - 🧪 Test scripts locally on small RSA examples before using challenge values.
📚 What you learn (takeaways)
- 🔍 How to fetch RSA parameters using
netcat
. - 🛡 When Wiener’s attack is applicable and how it works.
- 💻 Using
owiener
to recoverd
. - 🔑 Decrypting RSA ciphertext using modular exponentiation.
- 🧰 Workarounds for Python package installation issues.
🧾 Short explanations for commands / techniques used
- 💬
nc host port
— Opens TCP connection to server; prints output. - 🔢
e, n, c
— RSA public exponent, modulus, ciphertext. - 🕵️♂️ Wiener’s attack — Recovers
d
if it is small relative ton
. - 📦
pip install owiener
— Installs theowiener
Python package. - 🌐
curl -O <url>
— Downloads file from URL to current directory. - 🐍
import owiener
/owiener.attack(e, n)
— Recovers private keyd
. - ⚡
pow(c, d, n)
— Efficient modular exponentiation; decrypts RSA ciphertext. - 🧩
to_bytes((x.bit_length()+7)//8, 'big')
— Converts integer to bytes for readable output.