← Back to Feed CACHED · 2026-11-01 12:38:45 · CACHE_KEY CVE-2026-120189
CVE-2026-120189 · CWE-119 · Disclosed 2026-11-01

D-Link DIR-505 tftpd save_upload_file stack-based buffer overflow

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

A remote stack smash in a pocket router's file upload daemon

CVE-2026-120189 is a pre-auth stack-based buffer overflow in the TFTP upload filename handler (save_upload_file/mp_upload_file) of the /usr/bin/tftpd binary on D-Link DIR-505 firmware 1.10B02. A remote attacker sends a TFTP WRQ with an oversized filename, smashes the stack, and takes control of the daemon.

D-Link labelled it CRITICAL/10, and mechanically the vector is unauthenticated RCE with public exploit code. But the DIR-505 is a low-cost travel router that has been out of production for years; TFTP is not enabled by default, and the device rarely has a public internet footprint. For an enterprise patching team, real-world exposure is far lower than the CVSS score suggests, so this lands at HIGH.

"Public exploit for a discontinued pocket router's TFTP daemon — root RCE where exposed, but narrow install base knocks CRITICAL down to HIGH."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a DIR-505 with TFTP listening

Attacker scans local or internet-facing UDP/69, or discovers the device via UPnP/SSDP. Stock DIR-505 firmware does not enable TFTP by default; it must be turned on for SharePort/file-sharing functions. An attacker needs a network path to the router—usually LAN, guest Wi-Fi, or a misconfigured port-forward.
Conditions required:
  • TFTP service enabled
  • UDP/69 reachable from attacker
Where this breaks in practice:
  • DIR-505 is discontinued and uncommon in enterprise inventories
  • TFTP is not enabled by default
  • Internet exposure of a travel router is rare
Detection/coverage: Shodan/Censys can find exposed TFTP; enterprise scanners rarely cover SOHO routers
STEP 02

Send an oversized TFTP WRQ filename

The attacker sends a TFTP write request with a filename longer than the stack buffer. save_upload_file/mp_upload_file copies the filename without bounds checking, overwriting the return address on the stack. The overflow is reachable without authentication because TFTP has no auth handshake.
Conditions required:
  • Firmware 1.10B02 or earlier
  • Attacker can send UDP packets to tftpd
Where this breaks in practice:
  • Exact offset may require tuning for this firmware; public exploit may need adaptation
  • TFTP packet size limits can constrain payload size
Detection/coverage: Network IDS can flag anomalous TFTP filename lengths, but coverage is inconsistent
STEP 03

Hijack control flow and execute code as root

The overwritten return address redirects execution to attacker-controlled shellcode placed in the filename or nearby memory. Because embedded tftpd runs as root, the result is a full device compromise.
Conditions required:
  • Reliable payload for MIPS/ARM target
  • No stack canary/ASLR on the device
Where this breaks in practice:
  • Payload staging may be needed due to small packet sizes
  • Post-exploitation persistence requires additional steps in limited flash
Detection/coverage: No endpoint detection on the device; flow logs may show unexpected TFTP traffic
STEP 04

Pivot to connected clients or upstream network

With root on the router, the attacker can intercept DNS, sniff traffic, or use the device as a pivot into an attached LAN. For a travel router, this often means guest devices or a hotel/coffee-shop network, not a corporate domain.
Conditions required:
  • Active clients connected to the router
  • Uplink to a more valuable network
Where this breaks in practice:
  • Travel routers are transient by design; dwell time is limited
  • Enterprise NAC may flag the rogue device or its traffic
Detection/coverage: SIEM can detect DNS anomalies or unexpected device MACs
03 · Compensating Control

1
HIGH 7.5→LOW 2.0
SEVERITY REDUCED
Disable TFTP/SharePort on all D-Link DIR-505 devices — Turn off TFTP UDP/69 in the management UI and block it at the network boundary. This removes the vulnerable code path without patching. Deploy within 30 days per noisgate mitigation SLA for HIGH; if internet-exposed, do it within hours.
2
HIGH 7.5→IGNORE 0.0
SEVERITY REDUCED
Retire or isolate all DIR-505 devices from trusted networks — The device is end-of-life and will not receive a patch. Segment it on a dedicated VLAN with no trust or remove it entirely. Complete within 30 days.
3
HIGH 7.5→MEDIUM 4.0
SEVERITY REDUCED
Block UDP/69 at perimeter and between internal VLANs — Even if TFTP is enabled on a device, this control prevents remote exploitation from unmanaged segments. Apply to all east-west and north-south firewall rules within 30 days.
4
HIGH 7.5→MEDIUM 4.0
SEVERITY REDUCED
Detect rogue SOHO routers and unexpected TFTP traffic — Use NAC, DHCP, and SIEM to flag new MACs and UDP/69 flows. Alert on DIR-505 fingerprints. Within 30 days.
What doesn't work
  • Vendor patching: DIR-505 is discontinued; no firmware fix will be issued.
  • Web-application or TLS inspection: this path uses raw UDP/69 TFTP, so HTTP/TLS controls cannot see it.
  • Endpoint EDR: the vulnerable component is an embedded router; enterprise EDR agents are not present.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusNot in CISA KEV; no named campaigns; vendor states exploit is publicly available
