# Keith BotLooking at the discord api, it's evident that the bot executes `on_message` when it receives a text. Which executes any python code prefixed with `_eval`.    eval.py reveals that we are in a situation, python jail.     We can execute commands but only a limited number of them.     These two lines make sure we cannot execute builtin commands.    ```env = {"__builtins__": {}}
exec(f"def func():\n{textwrap.indent(sys.stdin.read(), '    ')}", env)
```It also states that the input sent is used to create a function named `func` which is later called and the return value is sent back by the text.    Sending `_eval return 0` verifies this prediction.    ![return 0](https://i.imgur.com/uhu3ULN.png) As we are in a jail, we cannot execute most of the functions but we can play with the data types.    [Standard types](https://docs.python.org/3/library/stdtypes.html#instance.__class__) here show some useful properties.    Tracing the tree, we can deduce that     `().__class__.__bases__[0]` would provide us with an `object` class.     `().__class__.__bases__[0].__subclasses__()` wolud provide a list of all subclasses of `object` we can use now.    
Though, in this scenario     `_eval return ().__class__.__bases__[0].__subclasses__()` results nothing, probably because of some character limit.The workaround is to split the list and view part-wise.    i.e.`_eval return ().__class__.__bases__[0].__subclasses__()[0:50]`    and so on.    
![object subclasses](https://i.imgur.com/3BW88NF.png)
On further inspection of the subclasses, there is one `BulitinImporter` class available at our disposal. A normal search reveals that [BuiltinImporter](https://docs.python.org/3/library/importlib.html#importlib.machinery.BuiltinImporter) implements [InspectLoader](https://docs.python.org/3/library/importlib.html#importlib.abc.InspectLoader) which provides [load_module](https://docs.python.org/3/library/importlib.html#importlib.abc.InspectLoader.load_module) function.     Using the same, it is possible to load the [io module](https://docs.python.org/3/library/io.html) and read the flag.    The final exploit would look like    ```_eval return [ c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__=='BuiltinImporter' ][0].load_module('io').open('flag.txt').read()```which results in ![flag](https://i.imgur.com/1wkIa2H.png)
Further reading: [https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html](https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html)