As usual, the vulnerable file is here
feap is a binary that allows you to add/edit/delete a list of notes. The
notes are stored in a table locate in the
.bss at 0x6020a8. This table can
hold 20 notes. A note has the following structure:
For each note at offset i, the total size of the malloc-block can be found
at the offset i of the table
notes_sizes located at 0x6020b0,
notes_sizes[i] = sizeof(notes[i]).
To manipulate the notes, the program offers several options via a simple menu with different choices:
- function at 0x400D2B allows to add new notes (later called
- function at 0x400C5A allows to delete new notes (later called
- function at 0x400AFC allows to edit a note (later called
- function at 0x40096D allows to print all notes (later called
- function at 0x0400A1D allows to print one note (later called
Two vulnerabilities were found:
- a lack of boundary check in
print_note()function allows to read at arbitrary address of the memory space;
- a heap overflow in the
edit_note()function allows to overwrite adjacent chunks.
When printing a specific note, the user is prompted for a note index. However,
this index is not checked, meaning that any submitted value outside the boundary
notes table (i.e. between [0, 19]) will leak the process memory.
notes_sizes are 2 adjacently allocated chunks of size 160
bytes. This implies that attempting to reach
notes will land in
prev_size section, and
section. So by accessing
notes we will attempt to read the content pointed
So to read at address
ADDR in the memory layout, we must:
- create a note of size
- print the note at offset 22
(as implemented in leak_memory function)
This leak not only allows us to dump heap addresses, but also GOT addresses
printf@got) etc. which defeats the library
edit_note(), allows to edit the
content of a note, by editing its name of its body.
When editing the body, the function calls
note[i]->body, but with
a size to read of the entire chunk (name + body).
So we have 64 bytes (i.e. sizeof(note.name) ) that we can overwrite in the next chunk.
On top of the vulnerabilities mentioned earlier, we have total control over the
size of a call to
malloc() in the
add_note() function (at 0x400DAE). This is the perfect scenario for a House
of Force exploitation.
The House of Force technique has already been used in previous post so I won’t detail it as much (no pretty ascii art this time ). But the idea stays the same:
- allocate a first note;
- allocate a second note, whose malloc-ed size will drop us into the GOT;
noteschunk headers by editing
- create a last chunk that will actually overwrite the desired address.
firstname.lastname@example.org at 0x602018 is a good candidate to be overwritten, so we need to
create a size of
free_location - notes_location. With a few adjustments we
Now we know that
email@example.com will be overwritten by the
note->name of the
next note created.
With the memory leak explained above, we can dynamically get several addresses
in the GOT. Using 2 addresses and
libcdb, we can know the
libc version and therefore the offset of the
All we have left to do, is to write
"/bin/sh" as the note->name of the note we
will want to delete.
Put it all together in the complete exploit and you get the flag:
Share this post: