There is a netcat
CTF task where it is needed to get the flag via an RCE (the most simple and obvious variant for me is exec()
)
Python 2.7.18 (default, Apr 28 2021, 17:39:59)
[GCC 10.2.1 20210110] on linux2
>>> print input()
pow(2, 3) # No problems with functions
8
>>> print input()
None # Can print None values
None
>>> print input()
eval('1 + 1')
2
>>> print input()
eval('1 + 1') # eval() works
2
>>> x = 1
>>> print input()
eval('x + 1') # eval() with local variables involved also works
2
>>> print input()
exec('') # Even empty exec() causes an error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
exec('') # Even empty exec() causes an error
^
SyntaxError: invalid syntax
>>> print input()
exec('import os') # exec() call causes an error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
exec('import os') # exec() call causes an error
^
SyntaxError: invalid syntax
Is it possible to push an exec()
with input()
called in Python 2.7? (Switching the Python version or changing executable print input()
cannot be done)
UPD
I need something like this:
>>> print input()
exec('import os\nprint os.name') # I need a similar RCE in this CTF task, so eval() is not suitable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
exec('import os\nprint os.name') # I need a similar RCE in this CTF task, so eval() is not suitable
^
SyntaxError: invalid syntax
Instead of
>>> print input()
exec('1 + 1')
do
>>> print input()
eval('1 + 1')
and you will get the output 2
that you expect. exec()
expects executable statements; eval()
expects an expression, which is what 1+1
is. Though this is simpler and equivalent:
>>> print input()
1 + 1
I must admit I have no idea what a CTF task is, or why it needs to execute RTE code, whatever that is, but given that your real requirement is not to produce the result of 1 + 1
but rather the value of os.name
, it might suit your purpose better to avoid futzing around the corner cases of the obsolete input()
function and simply do, as a command line,
python -c "import os;print(os.name)"
which (on my system) produces the output
nt
and will work in every version of Python.
The reason why the Python 2 input()
function cannot be made to do what you want, is that in Python 2
exec
is a statement, not a function.input()
is roughly equivalent to eval(raw_input())
: it will accept expressions but not statements.