Exploiting Exposed Encryption Keys in Web Applications

Rushikesh PatilRushikesh Patil
5 min read

Introduction:

During a recent penetration testing engagement, I identified a critical security issue: exposed encryption keys in a web application's client-side JavaScript. This vulnerability is particularly severe as it enables attackers to decrypt and potentially modify encrypted data communicated between the client and the server, such as requests and responses. This could lead to unauthorized access and manipulation of sensitive information, including the ability to bypass security mechanisms such as One-Time Password (OTP) verification.

Most people would identify hardcoded encryption and decryption keys in JavaScript files and report them as such without further exploration. They typically do not attempt to decrypt the encrypted payloads, potentially missing critical insights into the severity of the vulnerability. If you're not familiar with writing custom code to demonstrate the exploit like me ;), you can use tools like ChatGPT. Make sure to replace any actual keys with dummy keys before sharing your findings, ensuring that your client's keys do not get disclosed in real time. This approach not only highlights the vulnerability but also emphasizes the potential impact, providing a complete picture of the security risk involved.

Due to confidentiality constraints, I cannot display the original Proof of Concept (POC) used during the engagement. However, to help the cybersecurity community understand and address such vulnerabilities, I have re-created a similar environment in a lab setting. This setup mimics the original issue, allowing me to demonstrate how attackers could exploit the exposed encryption key to decrypt encrypted requests and responses. This demonstration is intended to underline the importance of secure cryptographic practices and highlight effective strategies for protecting web applications from similar vulnerabilities.

Identifying the Misconfiguration:

  1. While examining the client-side javascript code during routine testing, I identified that the encryption key was hardcoded within the JavaScript file, openly accessible to anyone who views the source code. This discovery was significant because it meant that any encrypted data sent from the server could potentially be decrypted by an unauthorized user with access to this key.

  2. By analyzing the JavaScript code, we can exploit its encryption process, which utilizes a hardcoded key. This presents an opportunity for further exploitation.

  3. As you can see when I enter the mobile number and verify the OTP, the request and response are sent in an encrypted form.

    sent-otp

  4. Now that we've identified the key for encryption and decryption, we can instruct ChatGPT to write the code for decrypting and re-encrypting the modified payload. Before proceeding, paste the JavaScript code into ChatGPT for analysis.

  5. We can direct ChatGPT to generate the code for decrypting the payload and then re-encrypting it. (You can get creative in your way)

  6. Save the provided code in a .html file.

OTP Bypass: Let's simulate how I have bypassed the OTP

  1. Entered wrong OTP and captured request in burp suite. (In my lab environment I have set "000000" static OTP for demonstration purposes)

  2. Right-click > Do Intercept > Response to this request

    As you can see the response is encrypted.

  3. Copy the encrypted payload and paste it into our decryptor.

    Here you can see we have got a response as false. We will modify it true re-encrypt it and paste it into our burp.

  4. As you can see OTP is bypassed.

During my pentest, I discovered 4-5 JSON parameters in response that required modification. Each parameter needs to be changed from false to true, 0 to 1, and so forth.
The OTP bypass vulnerability I found due to two main issues:

  1. Weak Encryption Logic: The encryption logic used to secure the OTP during transmission is not robust enough, making it susceptible to decryption attacks. It's crucial to use strong encryption algorithms and securely manage encryption keys to prevent unauthorized access to sensitive data.

  2. Lack of Server-Side Validation: The server blindly accepts the decrypted OTP without performing any validation checks, such as verifying its authenticity or ensuring it hasn't expired. Server-side validation is essential to verify the integrity and validity of the OTP before granting access or performing sensitive operations.

Remediation:

  1. Implement Strong Encryption Logic:

    • Use industry-standard cryptographic algorithms like RSA for asymmetric encryption.

    • Ensure proper key length and key generation methods to withstand brute-force attacks.

    • Follow best practices for encryption, such as using padding schemes like OAEP (Optimal Asymmetric Encryption Padding) to enhance security.

    • Regularly update cryptographic libraries and algorithms to mitigate known vulnerabilities.

  2. Implement Encryption with RSA & AES for Larger data sets:

    • Generate three random strings: Passphrase, IV, and Salt.

    • Create an AES key using the three random strings.

    • Encrypt the data using the AES key (encdata).

    • Encrypt the three random strings with the server's public key using the RSA algorithm (enckeys).

    • Send the encrypted data and encrypted keys to the server.

    • Receive the encrypted data (encdata) and encrypted keys (enckeys).

    • Decrypt the encrypted keys using the server's private key.

    • Generate the AES keys using the decrypted keys (Passphrase, IV, Salt).

    • Decrypt the encdata using the AES keys.

    • Process the data.

    • Encrypt the response with the same AES keys used for encrypting the request (encRes).

    • Send the response to the client.

    • Receive the encrypted response (encRes).

    • Decrypt the response with the same AES keys (Passphrase, IV, Salt).

    • Process the data and display it to the user.

  3. Enforce Server-Side Validation for OTP:

    • Implement server-side validation to verify the correctness and authenticity of OTPs.

    • Validate OTPs against a trusted source, such as a secure database or authentication server.

    • Implement rate limiting and other security measures to prevent brute-force attacks and OTP guessing.

    • Consider using multi-factor authentication (MFA) to add a layer of security beyond OTPs.

References:

Lab Setup:

https://github.com/rushikeshhh-patil/OTP-Bypass

10
Subscribe to my newsletter

Read articles from Rushikesh Patil directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rushikesh Patil
Rushikesh Patil

Cyber Security Enthusiast