shxdow's notebook

aboutblog rss

CVE-2018-1160: Netatalk RCE

This is the solution to a Pwnable.tw challenge, as well as an n-day exploit. At the time of writing only 87 88 players managed to solve it. The most troublesome part is finding the correct offset against the challenge server, which is Ubuntu 16.04 Kernel x86-64 4.9.0.


Table of contents


Bug analysis

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. __free_hook).

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.

Exploitation strategy

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 invocked when 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 _rtld_global._dl_load_lock.

Full exploit code

The full exploit code can be found on GitHub.