How to leak the value of a variable in python

1.1k views Asked by At
hidden = random.random()
val = input("Guess the value of the randomly generated number. ")
if float(val) == hidden:
     print("You got it!")
else:
     print("Sorry. You missed.")

Hey Guys, Is there a way to exploit this raw input, and leak the value of the variable "hidden" from within the program? In other words, could you execute a line of code from the input alone? I tried format string attacking the program, but it didn't work. Note: You cannot change the code.

Any suggestions?

2

There are 2 answers

0
BrenBarn On

In Python 2, yes, because you didn't use raw_input, you used input. So you can type "hidden" at the prompt and magically get it right (because it evaluates the value of the variable called hidden):

Guess the value of the randomly generated number. hidden
You got it!

In Python 3, no, because input now does what raw_input used to do, which is treat the value only as a string, to avoid this sort of sneakiness.

0
chepner On

You can get input (in Python 2.x) to evaluate an arbitrary expression, which includes the write method of an appropriate object (say, a file object):

$ python tmp.py
Guess the value of the randomly generated number. open("/dev/tty", "w").write(str(hidden))
0.111568033994Traceback (most recent call last):
  File "tmp.py", line 6, in <module>
    if float(val) == hidden:
TypeError: float() argument must be a string or a number

The input string open("/dev/tty", "w").write(str(hidden)) will trigger a TypeError, but not before the string is evaluated, which causes the value of hidden to be written to the current terminal. This example is somewhat OS-dependent, in that it assumes /dev/tty exists, but I only used it to cause the value to be displayed immediately. Any file the users will have permission to write to can be used, and the contents of the file can be viewed after the Python script exists.

If the code had included import sys, you could use the input sys.stdout.write(hidden) instead.

If the code had included from __future__ import print_function, you could use the input print(hidden) instead.