Submit #1027185: D-Link DIR-505 1.10B02 Stack-based Buffer Overflowinfo

TitleD-Link DIR-505 1.10B02 Stack-based Buffer Overflow
DescriptionSummary: D-Link DIR-505 A1 firmware 1.10B02 (components: /usr/bin/tftpd and /lib/libputil.so) contains a stack-based buffer overflow in the TFTP upload filename handling (save_upload_file / mp_upload_file). The TFTP daemon accepts unauthenticated WRQ uploads; the attacker-controlled TFTP filename is copied with strcpy() into a 30-byte stack buffer as "/tmp/<filename>" without any length or character validation. An overlong filename overflows saved registers and the return address, leading to remote code execution as root. The complete chain was verified end-to-end on the real firmware. Technical details: - Overwrite site 1: save_upload_file() performs strcpy(local[30], "/tmp/<filename>"); the saved $ra is at filename offset 47 (path offset 52). Calibration with 0xdeadbeef produced the kernel register dump "epc/ra = 0xdeadbeef, BadVA = deadbeee", proving exact return-address control. - Overwrite site 2: mp_upload_file() performs sprintf(local[64], "/tmp/%s", filename) which additionally fills the caller's frame; this yields the deterministic mapping content(sp+m) = filename[0x33+m], used to place the payload. - ROP: the hijacked return address is set to libputil.so + 0x6838 (disasm: "lw $t9, -0x7e80($gp); addiu $s1, $sp, 0x28; jalr $t9; move $a0, $s1"), which calls system(sp+0x28). The command string is taken from the overflow payload itself at stack offset +0x28 (filename offset 91) and is NUL-terminated by the copying strcpy. Only the libputil.so base address is required; the command pointer is computed at runtime from $sp (no stack-address leak needed). - Address stability: tftpd forks one child per request; children inherit the parent's memory map and stack layout, so the libputil base and the stack addresses remain constant for the lifetime of the tftpd parent (until reboot or re-trigger). Failed attempts only crash the forked child; the daemon survives and the attack is repeatable (address leak or brute force are viable remotely). - Protocol quirk: the daemon truncates the received TFTP filename at the first whitespace byte; exploit commands are therefore written space-free (e.g. "id>/tmp/q", "sh</tmp/x"). Full verified exploit chain (all unauthenticated): 1. The device's TFTP daemon is started without authentication by a hidden maintenance backdoor reachable via POST /secmark1524.cgi (separate advisory; the daemon itself then performs no authentication). 2. Plant a script via the same service's unauthenticated file-write primitive (upload with filename "x" writes /tmp/x). 3. Send the overflow filename whose payload calls system("sh</tmp/x"). 4. The script executes as root: telnetd -p 2327 -l /bin/sh started; /tmp/rc_proof created; interactive root shell obtained over TCP. Impact: Unauthenticated remote code execution as root (complete device compromise: arbitrary commands, file read/write, credential theft, persistence). Affected versions: - D-Link DIR-505 A1 firmware 1.10B02 - confirmed vulnerable (full exploitation, root shell). - Firmware 1.06 contains the same code family (tftpd + libputil save_upload_file/mp_upload_file); exploitation not attempted. Classification: CWE-121 (Stack-based Buffer Overflow), consequence CWE-78 (OS Command Injection). CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8 Critical). Remediation: Remove the hidden maintenance backdoor; replace the unbounded strcpy/sprintf with bounded copies and reject path separators; require authentication and drop privileges for any file-transfer service.
Source⚠️ https://github.com/Walnut1337/DIR-505_filename_rce/tree/main/poc
User
 Walnut1337 (UID 100856)
Submission10/13/2026 04:57 (19 days ago)
Moderation10/31/2026 09:05 (18 days later)
StatusAccepted
VulDB entry429528 [D-Link DIR-505 1.10B02 TFTP Upload Filename /usr/bin/tftpd save_upload_file/mp_upload_file stack-based overflow]
Points20

Do you want to use VulDB in your project?

Use the official API to access entries easily!