Proof-of-concept availabilityPublic exploit referenced in the CVE record; no specific GitHub repo confirmed in supplied data
EPSS scoreUnknown from supplied data; public exploit likely raises probability but EPSS not available
KEV statusNot listed in CISA KEV as of 2026-11-01
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — 10.0; assumes internet-exposed TFTP and full compromise
Affected versionsD-Link DIR-505 firmware 1.10B02 and earlier
Fixed versionsNone; DIR-505 is end-of-life and no patch is expected
Scanning/exposureNo GreyNoise/Shodan data for this CVE; general TFTP UDP/69 internet exposure is low for SOHO routers
Disclosure date2026-11-01
Reporting researcher/orgNot specified in CVE record

Sources.

  1. NVD CVE-2026-120189
  2. CVE.org Record
  3. CWE-119
  4. D-Link Security Bulletins
  5. CISA Known Exploited Vulnerabilities Catalog
  6. PoC Index
05 · The Call

Final Verdict
↓ DOWNGRADED to HIGH (7.5/10)

Why this verdict

  • Baseline: vendor CRITICAL/10 is technically accurate for unauthenticated pre-auth RCE with public exploit.
  • Friction audit: TFTP is off by default, internet exposure is rare, and the DIR-505 is a discontinued SOHO travel router; each step narrows the reachable population.
  • Role multiplier: the DIR-505 is not a canonical enterprise high-value component. Worst plausible outcome is compromise of a small router and its directly connected clients—not domain/fleet/supply-chain/OT impact. This caps the practical severity below CRITICAL.
  • Public exploit: keeps it above MEDIUM because any exposed device can be taken over with low effort.

Why not higher?

Not CRITICAL because the device is a discontinued consumer travel router with a very small enterprise install base, TFTP is disabled by default, and internet-facing exposure is uncommon for this model. The vendor's 10.0 assumes worst-case reachability that most defenders won't encounter.

Why not lower?

Not MEDIUM because the bug is unauthenticated, root-level, and has publicly available exploit code. Where a DIR-505 is actually present and TFTP is on, the impact is immediate full device compromise and a pivot to connected clients, so it deserves a HIGH response.

06 · Verification

Crowdsourced verification payload.

Run from an auditor workstation with Python 3 and network access to the target segment. Invoke python3 check_dir505_tftp.py 192.168.1.0/24 to scan a CIDR, or python3 check_dir505_tftp.py 192.168.1.1 for a single host. No special privileges required, but ICMP filtering may cause UNKNOWN results for filtered ports.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
"""Check for exposed TFTP (UDP/69) on D-Link DIR-505 or any TFTP server."""
import argparse
import ipaddress
import socket
import sys

def check_host(host, port=69, timeout=3):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(timeout)
        pkt = b'\x00\x01' + b'noisgate-probe' + b'\x00' + b'octet' + b'\x00'
        sock.connect((host, port))
        sock.send(pkt)
        try:
            data, _ = sock.recvfrom(1024)
            # TFTP error opcode 5 = any response, listener is present
            if len(data) >= 2 and data[1] == 5:
                return 'VULNERABLE'
            return 'VULNERABLE'
        except socket.timeout:
            return 'UNKNOWN'
        except ConnectionRefusedError:
            return 'PATCHED'
        finally:
            sock.close()
    except OSError as e:
        if e.errno == 111:
            return 'PATCHED'
        return 'UNKNOWN'

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('target', help='IP or CIDR to check')
    ap.add_argument('--port', type=int, default=69)
    ap.add_argument('--timeout', type=float, default=3.0)
    args = ap.parse_args()
    targets = []
    try:
        net = ipaddress.ip_network(args.target, strict=False)
        targets = [str(ip) for ip in net.hosts()] if net.num_addresses > 2 else [args.target]
    except ValueError:
        targets = [args.target]
    for host in targets:
        status = check_host(host, args.port, args.timeout)
        print(f'{host}: {status}')
        if status == 'VULNERABLE':
            sys.exit_code = 1
    sys.exit(0)

if __name__ == '__main__':
    main()