| Title | D-Link DIR-505 1.10B02 Stack-based Buffer Overflow |
|---|
| Description | Summary:
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) |
|---|
| Submission | 10/13/2026 04:57 (19 days ago) |
|---|
| Moderation | 10/31/2026 09:05 (18 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 429528 [D-Link DIR-505 1.10B02 TFTP Upload Filename /usr/bin/tftpd save_upload_file/mp_upload_file stack-based overflow] |
|---|
| Points | 20 |
|---|