Alright, let's drop a shell from the house_of_spirit binary, you can either make a copy of your
exploit from the previous video, edit it in place, which is what I'll do or work off the commented
exploit from the previous videos resources.
Scroll to the bottom of your script and remove the final call to the malloc() helper function, we can
ignore the "age" and "username" fields since our focus will, as usual, be on the heap and GLIBC.
The first thing we're going to edit is the "name" variable, the second half of which is what overflows
into a chunk pointer, giving us our House of Spirit primitive.
As we learned in the previous video, we can't free fake normal chunks at addresses higher than the
default heap without triggering a mitigation.
So if we want to target the malloc hooks, our fake chunk size is immediately restricted to the
fastbins range.
The first approach that comes to mind is why not just free that 0x7f chunk that we used for our
fastbin dup in HeapLAB Part 1, the one that sits just before the malloc hook and is consistently
formed by one of the standard IO vtable pointers and following padding quadword?
But we know that won't work because a 0x7f size field has three set bits that will cause our House
of Spirit primitive to fail, namely the IS_MMAPPED bit, the NON_MAIN_ARENA bit and the fourth-least
significant bit.
There's another reason this won't work either, a mitigation we didn't come across in the previous video.
If I run my pwntools script in its current state with the GDB and NOASLR options, it will attempt to
free the fake chunk near the malloc hook.
And as expected, GDB will stop.
But if I switch to the free() frame and check the source line where the issue occurred,
we can see that I've triggered a mitigation before the one that checks the freed chunk's size field.
This mitigation is checking two things;
the first is whether the freed chunk wraps around the VA space House of Force style.
The second is whether the chunk is 16 byte aligned, due to the nature of how heaps are mapped and the
fact that chunk sizes are always multiples of 16 bytes on this architecture, legitimate chunks should
never be misaligned.
Let's take this opportunity to review the many constraints we must adhere to for our House of Spirit
attack to be successful.
Assuming we wish to target to one of malloc's hooks, our fake junk must be in the fastbin range because
normal chunks can't be freed at addresses above the default heap.
The second, third and fourth least significant bits of our fake chunks size field must be clear.
If not, they'll trigger mitigations or cause segfaults.
Our fake chunk must be 16 byte aligned.
And don't forget that we need to provide a succeeding size field of appropriate value at the right location.
If you're able to find naturally occurring data or massage libc data to fit this profile, then that's
extremely impressive, but not the route we're going to take right now.
I want you to take a moment to consider how we might approach this problem.
Our target is the malloc hooks, and we have eight requests to make this work.
Remember that we not only have a libc leak, but a heap leak too, stored in that "heap" variable in our
exploit script.
Pause the video now and see if you can come up with any ideas, if you think it might work, try it
out before returning.
If you're watching this having already got a shell, that's great work, otherwise hopefully you
came up with a plan to bypass those legitimate chunk mitigations we're dealing with and what could be
more a like a legitimate chunk than a legitimate chunk.
Consider the following scenario;
we request 3 chunks, 2 of which are the same fastbin eligible size, A & B, and the third chunk
is any size.
We then leverage this program's bug to overwrite the 3rd m_array entry with the address of the first chunk's
user data, the address of which we know thanks to the heap leak.
Note that if we weren't able to leak the heap but could still make a controlled overwrite of the least
significant byte of the chunk pointer, we may still be able to achieve the same effect.
Next, we free those chunks in the same order we requested them A, B, then C. When chunk A is freed,
it's linked into the appropriate fastbin, followed by chunk B. But when free() is called on the 3rd
m_array entry, rather than freeing chunk C, it instead frees chunk A again.
You will, of course, recognize this pattern from the fastbin dup technique as the fastbins double-
free mitigation bypass.
So we can turn a House of Spirit primitive into a fastbin dup primitive. In this example I've used
legitimate chunks on the heap since we have a heap leak, but you could just as easily use the same trick
to double-free a fake fast chunk elsewhere in memory.
I've created a template that sets up a double free scenario using our House of Spirit primitive,
it's what's on screen now and you can download a copy from this lecture's resources. This template
can be used to practice dropping a shell via the House of Spirit.
You'll need to leverage what you learned during the fastbin dup exercises in HeapLAB Part 1 to make
this work.
Since we've already covered the malloc internals and heap exploitation techniques required to do this,
I'll leave it up to you to drop a shell from this binary.
If you get stuck or want to revisit this technique, then there are two commented solution scripts available
from this lecture's resources.
The first builds on this template to drop a shell,
the second ignores the heap leak completely, but still achieves the same result.
Once you're comfortable with the House of Spirit and the different ways it can be leveraged, join me
in the next video where we'll be learning about the House of Lore.