Pull to refresh

Книга «Black Hat Python: программирование для хакеров и пентестеров, 2-е изд»

Reading time9 min
Views22K
image Привет, Хаброжители! Когда речь идет о создании мощных и эффективных хакерских инструментов, большинство аналитиков по безопасности выбирают Python. Во втором издании бестселлера Black Hat Python вы исследуете темную сторону возможностей Python — все от написания сетевых снифферов, похищения учетных данных электронной почты и брутфорса каталогов до разработки мутационных фаззеров, анализа виртуальных машин и создания скрытых троянов.

С тех пор как я написал предисловие к первому чрезвычайно успешному изданию Black Hat Python, прошло шесть лет. За это время в мире многое изменилось, но я по-прежнему пишу чертовски много кода на Python. В сфере компьютерной безопасности все еще встречаются инструменты, написанные на разных языках, в зависимости от назначения. Эксплойты для ядра создают на C, средства фаззинга для веб-страниц — на JavaScript, а прокси-серверы могут быть написаны на таком новомодном языке, как Rust. Однако Python остается главной рабочей лошадкой в этой отрасли. Я считаю, что это все еще самый простой язык для начинающих и лучший выбор для быстрой разработки инструментов, решающих сложные задачи простым способом, учитывая большое количество доступных библиотек. Большая часть средств компьютерной безопасности и эксплойтов, как и раньше, написана на Python. Это касается фреймворков создания эксплойтов наподобие CANVAS, классических фаззеров, таких как Sulley, и всего остального.

Веб-хакерство


Навыки анализа веб-приложений совершенно необходимы любому хакеру или пентестеру. В большинстве современных сетей веб-приложения имеют самый высокий потенциал для взлома, поэтому несанкционированный доступ к ним чаще всего получают через них самих.

На Python написано множество отличных веб-инструментов, включая w3af и sqlmap. Если честно, то такие темы, как внедрение SQL-кода, являются крайне заезженными, а готовый инструментарий достаточно развитой для того, чтобы не изобретать велосипед. Поэтому сосредоточимся на основах работы с сетью при помощи Python и затем, опираясь на эти знания, разработаем собственные инструменты для сбора полезных сведений и анализа веб-приложения методом перебора. Это позволит вам приобрести фундаментальные навыки и умения, необходимые для создания любого рода средств анализа веб-приложений, уместных в конкретной атаке.

В этой главе мы рассмотрим три сценария атаки. В первом из них вам известно, какой каркас веб-приложений применяет жертва, и так сложилось, что он имеет открытый исходный код. Каркас веб-приложений содержит множество файлов и вложенных каталогов. Мы сгенерируем локальную карту иерархии веб-приложения и воспользуемся ею для поиска реальных файлов и каталогов на компьютере жертвы.

Во втором сценарии вам известен только URL-адрес жертвы, поэтому придется прибегнуть к методу перебора, чтобы получить ту же структуру каталогов. Мы возьмем словарь и сгенерируем на его основе набор путей и названий каталогов, которые могут присутствовать на атакуемом компьютере. Затем попытаемся отобрать из полученного списка потенциальных путей те, которые действительно существуют.

В третьем сценарии вам известны базовый URL-адрес жертвы и страница для входа. Мы проанализируем эту страницу и попробуем подобрать учетные данные по словарю.

Использование веб-библиотек

Для начала сделаем краткий обзор библиотек, которые можно применять для взаимодействия с веб-сервисами. При выполнении сетевых атак вы можете пользоваться либо своим компьютером, либо устройством внутри атакуемой сети. Если вы пробрались на взломанный компьютер, то придется работать с тем, что под рукой, — это может быть базовая версия Python 2.х или Python 3.х. Мы поговорим о том, что можно сделать в такой ситуации, обходясь стандартной библиотекой. Однако в остальных разделах этой главы предполагается, что на компьютере, с которого проводится атака, установлены самые свежие пакеты.

Библиотека urllib2 для Python 2.х

В коде, написанном на Python 2.х, можно встретить пакет urllib2, встроенный в стандартную библиотеку. Если пакет socket применяется для написания сетевого инструментария, то с помощью urllib2 создают средства взаимодействия с веб-сервисами. Рассмотрим код, который выполняет очень простой GET-запрос к веб-сайту No Starch Press:

import urllib2
url = 'https://www.nostarch.com'
response = urllib2.urlopen(url) # GET 
print(response.read()) 
response.close()

Это простейший пример того, как выполнить GET-запрос к веб-сайту. Мы передаем URL-адрес функции urlopen, которая возвращает объект, похожий на дескриптор, с его помощью можем прочитать тело того, что нам возвращает веб-сервер. Поскольку мы получаем всего лишь код страницы с веб-сайта No Starch, никакие клиентские скрипты, написанные на JavaScript или другом языке, выполняться не будут.

