[Western Digital PR4100] RCE due to Ignored Bounds Check Warning
An out of bounds access bug in the netatalk open source library for the Apple Filing Protocol (AFP) that could be exploited on WD PR4100 NAS for pre-auth RCE. The bug happens when parsing resource fork file headers, which can be reached through the afp_openfork
handler over AFP or SMB without authentication. Resource fork file headers contain entry descriptors, which have an offset and length for the backing data. When ad_header_read_osx()
calls parse_entries()
, it will check if an offset is out of bounds and set a failure return value. Even though this return value was checked, it just throws a warning and continues on in the error handling. This leads to the offset being used later on when ad_convert_osx()
is called and uses it for a memmove()
. The offset is used in calculating both the source and destination, and the attacker has control over the size of the copy via the entry length.
Exploitation
This bug was exploited twice to full chain, as the binary was ASLR’d and position independent (PIE). First, it was used to force the memmove()
source stack pointer out of bounds to leak stack data via saving to a file which could be exfil’d over SMB. This allowed them to defeat ASLR and resolve the address of system()
. The control flow hijack was a bit more interesting. They found by providing a file that was less than 0x1000 in size, they were able to get the file mapped 0xC000 bytes before the ld (dynamic linker) library. They could corrupt the .data segment to overwrite the _dl_rtld_lock_recursive
function pointer. Since memmove()
was being used which uses SSE (and SSE requires 16-byte alignment for operands), it was possible to get this pointer called by intentionally triggering an SSE exception through misaligning the source pointer.