This is the solution to a Pwnable.tw challenge, as well as
an n-day exploit. At the time of writing only
players managed to solve it. The most troublesome part is
finding the correct offset against the challenge server,
Ubuntu 16.04 Kernel x86-64 4.9.0.
Table of contents
The root cause has already been thoroughly explained in many other blog posts
so I won’t delve too much into that.
AFP (Apple Filing Protocol) is an old server protocol that can be thought as SMB for Apple’s filesystem.
The vulnerability is a heap overflow in
dsi_opensess.c that occurs when trying to open a new session with the server.
The 255 bytes overflow allows an attacker to overwrite the pointer at which subsequent packets are written to. Given knowledge of the memory layout of the process, the second packet can be used to overwrite function pointers in memory, for example malloc’s internal hooks (i.e.
What hasn’t been touched upon as much is how to reliably defeat ASLR: the original discovery of the bug abused the fact that the binary wasn’t compiled with PIE (Position Indipendent Executable) enabled.
ASLR in Netatalk server
Due to the client-server architecture, the application behaves as a oracle by crashing the thread when writing to an invalid memory address and responding over the socket when writing to a valid one. Doing this allows an attacker to leak a memory address in \(2^8 \cdot 3\) attempts.
Memory corruption attacks usually make use of existing
program functionalities to redirect control flow.
In this instance overwriting
_rtld_global._dl_rtld_lock_recursive, which is a function
exit(...) is called, is a reliable path to
obtain code execution as soon as the program tries to clean
up the thread used to handle the request.
Its function arguments can be found in
Full exploit code
The full exploit code can be found on GitHub.