Python Interpreters
Useful Knowledge
There’s a lot you can do within an interpreter even without direct access to source.
dir()
will list out all the available names inside the current space. You can also usedir()
on a function to see what attributes and properties the function has.func_name.func_code
has a ton of useful properties to get information about the function. Among the most useful:
func_name.func_code.argcount
- Self-explanatoryfunc_name.func_code.co_code
- Gives you the bytecode representing the function.func_name.func_code.co_consts
- Constant numbers and strings present inside the function.func_name.func_code.co_varnames
- Names of variables inside the function.
Eval to String when Alphanumeric Characters Disallowed
I first came across this problem during TJCTF 2018, “Mirror Mirror”.
We were dropped into an REPL with the knowledge that there was a get_flag function.
Here is what the code looked like:
1 | super_secret_string = 'this_is_the_super_secret_string' |
Of course, most special functions were blocked so I couldn’t view the flag directly.
With big credit to http://wapiflapi.github.io/2013/04/22/plaidctf-pyjail-story-of-pythons-escape/, we were able to create a string that would evaluate to another string, bypassing the input check. I stole the following from https://ctftime.org/writeup/10677.
1 | def brainfuckize(nb): |
Restricted Shells
No Letters
You can do tons of interesting things in a shell using shell expansions to call binaries even if you are restricted by the letters you can input. For example:
/???/???/?????32
expands to /usr/bin/linux32, which will give you a simple dash shell. You could also run python using /???/???/??????2
.