Breaking Crypto the Simple Way - TryHackMe Writeup
**Breaking Crypto the Simple Way** - TryHackMe Writeup
#Task 1 | Introduction
##Overview
Cryptography is designed to protect sensitive data, but it's only effective when implemented correctly. Even small mistakes in how cryptographic systems are set up can open the door for attackers. These mistakes are surprisingly common and often become "quick wins" during penetration testing or real-world attacks.
For example, using a weak encryption key or a predictable random number generator can make encryption easier to break. Similarly, exposing secrets like API keys in client-side code gives attackers everything they need to bypass cryptographic protections. The key takeaway here is that it's not always the algorithm itself that's flawed—it's how it's used.
##Learning Objectives
By the end of this room, you will:
- >Understand why cryptographic mistakes occur and their impact on security
- >Recognize and exploit vulnerabilities like weak encryption keys and poorly configured algorithms
- >Learn how to identify and exploit issues like exposed keys
- >Understand how to secure cryptographic systems by avoiding these mistakes
##Initial Setup
Before starting the room, add the target machine to your hosts file:
echo "10.49.188.155 bcts.thm" >> /etc/hostsThis ensures that when you navigate to
, your system resolves it to the correct IP address.bcts.thm
#Task 2 | Brute-forcing Keys
##Challenge Overview
In this task, we'll explore how weak RSA key generation can lead to vulnerabilities. RSA encryption relies on the mathematical difficulty of factoring large numbers, but when keys are poorly generated, this security assumption breaks down.
Question: What is the flag?
Answer:
THM{Psssss_4nd_Qsssssss}
##Understanding RSA Mathematics
RSA encryption, named after its inventors Rivest, Shamir, and Adleman, is based on the difficulty of factoring large numbers.
###Public Key Components
A public key consists of:
- >n = p × q: The product of two large prime numbers,
andpq - >e: A small public exponent (commonly
)e = 65537
###Private Key Components
The private key is derived from:
- >φ(n) = (p - 1) × (q - 1): Where φ is Euler's totient function
- >d: The modular inverse of
moduloe
, satisfyingφ(n)e × d ≡ 1 (mod φ(n))
###Security Assumption
The security of RSA depends on the difficulty of factoring
into its prime componentsn
andp
. However, ifq
orp
is poorly generated or shared across keys, this foundational assumption breaks down.q
##Exercise: Breaking Weak RSA
###Challenge Details
Using the provided
,c
, andn
values, which are crucial components of the RSA encryption process, we need to recover the hidden plaintext. The challenge assumese
is a product of two weakly generated primesn
andp
.q
Given Values:
- >Public Key (n):
43941819371451617899582143885098799360907134939870946637129466519309346255747 - >Exponent (e):
65537 - >Ciphertext (c):
9002431156311360251224219512084136121048022631163334079215596223698721862766
Your task is to recover the plaintext by factoring
and deriving the private key.n
###Step 1: Factoring the Modulus
Since
is the product of two large primes (n
andp
), factorization is the first step. Modern factoring tools, like MSIEVE or YAFU, can be used for this purpose. However, for educational purposes, you can use Python and a library likeq
.sympy
Note: This computation takes a lot of processing power, so if you are using the AttackBox, we strongly recommend that you skip this step and follow along.
Here's the Python code to factor
inton
andp
:q
from sympy import factorint
from Crypto.Util.number import inverse, long_to_bytes
# Given values
n = 43941819371451617899582143885098799360907134939870946637129466519309346255747
# Factor n
factors = factorint(n)
p, q = factors.keys()
print("Prime factors:")
print("p =", p)
print("q =", q)Expected Output: The script will compute:
- >
p = 205237461320000835821812139013267110933 - >
q = 214102333408513040694153189550512987959
###Step 2: Computing φ(n)
Using the two primes, calculate
, where:φ(n)
phi_n = (p - 1) * (q - 1)
print("Phi(n) =", phi_n)###Step 3: Finding the Private Key
The private key exponent
is the modular inverse ofd
moduloe
:φ(n)
from sympy import factorint
from Crypto.Util.number import inverse, long_to_bytes
e = 65537
d = inverse(e, phi_n)
print("Private key (d):", d)###Step 4: Decrypting the Ciphertext
Now that you have
, decrypt the given ciphertextd
:c
c = 9002431156311360251224219512084136121048022631163334079215596223698721862766
plaintext = pow(c, d, n)
flag = long_to_bytes(plaintext)
print(flag.decode())
print("Decrypted Plaintext:", flag)##Key Takeaways from Broadcast RSA
- >Avoid small public exponents like
; instead, use larger values likee = 3e = 65537 - >Ensure encrypted messages are padded with random data (e.g., PKCS#1 or OAEP) to prevent mathematical attacks
- >Use different plaintexts for different recipients to avoid the conditions that make CRT attacks possible
##My Solution
I used the following approach to solve this challenge:
Given:
- >
n = 43941819371451617899582143885098799360907134939870946637129466519309346255747 - >
c = 9002431156311360251224219512084136121048022631163334079215596223698721862766
###Step 1: Factorization
First, I factorized
using FactorDB, an online database of factorized numbers.n

###Step 2: Decryption Script
Then, I recovered the plaintext using this script: solve.py
PS D:\Documents > python3 .\rsa-solve.py
THM{Psssss_4nd_Qsssssss}
Decrypted Plaintext: b'THM{Psssss_4nd_Qsssssss}'Flag:
THM{Psssss_4nd_Qsssssss}
#Task 3 | Breaking Hashes
##Challenge Overview
In this task, we'll explore vulnerabilities in hash-based authentication systems, specifically focusing on HMAC (Hash-based Message Authentication Code) implementations with weak secret keys.
Question: What is the secret used to encrypt the message?
Answer:
sunshine
##Understanding Hashing
Hashing is a cryptographic process that transforms an input (e.g., a password or a message) into a fixed-size string, often called a hash. The transformation is one-way, meaning it's not feasible to reverse the hash to recover the original input.
###Common Uses of Hashing
- >Password Storage: Instead of storing plaintext passwords, systems store their hashes. During login, the input password is hashed and compared to the stored hash.
- >Data Integrity: Hashes verify that data has not been altered during transmission.
- >Message Authentication (HMAC): Hashes combined with a secret key verify that a message hasn't been tampered with.
##Common Vulnerabilities in Hashing
###Weak Hash Algorithms
Older algorithms like MD5 and SHA-1 are considered insecure due to their susceptibility to collisions (two inputs producing the same hash). Attackers can exploit this to craft malicious data with the same hash.
###Lack of Salting
When the same input consistently produces the same hash, attackers can use precomputed databases (rainbow tables) to reverse the hash to its original value. Salting—adding a unique, random value to each input before hashing—prevents this.
###Insecure HMACs
Hash-based Message Authentication Codes (HMACs) rely on a hash function combined with a secret key to ensure message authenticity. Weaknesses arise when:
- >The hash function is insecure
- >The key is short, predictable, or reused
##Challenge: Breaking HMAC-SHA1
###Problem Statement
HMAC (Hash-based Message Authentication Code) is a cryptographic method used to verify the integrity and authenticity of a message. It combines a cryptographic hash function (in this case, SHA-1) with a secret key. If an attacker can determine the secret key, they can forge valid HMACs and manipulate messages.
In this challenge, you are given a message along with its HMAC-SHA1 digest. However, the secret key used for signing is weak. Your objective is to recover the key.
Given:
- >Message:
CanYouGuessMySecret - >SHA1-Digest:
1484c3a5d65a55d70984b4d10b1884bda8876c1d
###Solution Approach
Hashcat is a powerful tool for cracking hashes and HMAC keys. Since we know the format is HMAC-SHA1, we will use mode
. Mode 150 targets HMAC-SHA1 based on Hashcat's documentation.150
###Step 1: Prepare the Hash File
Save the hash and message into a file in the format required by Hashcat:
root@ip-10-49-107-54:~# echo -n "1484c3a5d65a55d70984b4d10b1884bda8876c1d:CanYouGuessMySecret" > digest.txtThe format is:
hash:message
###Step 2: Run Hashcat
Run Hashcat with the RockYou wordlist:
root@ip-10-49-107-54:~# hashcat -a 0 -m 150 digest.txt /usr/share/wordlists/rockyou.txtCommand Breakdown:
- >
: Dictionary attack mode-a 0 - >
: HMAC-SHA1 mode-m 150 - >
: Input file containing the hash and messagedigest.txt - >
: Wordlist to use for brute-forcing/usr/share/wordlists/rockyou.txt
###Step 3: Results
---SNIP---
Dictionary cache building /usr/share/wordlists/rockyou.txt: 33553435 bytes (23.9%)
Dictionary cache building /usr/share/wordlists/rockyou.txt: 67106875 bytes (47.9%)
Dictionary cache building /usr/share/wordlists/rockyou.txt: 100660309 bytes (71.8%)
Dictionary cache building /usr/share/wordlists/rockyou.txt: 134213745 bytes (95.9%)
Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 14 secs
1484c3a5d65a55d70984b4d10b1884bda8876c1d:CanYouGuessMySecret:sunshine
---SNIP--- Secret Key Found:
sunshine
#Task 4 | Exposed Keys
##Understanding the Risk
Exposing cryptographic keys in client-side code is a common yet critical mistake. When keys are included in code that runs in the user's browser (e.g., JavaScript), anyone with access to the application can retrieve and misuse those keys. This defeats the purpose of encryption and authentication, as the attacker gains direct access to the mechanism meant to protect the data.
###Key Risks Include:
- >Unauthorized Access: Exposed keys can be used to decrypt sensitive data or interact with backend APIs as an authenticated user
- >Data Tampering: An attacker can use the keys to generate signed payloads or modify encrypted messages, bypassing integrity checks
- >API Abuse: Hardcoded API keys may allow attackers to access privileged API endpoints without authorization
##Common Scenarios of Key Exposure
###Hardcoded API Keys in JavaScript
Developers often embed API keys in front-end code for convenience, forgetting that anyone can view this code using browser developer tools.
###Encryption Keys in Client-Side Frameworks
Encryption keys are sometimes included in front-end libraries or scripts to encrypt/decrypt data locally. These keys can be easily extracted and used maliciously.
###Unsecured Configuration Files
Configuration files embedded in web applications may contain sensitive credentials or keys in plain text.
##Exercise: Exploiting Exposed Keys
###Step 1: Access the Lab
Navigate to
.http://bcts.thm/labs/lab3

###Step 2: Inspect Network Traffic
Open your developer tools (F12), navigate to the Network tab, and try submitting a message.

Observed Request Payload:
{"data":"EeyfXO1sCHpr1vlhNnOT7w==","iv":"lClWlBpL9B8sbdcl9c/v6A=="}###Step 3: Analyze Client-Side Code
In the source code of the webpage, we can see JavaScript being used for encrypting these values:
<script>
const encryptionKey = CryptoJS.enc.Utf8.parse("1234567890123456"); // 16-byte key
const iv = CryptoJS.lib.WordArray.random(16); // Random 16-byte IV
function encryptMessage(message) {
const encrypted = CryptoJS.AES.encrypt(message, encryptionKey, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return {
ciphertext: encrypted.ciphertext.toString(CryptoJS.enc.Base64),
iv: iv.toString(CryptoJS.enc.Base64),
};
}
document.getElementById("secureForm").addEventListener("submit", async (e) => {
e.preventDefault();
const message = document.getElementById("message").value;
const { ciphertext, iv } = encryptMessage(message);
const response = await fetch("process.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data: ciphertext, iv: iv }),
});
const result = await response.text();
document.getElementById("response").innerText = result;
});
</script>###Step 4: Understanding the Vulnerability
Since the encryption key used to encrypt the message is hardcoded in the JavaScript code (
), it is possible for an attacker to create a script that will brute-force for the correct message using the hardcoded1234567890123456
value.encryptionKey
To simplify this, a wordlist containing the possible messages is available on the server at
.http://bcts.thm/labs/lab3/wordlist.txt
###Step 5: Automating the Attack
However, directly brute-forcing the application will not work since the request is encrypted, so we must automate this using Python.
Here is the Python script that uses the available
on the server.wordlist.txt
###Step 6: Download the Wordlist
root@ip-10-49-107-54:~# wget http://bcts.thm/labs/lab3/wordlist.txt
--2026-01-05 05:44:08-- http://bcts.thm/labs/lab3/wordlist.txt
Resolving bcts.thm (bcts.thm)... 10.49.188.155
Connecting to bcts.thm (bcts.thm)|10.49.188.155|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1423 (1.4K) [text/plain]
Saving to: 'wordlist.txt'
wordlist.txt 100%[===================>] 1.39K --.-KB/s in 0s
2026-01-05 05:44:08 (165 MB/s) - 'wordlist.txt' saved [1423/1423]###Step 7: Execute the Brute-Force Script
root@ip-10-49-107-54:~# python3 bruteforce.py
Trying: jadmxqtideg
Response: Message jadmxqtideg is invalid!
---SNIP---
Trying: wdjdzzsx
Response: Message wdjdzzsx is invalid!
Trying: ankhzljjgu
Response: Access granted! Here's your flag: THM{3nD_2_3nd_is_n0t_c0mpl1c4ted}
[+] Found the correct message: ankhzljjguFlag:
THM{3nD_2_3nd_is_n0t_c0mpl1c4ted}
#Task 5 | Bit Flipping Attacks
##Understanding Unauthenticated Encryption
Unauthenticated encryption refers to encryption that does not include a mechanism to verify the integrity or authenticity of the ciphertext. This means that an attacker can modify encrypted data that is in transit, and the system will still accept and process it without detecting any tampering.
When the application decrypts tampered ciphertext without verifying its integrity, an attacker can manipulate the plaintext in predictable ways. This is the root cause of bit-flipping attacks.
###Example: AES-CBC Vulnerability
A classic example is AES in CBC (Cipher Block Chaining) mode without an authentication tag. AES-CBC encrypts data securely but does not ensure integrity. If an attacker can modify the ciphertext, they can manipulate certain bits of the decrypted plaintext without breaking the encryption.
This leads to bit-flipping attacks, where an attacker changes ciphertext in a way that results in controlled modifications in the plaintext.
##Understanding Bit Flipping Attacks
Bit flipping attacks target systems that use unauthenticated encryption, allowing an attacker to modify ciphertext so that the decrypted plaintext is manipulated in predictable ways. This type of attack is particularly dangerous when systems assume that encrypted data is inherently safe to trust without verifying its integrity.
###How CBC Mode Works
Encryption schemes like AES-CBC (Cipher Block Chaining) are vulnerable to bit flipping when no integrity check, such as a Message Authentication Code (MAC), is applied. In CBC mode:
- >The plaintext is XORed with the previous ciphertext block before encryption
- >If an attacker alters bits in a ciphertext block, it changes the corresponding plaintext block during decryption
###Example Scenario
For example, consider an encrypted payload:
{"role":"0"}If this ciphertext is tampered with, the role could be escalated to
. Without integrity protection, the system would accept the manipulated plaintext as legitimate."1"
##Exercise: Exploiting Bit Flipping
###Step 1: Access the Lab
Navigate to
.http://bcts.thm/labs/lab4/

###Step 2: Understanding the Application Logic
The application accepts any credential as shown in the PHP code below:
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'], $_POST['password'])) {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
$message = "username={$username}";
$role = "0";
$token = encrypt_data($message, $key, $iv);
$token2 = encrypt_data($role, $key, $iv);
setcookie("auth_token", $token, time() + 3600, "/");
setcookie("role", $token2, time() + 3600, "/");
header("Location: dashboard.php");
exit();
}Notice that the
is set torole
(likely representing a guest user) and is encrypted separately."0"
###Step 3: Initial Login
I logged in with
credentials.admin:admin

