🎯 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, andcexactly; one digit error breaks everything. - 🛠 If
pip installfails, 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
owienerto 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
dif it is small relative ton. - 📦
pip install owiener— Installs theowienerPython 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.

Leave a Reply