Привет! Эта маленькая статья расскажет об уязвимости в Python приложении. Эта уязвимость заключается в неправильном использовании функции input(). Для тех из вас, кто использует Python версии 3.x, эта уязвимость не относиться. В Python 3 функция raw_input() была удалена, и ее функциональность была перенесена на новую встроенную функцию, известную как input(). В отличие от Python 2.x, которые существуют как с функцией input(), так и с функцией raw_input(). Поэтому эта статья применима только к программам, написанным на Python 2.x.
Функция eval() в Python получает критику за потенциально опасное неправильное использование. Функция eval() оценивает строку текста, которая передается в качестве ее параметра, принимая возможный второй аргумент для глобальных значений, используемых во время оценки. Кроме того, функция input() в Python 2.x это тоже самое, что написать eval(raw_input()). Это делает функцию input() очень опасной.
Лучший способ понять эту уязвимость, это увидеть работу этой функции. Я продемонстрирую работу input(), написав небольшой скрипт игры с угадыванием.
Python:
import random
lucky_num = random.randint(1, 10001)
print "Choose a number beetwen 1 and 10,000"
while True:
res = input("Guess a number: ")
if res == lucky_num:
print "Congratulations, you win!"
break
else:
continue
Начнем с импорта модуля random, чтобы мы могли использовать функцию random.randint(1, 10001) для генерации псевдослучайного числа в этом диапазоне. В бесконечном цикле мы устанавливаем переменную res, эквивалентную вводу пользователя. И, наконец, проверяем, соответствует ли этот вход случайному числу, которое было случайно сгенерированно. Если они равны, будет выведено сообщение о победе, иначе цикл продолжится. Теперь поговорим об эксплуатации...
Из просмотра изображения выше вы можете видеть, что после запуска программы в терминале мне было предложено ввести номер. После нескольких неудачных попыток, я решил просто использовать имя переменной, в которой хранится значение случайного целого числа. В нашем случае это было lucky_num. Поскольку input() совпадает с eval(raw_input ()), он оценивает переменную так, как если бы номер был введен непосредственно, что означает, что он возвращает значение True и завершает игру. Если бы я использовал raw_input(), этой проблемы бы не возникло.
Приведенный выше пример - это лишь небольшая и незначительная игра. Но представьте, что вы использовали input (), чтобы получить учетные данные пользователя и сохранить их в базе данных. Если вы настаиваете на том, чтобы придерживаться Python 2.x, придерживайтесь raw_input (). Также старайтесь избегать злоупотребления eval(). Также, с помощью уязвимости этого кода, можно добиться Remote Code Execution.
На изображении выше, показано как легко можно выполнить нужные нам команды. Ну, на этом всё. Спасибо за внимание.