As expected, the role is set to
, indicating a guest user.0
###Step 4: Performing the Bit Flip Attack
Here's a Python script that will flip the
torole=0
.role=1
Encrypted role token:
b630b852b5a788528a78ecd4059258d011d4a1c60906f1f5dad2aba8e2706f2df4fa44ef27238a330884c90879c8fec3
###Step 5: Execute the Script
root@ip-10-49-107-54:~# python3 flip.py b630b852b5a788528a78ecd4059258d011d4a1c60906f1f5dad2aba8e2706f2df4fa44ef27238a330884c90879c8fec3
[DEBUG] Original IV (First 16 Bytes): b630b852b5a788528a78ecd4059258d0
[DEBUG] Modifying byte at offset 0: 0xb6 XOR 0x1
[DEBUG] Modified IV (First 16 Bytes): b730b852b5a788528a78ecd4059258d0
Modified Token:
b730b852b5a788528a78ecd4059258d011d4a1c60906f1f5dad2aba8e2706f2df4fa44ef27238a330884c90879c8fec3
Use this token as the new 'role' cookie in your browser to log in as admin.
root@ip-10-49-107-54:~# ###Step 6: Update the Cookie and Retrieve the Flag
Update the
cookie value in your browser with the modified token and hit refresh to get the flag.role

