Synology DSM as a Target: Scale and Constraints
Emmons had 3.5 weeks to build an exploit for Pwn2Own Ireland 2024. His requirements: unauthenticated, default config only, no MITM, highly reliable. A Shodan query for Synology DSM returns approximately 1 million public-facing devices. Prior research from Clarity Team 82 and Devcore both required LAN access. Emmons wanted a point-and-shoot remote exploit that worked from anywhere on the internet against one of those million devices, with the DSM web service as the primary attack surface.
Tracing the Login Pipeline with bpftrace
bpftrace on the BeeStation showed three process executions during every login attempt. First: a CGI binary. Second and third: syno-cgi-plugin-weblogin, run once with –pre and once with –post. Each execution received attacker-supplied data via ephemeral temp files whose paths were passed through the syno_plugin_args environment variable. The files vanish within milliseconds. A bash race script captured the contents before deletion: the username and user-agent string were written to disk before any authentication decision ran.
Escaping the Login Context via Delimiter Smuggling
The login form applies client-side RSA+AES encryption. Emmons bypassed it using Vue devtools to submit raw strings directly. Injecting a line feed in the username triggered a defensive response: the system wrapped attacker data in plugin_value_start and plugin_value_end bookend delimiters. Injecting those same delimiter strings back in the username broke out of the contained context and added new entries to the root process environment. The syno_plugin.log confirmed it: new_variable=test appeared as a root process argument without any authentication.
LD_DEBUG Turns Any Root Process into a File Write Primitive
LD_DEBUG has shipped with glibc since 1999. Its partner, LD_DEBUG_OUTPUT, redirects dynamic linker debug output from stderr to a named file, appending the process ID as a suffix. The dynamic linker does not sanitize newline characters in LD_PRELOAD library paths when writing that debug output. Inject a line feed inside the LD_PRELOAD value and one fully attacker-controlled line appears in the output file. The file path is mostly attacker-controlled via LD_DEBUG_OUTPUT. The extension is not.
Cron as the Execution Stage: the Tab Delimiter Trick
The cron daemon reads /etc/cron.d/ on most Linux systems, is file-extension agnostic, and ignores malformed lines. Writing there via LD_DEBUG_OUTPUT is straightforward. The obstacle: LD_PRELOAD treats spaces as library delimiters, so a standard space-separated crontab payload gets split into multiple failed library lookups. The fix, discovered through testing: cron also accepts tab characters as field separators. Tabs are undocumented, not treated as delimiters by LD_PRELOAD, and survive the injection intact. A base64-encoded reverse shell command handles remaining bad characters.
Full Chain and Live Demo at Pwn2Own
The complete payload goes in the username field of the Synology DSM login form. It injects LD_PRELOAD, LD_DEBUG=libs, and LD_DEBUG_OUTPUT=/etc/cron.d/hacks into the root-owned syno-cgi-plugin-weblogin process. The cron daemon picks up the file within one minute and executes the tab-delimited reverse shell as root. No authentication, no file upload, no prior access. A netcat listener on port 4444 catches the shell. At Pwn2Own Ireland 2024, this chain won Emmons a $40,000 prize against one of roughly 1 million exposed Synology devices.
Notable Quotes
Pretty exciting without authentication. Ryan Emmons · ▶ 20:28
execution. It’s a strong primitive. Ryan Emmons · ▶ 20:38
that’s enough for remote code execution Ryan Emmons · ▶ 32:39
copy-paste a payload in my opinion. Ryan Emmons · ▶ 38:02
Key Takeaways
- Synology’s login pipeline writes tainted user input into root process environment variables before authentication completes.
- Bookend delimiters designed to safely contain newlines can be injected to escape their own containment context.
- LD_DEBUG_OUTPUT combined with line-feed-injected LD_PRELOAD writes attacker-controlled content to /etc/cron.d, delivering a root shell within one minute.
About the Speaker(s)
Ryan Emmons is a security researcher on the Emergent Threat Response team at Rapid7, focused on n-day analysis and zero-day research targeting network edge devices. He has reported vulnerabilities to Oracle, Microsoft, and SonicWall. He competed at the 2024 Pwn2Own Ireland competition, where he won a $40,000 prize. Outside of research, he participates in CTF competitions and composes music.