Dachshund Attacks picoCTF-Forensics

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

StepCommand / ActionPurposeKey Result
1nc mercury.picoctf.net 36463Fetch RSA parameters e, n, cReceived e, n, c
2Analyze eRecognize vulnerabilityWiener attack applicable
3Python script using owiener.attackRecover d and decrypt cDecrypted message → readable flag
4pip install owiener (failed) → curl -O .../owiener.pyObtain owiener implementationowiener available locally
5python script.pyExecute attackpicoCTF{proving_wiener_2635457}

🌱 Beginner Tips

  • 🧾 Copy e, n, and c exactly; one digit error breaks everything.
  • 🛠 If pip install fails, download the module source directly.
  • 🔐 Recognize common RSA vulnerabilities: small d, low exponent e, 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 recover d.
  • 🔑 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 to n.
  • 📦 pip install owiener — Installs the owiener Python package.
  • 🌐 curl -O <url> — Downloads file from URL to current directory.
  • 🐍 import owiener / owiener.attack(e, n) — Recovers private key d.
  • 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.