Question: What is the flag?
Answer:
THM{flip_n_flip}
#Recap: Key Concepts and Best Practices
##Summary of Cryptographic Mistakes
In this room, we've explored common cryptographic mistakes that developers often make, along with practical demonstrations of how these errors can be exploited. Let's summarize the critical concepts and vulnerabilities you've encountered:
###1. Brute-forcing Keys
Weak or predictable keys, such as those derived from timestamps or short alphanumeric strings, can be cracked using brute-force attacks with tools like Hashcat or John the Ripper.
###2. Breaking Hashes
- >Outdated hash functions like MD5 and SHA-1 are vulnerable to attacks such as collision and preimage attacks
- >Lack of salting enables attackers to use rainbow tables to reverse hashes into plaintext
###3. Keys Exposed in Client-Side Code
- >Hardcoding encryption keys or API secrets in front-end code exposes them to anyone with access to the application
- >This allows attackers to decrypt sensitive data or impersonate users
###4. Bit Flipping Attacks
- >Unauthenticated encryption (e.g., AES-CBC without a MAC) enables attackers to modify ciphertext, resulting in controlled changes to decrypted plaintext
##Best Practices for Avoiding Cryptographic Mistakes
To secure cryptographic implementations and prevent the vulnerabilities explored in this room, follow these best practices:
###Use Strong Keys and Secure Algorithms
- >Generate keys with sufficient entropy and length (e.g., AES-256 for symmetric encryption)
- >Use modern, secure algorithms such as AES-GCM, RSA-2048, and SHA-256
- >Regularly update cryptographic libraries to protect against newly discovered vulnerabilities
###Avoid Exposing Keys in Client-Side Code
- >Never hardcode encryption keys, API secrets, or sensitive credentials in JavaScript or other client-side files
- >Store secrets securely on the server side and use environment variables or key management systems like AWS KMS or Azure Key Vault
###Implement Authenticated Encryption
- >Always pair encryption with integrity checks using authenticated encryption modes like AES-GCM or AES-CCM
- >Ensure that any data transmitted over untrusted channels is encrypted and includes integrity protection
###Secure RSA Implementations
- >Use larger public exponents (
) and ensure that encrypted messages include padding (e.g., OAEP or PKCS#1)e = 65537 - >Avoid encrypting the same plaintext for multiple recipients with the same public exponent
###Educate Developers
- >Ensure that development teams understand secure cryptographic practices and the risks of misconfigurations
- >Conduct regular training and code reviews to identify and fix potential issues before deployment
##Conclusion
This room has demonstrated that cryptographic security is not just about using strong algorithms—it's about implementing them correctly. Common mistakes like weak keys, exposed secrets, and unauthenticated encryption can completely undermine the security of a system. By understanding these vulnerabilities and following best practices, you can help build more secure applications and better protect sensitive data.