The Pwn2Own Exploit That Never Was: A Format String Flaw in Synology IP Cameras Allowed Remote Code Execution
In the autumn of 2024, the InfoSect bug hunting team prepared a remote code execution attack targeting the Synology TC500 IP camera for entry in the Pwn2Own Ireland competition. The exploitation hinged on a flaw in the implementation of string formatting, which allowed the bypass of ASLR and granted complete control over the device. Although Synology managed to patch the vulnerability at the last moment, the exploit’s development served as a compelling demonstration of the offensive potential that remains even under modern defensive mechanisms.
The research began with firmware analysis, made accessible through public downloads. Using emulation, the team examined the device’s internal services, including a civetweb-based web interface and an RTSP server. Attention quickly centered on the webd
process responsible for handling HTTP requests. Despite contemporary protections—PIE, RELRO, ASLR, and Stack Canary—a critical vulnerability was discovered in the process_new_connection
function.
Synology had implemented a debugging feature in webd
, wherein each thread logged the requested URI to a global table via the set_thread_name
function. The issue stemmed from how this URI was passed to mg_snprintf
and treated as a format string—without verifying whether it contained control characters. This introduced a classic format string vulnerability.
Though direct reading of the result was impossible, stack analysis revealed a pointer referencing the HTTP version string returned to the client. By crafting format specifiers such as %[len]c%[pos]$n
, the researchers achieved memory leakage, effectively circumventing ASLR. While the accessible memory range was constrained to 0x50000000–0x60000000, it sufficed to expose addresses within the executable module.
The next phase involved arbitrary memory writes. Leveraging stack pointers, the team constructed a chain: p1
pointed to p2
, which in turn pointed to p3
, located in a safe stack region. By carefully modifying the bytes of these pointers step-by-step, they redirected p3
to an arbitrary memory location and wrote data to the desired address.
This technique culminated in a rudimentary arbitrary write primitive operating at 8-bit granularity. It enabled the modification of memory contents and set the stage for an attack on the free()
function within the glibc library.
Armed with the earlier leakage and knowledge of the .got
address, the team calculated the location of __free_hook
and replaced it with system()
. To trigger a call to free()
with a controlled argument, they exploited the behavior of the GetSessionIdFromCookie
function, which frees memory allocated to a Cookie header. By supplying a payload such as telnetd -p 1337 -l /bin/sh -F
in the Cookie, the attacker ensured that free(cookie)
would invoke system("telnetd -p 1337 -l /bin/sh -F")
, thereby spawning a reverse shell.
Although the exploit was never demonstrated at Pwn2Own due to Synology’s last-minute firmware update, the methodology offered a vivid illustration of how a single format string vulnerability—combined with glibc internals—can grant an attacker full dominion over a device.