CVE-2019-5591 has a selected CVSS score of 6.5 (medium); EIP currently links 1 repository PoC, 1 Nuclei template, and 1 lab environment. CISA lists CVE-2019-5591 in KEV; VulnCheck reports CVE-2019-5591 use in known ransomware campaigns.
Description
A Default Configuration vulnerability in FortiOS may allow an unauthenticated attacker on the same subnet to intercept sensitive information by impersonating the LDAP server.
A Python-based LDAP honeypot server that impersonates a legitimate LDAP server to intercept credentials from a vulnerable FortiOS device via a Man-in-the-Middle (MITM) attack. It parses LDAP BIND requests to extract usernames and passwords, and attempts to exfiltrate captured credentials by making an HTTP GET request to a URL derived from the captured password.
Backdoor review
Suspicious behavior
The PoC for CVE-2019-5591 is a local LDAP honeypot server that captures credentials from a FortiGate device. The primary behavior is disclosed. However, the server contains an automatic, unconditional outbound GET request to the captured password string, which is treated as a URL. This behavior is not disclosed in the README and is materially misrepresented as a simple credential capture. It silently exfiltrates the captured credential to an external, attacker-controlled destination embedded in the credential itself, which is a deceptive and harmful action against the operator.
The artifact contains a fully functional LDAP honeypot server (ldap_honeypot.py) designed to actively intercept and exfiltrate credentials from a vulnerable FortiOS device. The README explicitly describes it as a 'Proof of Concept (PoC) demonstrates a MITM (Man-In-The-Middle) Attack: impersonation of an LDAP server' and includes a log showing captured credentials. The code goes beyond detection by extracting passwords and attempting to send them to an external URL, which constitutes exploitation.
README.md:3-4ldap_honeypot.py:250-276
Requirements
Attacker must be on the same subnet as the vulnerable FortiGate device to intercept LDAP traffic.README.md:3-4
The target FortiGate must be running a vulnerable version of FortiOS (6.0.3 through 6.2.0) with default LDAP configuration that does not verify server identity.README.md:8-13
Observed behavior
Starts an LDAP server on port 389 to accept connections from the target.ldap_honeypot.py:321-332
Parses incoming LDAP BIND requests to extract the DN and password.ldap_honeypot.py:84-122
Captures the password from the second BIND request (request #3) and attempts to exfiltrate it by making an HTTP GET request to a URL derived from the password string.ldap_honeypot.py:250-276
Responds to LDAP SEARCH requests with a success result to maintain the illusion of a legitimate LDAP server.ldap_honeypot.py:283-302
Safety-review evidence
Behaviors behind the backdoor verdict
Flagged behaviors
Concealed Exfiltration
The ldap_honeypot.py server automatically makes an outbound GET request to the captured password string, treating it as a URL. This behavior is not disclosed in the README or the script's docstring, which only mention logging captured credentials. The README example shows a password containing an oast.pro domain, indicating the captured credential is designed to be a callback URL, enabling silent exfiltration of the exploit results to an external server without the operator's knowledge or consent.ldap_honeypot.py:255-276README.md:44-50
Observables
Url
Payload withheldExample captured password from README that is automatically fetched by the server, demonstrating the exfiltration mechanism.README.md:45ldap_honeypot.py:265
Behavior
Payload withheldThe server unconditionally performs an HTTP GET request to the captured password, which is a deceptive exfiltration mechanism not disclosed to the operator.ldap_honeypot.py:255-276
Review boundaries
What the analysis did not establish
One file (add_fortigate_user.ldif) is omitted from the evidence, but its content is not required for classification as the exploit logic is fully present in ldap_honeypot.py.
The evidence does not include the actual network interception mechanism (e.g., ARP spoofing) required to redirect traffic; the honeypot assumes traffic is already directed to it.
The review is based solely on the provided text files. The binary file (add_fortigate_user.ldif) was not inspected, but its content is not expected to alter the verdict given the clear exfiltration behavior in the Python script.
The actual reachability or ownership of the oast.pro domain is not verified, but the mechanism itself is the concern.
Model interpretation
This review is limited to the supplied PoC code and context. It does not assert that the code works or is safe to execute.
Docker lab environments
1
SourceLocationAnalysisLinkedEnvironment
GitHub
Repository root
ayewo/fortios-ldap-mitm-poc-CVE-2019-5591Created Model review verdict: Suspicious behavior.Vuln labCVE-2019-5591Dockerfile
A Dockerized LDAP server based on Ubuntu Noble, pre-configured with a static domain and admin credentials, intended to act as a honeypot for demonstrating CVE-2019-5591 (FortiOS LDAP MITM credential interception). A separate Python script implements the honeypot listener.
The README explicitly states this is a Proof of Concept (PoC) for CVE-2019-5591, demonstrating a MITM attack on FortiOS LDAP. The Dockerfile builds a target LDAP server, and the Python script implements a honeypot to capture credentials, matching the described exercise.
A Docker container built from gns3/ubuntu:noble, running slapd with a pre-configured domain (dc=example,dc=com) and admin credentials. It exposes ports 389 and 636, copies an LDIF file to add a FortiGate user, and starts slapd via a startup script.
Dockerfile:1-74
LDAP Honeypot Script
MITM honeypotCredential interceptor
A Python script that listens on port 389, parses LDAP BIND and SEARCH requests, logs captured credentials, and attempts an HTTP GET request to any captured password that resembles a URL. It is designed to impersonate an LDAP server and exfiltrate credentials as described in the CVE-2019-5591 PoC.
ldap_honeypot.py:1-345
CVE assessment
How the supplied evidence relates each vulnerability
The README describes a MITM attack exploiting missing LDAP server identity checks in FortiOS 6.0.x-6.2.0, which matches the CVE description. The Dockerfile and honeypot script provide the components to demonstrate this attack.
README.md:1-5README.md:72-76
Exercise context
Requirements and sequence described by the evidence
Prerequisites
A FortiGate device running a vulnerable FortiOS version (6.0.3 through 6.2.0) configured to use LDAP authentication.README.md:5README.md:13-16
The attacker must be positioned on the same local subnet as the FortiGate device to perform the MITM attack.README.md:3
The LDAP honeypot script must be run on a machine that can intercept traffic intended for the legitimate LDAP server (e.g., via ARP spoofing).ldap_honeypot.py:1-345
Evidence-described exercise path
Build the Docker image for the LDAP server using the provided Dockerfile.Dockerfile:1-74
Run the LDAP server container, which starts slapd and adds a FortiGate user from the LDIF file.Dockerfile:48-73
Execute the LDAP honeypot script (ldap_honeypot.py) on the attacker's machine to listen for LDAP connections.ldap_honeypot.py:310-345
Perform a MITM attack (e.g., ARP spoofing) to redirect the FortiGate's LDAP traffic to the honeypot.README.md:3
Observe the honeypot capturing the FortiGate's LDAP BIND credentials, including the password, and optionally triggering an outbound HTTP request if the password resembles a URL.README.md:18-70ldap_honeypot.py:220-260
Safety-review evidence
Behaviors behind the stored safety assessment
Suspicious behavior
The honeypot script automatically performs an HTTP GET request to a URL constructed from the captured password, using a hardcoded external service (oast.pro) in the README example. This outbound call is not directed at the lab's own target but at an external, operator-uncontrolled domain, and it occurs automatically upon credential capture without explicit operator consent. This behavior is materially unrelated to the stated exercise and reaches external systems.
ldap_honeypot.py:240-260README.md:44-50
Indicators requiring review
The honeypot script automatically performs an HTTP GET request to a URL derived from the captured password, targeting an external domain (e.g., oast.pro) without operator interaction. This is an unexplained outbound call to a third-party service.ldap_honeypot.py:240-260README.md:44-50
Review boundaries
What the analysis did not establish
The Dockerfile references a local file 'add_fortigate_user.ldif' which is not included in the evidence packet, so its contents are unknown.
The .gitignore file is present in the file inventory but its content is not provided, though it is unlikely to affect the analysis.
The packet does not include any Compose file or instructions for running the honeypot alongside the LDAP server, leaving the exact network setup unspecified.
Model interpretation
This review is limited to the supplied lab evidence packet. It does not assert that the environment runs, reproduces a vulnerability, or is safe to execute. Contract: eip-docker-lab-analysis-v1.
The FortiGate LDAP configuration was detected to be insecure due to missing ca-cert, secure LDAPS, or server-identity-check, potentially exposing LDAP communications to credential interception or man-in-the-middle attacks under specific network conditions.
Impact
Unauthenticated attackers can intercept sensitive information by impersonating LDAP servers within the same subnet.
Remediation
Configure LDAP server settings properly and disable default configurations; update to the latest firmware version.