# Snappaste (Part 2) Writeup
Here's an improved version of our pasting service. Some weird stuff was happening in the previous version, so we added an integrity check for the pastes. Also, due to misuse, we began limiting the size of the pasted snippets (please don't paste Kali Linux ISOs, thanks).
URL: https://snappaste2.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
By using WinMerge we could observe the next major differences between the versions:
- `dword data_crc32;` added in `PASTE_NETWORK_HEADER`- Size checking added:
```c// Prevent service misuseif (header->metadata_size > 0x10000 || header->data_compressed_size > 0x10000 || header->data_decompressed_size > 0x10000) {  throw std::invalid_argument("data size too big :(");}```
- The next code was added:
```c// TODO: remove after testingif (true) {  auto flag = readfile("./flag");  if (paste_received->data_size >= flag.size()) {    memcpy(paste_received->data, flag.c_str(), flag.size());    if (backdoor) {      backdoor = false;      paste_received->metadata_size = 0;      paste_received->data_size = static_cast<dword>(flag.size());      return paste(paste_received);    }  }}```
- CRC validation.
This time we can't change `backdoor` variable because we don't have the previous integer overflow. Lets try to find new vulnerabilities with the added code.
Actually, this code:
```cauto flag = readfile("./flag");if (paste_received->data_size >= flag.size()) {  memcpy(paste_received->data, flag.c_str(), flag.size());```
Is giving us opportunity to leak the flag because it is being copied into the `paste_received->data_size` location, but it is being overwritten later with our data:
```pythonuncompress(paste_received->data, &dest_len, data, header->data_compressed_size);```
When we tried giving large `paste_received->data_size` value, but small actually compressed data (to see the rest of the flag), we are failing at the next CRC check:
```pythoncrc32(0, paste_received->data, paste_received->data_size);```
Because we don't know the flag content, we can't really guess/bruteforce the CRC.
What we CAN do is to guess one letter at a time.
Lets first guess the flag length:
```pythonguessed_length = 38
metadata = b'{"name": "alex","date":"2020-06-28T15:52:21.519Z"}'metadata_size = len(metadata)data_decompressed_size = guessed_lengthdata_decompressed = b'\x00'data_compressed = zlib.compress(data_decompressed)data_compressed_size = len(data_compressed)data_crc32 = zlib.crc32(b'\x00'*guessed_length)
paste_data = b''paste_data += struct.pack('