Однако в большинстве случаев требуется более гибкий подход к выполнению запросов. Например, иногда нужно указывать определенные заголовки, обрабатывать cookie и создавать запросы типа POST. Библиотека urllib2 имеет в своем составе класс Request, способный обеспечить такой уровень гибкости. В следующем примере показано, как с помощью этого класса создать такой же GET-запрос с указанием собственного HTTP-заголовка User-Agent:

import urllib2
url = "https://www.nostarch.com"
headers = {'User-Agent': "Googlebot"} 
request = urllib2.Request(url,headers=headers) 
response = urllib2.urlopen(request) 
print(response.read())
response.close()

Процесс создания объекта Request немного отличается от того, который мы видели в предыдущем примере. Чтобы указать собственные заголовки, добавляем их названия и значения в словарь headers. В данном случае мы сделаем так, чтобы наш скрипт представлялся поисковым роботом Googlebot. Затем создаем объект Request, предоставляя ему url и словарь headers, после чего передаем этот объект функции urlopen. В ответ получаем обычный объект-дескриптор, который можно использовать для чтения данных с удаленного веб-сайта.

Библиотека urllib для Python 3.х

Стандартная библиотека Python 3.х содержит пакет urllib, в котором возможности urllib2 разделены на два подпакета: urllib.request и urllib.error. Также в urllib появились функции разбора URL-адресов, доступные в подпакете urllib.parse.

Для создания HTTP-запроса с помощью urllib можно воспользоваться диспетчером контекста и инструкцией with. Полученный ответ должен содержать байтовую строку. Вот как это выглядит на примере GET-запроса:

import urllib.parse 
import urllib.request
url = 'http://boodelyboo.com' 
with urllib.request.urlopen(url) as response: # GET 
content = response.read() 
print(content)

Здесь мы импортируем нужные нам пакеты и определяем целевой URL-адрес. Затем с помощью метода urlopen в качестве диспетчера контекста выполняем запрос и читаем ответ.
Чтобы создать POST-запрос, передайте словарь с данными, закодированными в виде байтов, объекту Request. Этот словарь должен содержать пары «ключ — значение», которые ожидает получить атакуемое вами веб-приложение. В этом примере словарь info содержит учетные данные (user, passwd), необходимые для входа на веб-сайт:

info = {'user': 'tim', 'passwd': '31337'}
data = urllib.parse.urlencode(info).encode() 
# теперь данные имеют тип bytes
req = urllib.request.Request(url, data) 
with urllib.request.urlopen(req) as response: # POST
   content = response.read() 
print(content)

Мы кодируем словарь с учетными данными, чтобы превратить его в объект типа bytes, помещаем его в POST-запрос, передающий эти учетные данные, и принимаем ответ на попытку входа в веб-приложение.

Библиотека requests

Даже официальная документация Python рекомендует использовать в качестве высокоуровневого клиентского HTTP-интерфейса пакет requests. Он не входит в стандартную библиотеку, поэтому его нужно устанавливать отдельно. Вот как это сделать с помощью pip:

pip install requests

Пакет requests выгодно отличается тем, что может автоматически обрабатывать cookie, и в этом вы сами сможете убедиться в следующем примере, хотя наиболее наглядно это будет представлено в ходе демонстрационной атаки на веб-сайт WordPress, которую мы проведем в разделе «Взлом HTML-формы аутентификации методом перебора» далее. Для выполнения HTTP-запроса проделайте следующее:

import requests
url = 'http://boodelyboo.com'
response = requests.get(url) # GET
data = {'user': 'tim', 'passwd': '31337'}
response = requests.post(url, data=data) # POST 
print(response.text) # response.text = string; response.content = bytestring 

Создаем url, request и словарь data с ключами user и passwd. Затем отправляем запрос методом POST и выводим атрибут text (строку). Если вы предпочитаете работать с байтовыми строками, используйте атрибут content, возвращенный вместе с ответом. Пример этого будет показан в разделе «Взлом HTML-формы аутентификации методом перебора».

Пакеты lxml и BeautifulSoup

Для разбора содержимого полученного HTTP-ответа подойдет пакет lxml или BeautifulSoup. За последние несколько лет эти два пакета стали более похожими, вы можете применять синтаксический анализатор lxml в сочетании с BeautifulSoup, равно как и синтаксический анализатор BeautifulSoup в сочетании с lxml. Другие хакеры используют в своем коде и тот, и другой пакет. У lxml синтаксический анализатор чуть быстрее, а у BeautifulSoup предусмотрена логика для автоматического обнаружения кодировки заданной HTML-страницы. Здесь мы будем работать с lxml. Оба пакета можно установить с помощью pip:

pip install lxml
pip install beautifulsoup4

Допустим, вы сохранили HTML-код, возвращенный внутри ответа, в переменную content. С помощью lxml можете извлечь из него ссылки, как показано далее:
from io import BytesIO

from lxml import etree
import requests
url = 'https://nostarch.com
r = requests.get(url) # GET
content = r.content # content имеет тип bytes
parser = etree.HTMLParser()
content = etree.parse(BytesIO(content), parser=parser) # преобразуем в дерево 
for link in content.findall('//a'): # находим все ссылки (элементы "a") 
   print(f"{link.get('href')} -> {link.text}") 

Импортируем класс BytesIO из модуля io, он позволит нам использовать байтовую строку в качестве файлового объекта при разборе HTTP-ответа. Затем, как и раньше, выполняем GET-запрос и разбираем ответ с помощью синтаксического HTML-анализатора lxml. Анализатор принимает на вход объект-дескриптор или имя файла. Класс BytesIO превратит возвращенную байтовую строку в объект-дескриптор, который можно будет передать синтаксическому анализатору lxml. Мы применяем простой запрос для поиска всех тегов a (ссылок), содержащихся в возвращенном ответе, и выводим результаты. Каждый тег a определяет ссылку. Его атрибут href содержит URL-адрес этой ссылки.

Обратите внимание на использование f-строки, которая на самом деле выполняет запись. В Python версии 3.6 и выше f-строки можно использовать для создания строк с переменными, заключенными в фигурные скобки. Это, к примеру, позволяет легко включить в строку результат вызова функции (link.get('href')) или обычное значение (link.text).

Такого же рода разбор можно выполнить и с помощью BeautifulSoup, используя следующий код. Как видите, это очень похоже на предыдущий пример на основе lxml:

from bs4 import BeautifulSoup as bs
import requests
url = 'http://bing.com'
r = requests.get(url)
tree = bs(r.text, 'html.parser') # преобразуем в дерево 
for link in tree.find_all('a'): # находим все ссылки (элементы "a") 
print(f"{link.get('href')} -> {link.text}")

Синтаксис почти идентичен. Мы преобразуем содержимое в дерево, перебираем ссылки (теги a) и выводим соответствующие адреса (атрибут href) и текст (link.text).

Если вы работаете на взломанном компьютере, вам, вероятно, придется отказаться от установки всех этих сторонних пакетов, чтобы не поднимать слишком много шума в сети. Таким образом, вы будете использовать то, что под рукой, — например, минимальные версии Python 2 или Python 3. Это означает, что придется ограничиться стандартной библиотекой (urllib2 или urllib соответственно).

В следующих примерах мы исходим из того, что вы используете для взлома собственный компьютер, следовательно, можете соединяться с веб-серверами с помощью пакета requests и разбирать полученный вывод с применением lxml.

Итак, вы получили базовые средства для взаимодействия с веб-сервисами и веб-сайтами. Теперь создадим инструментарий, который будет полезен для атаки или тестирования на проникновение любого веб-приложения.

Получение структуры каталогов веб-приложений с открытым исходным кодом

Системы управления контентом (content management systems, CMS) и платформы для блогов, такие как Joomla, WordPress и Drupal, делают процесс создания блога или веб-сайта простым. Они пользуются довольно высокой популярностью в средах виртуального хостинга и даже в корпоративных сетях. У любой системы есть свои нюансы в плане установки, конфигурации и управления патчами, и пакеты CMS — не исключение. То, что перегруженный системный администратор или незадачливый разработчик не до конца соблюдает все процедуры обеспечения безопасности и установки ПО, может упростить взломщику получение доступа к веб-серверу.

Мы можем скачать любое веб-приложение с открытым исходным кодом и локально проанализировать его файлы и структуру каталогов. Это позволяет создать специализированный сканер, способный находить все файлы, доступные на удаленном компьютере. Таким образом можно избавиться от файлов, оставшихся после установки, защитить с помощью файлов .htaccess каталоги, требующие этого, и позаботиться о прочих нюансах, которые могут позволить взломщику проникнуть на веб-сервер.

В этом проекте мы также познакомимся с объектом Python Queue, позволяющим создавать большие потокобезопасные очереди, элементы которых обрабатываются разными потоками. Это сделает наш сканер очень быстрым. К тому же не нужно будет волноваться о состояниях гонки, так как очередь, в отличие от списка, будет потокобезопасной.

Более подробно с книгой можно ознакомиться на сайте издательства
» Оглавление
» Отрывок

Для Хаброжителей скидка 25% по купону — Python

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.

Tags:
Hubs:
Total votes 8: ↑4 and ↓4+2
Comments3

Articles

Information

Website
piter.com
Registered
Founded
Employees
201–500 employees
Location
Россия