Python в ИБ. Часть 1. Работаем с сетевыми сервисами.

Для чего годен Python?

Для всего что угодно. Данный язык нашёл активное применение в различных хакерских (ИБ) сферах: ревёрс, веб, криптография, написание эксплоитов и прочее. Данный язык встроен в один из самых мощных инструментов для хакера – IDA Pro (причём версия 2.7), поэтому знать этот язык необходимо. Многие задачи, встречающиеся в деятельности хакера можно автоматизировать. Python позволяет сделать это достаточно просто и быстро (в плане реализации), что также показывает необходимость его изучения.

Начальные знания.

Это не полный курс по Python с нуля и вообще не курс по Python. Данная рубрика скорее служит для введение в применения Python для упрощения задач хакинга. Предполагается, что вы уже знакомы с основами Python и умеете писать простые (а может и не очень) скрипты. Если же нет, но вам хочется познакомиться с этим языком и использовать его в хакинге, то вам нужно изучить основы Python (курсы, книга, видео на ютубе, самостоятельно), благо сейчас очень много источников, приведу пару, которые считаются наиболее простыми и основными:

  • курс на Stepik (https://stepik.org/course/67/)
  • Бесплатный курс прямо в браузере на одном сайте (https://pythontutor.ru/)

Ресурсов для изучения Python сейчас много, выбирайте любой, почти везде всё одинаково (только не выбирайте для детей, там обычно показывают как делать всякие простые игры и рисовать на экране).

Условно назовём посты “уроками”, каждый пост будет посвящён одной теме. Данная тема так или иначе относится к хакингу или рассматривается в контексте хакинга.

Урок №1. Основы взаимодействия с сетевыми сервисами.

В данном уроке мы разберём основы взаимодействия по сети с помощью Python 2.7. Речь пойдёт про сетевые сокеты.

Теория.

Кратко про сокеты (с википедии, оригинал тут, советую почитать)

Сокет (англ. socket — разъём) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.

Следует различать клиентские и серверные сокеты. Клиентские сокеты грубо можно сравнить с конечными аппаратами телефонной сети, а серверные — с коммутаторами. Клиентское приложение (например, браузер) использует только клиентские сокеты, а серверное (например, веб-сервер, которому браузер посылает запросы) — как клиентские, так и серверные сокеты.

Обобщим, сокет – есть интерфейс для взаимодействия между клиентом и сервером.

Сегодня мы поговорим о клиентских TCP-сокетах и научимся подключаться к серверу и взаимодействовать с ним. Для чего это может быть нужно? Ответов на этот вопрос очень много, например можно реализовать свой сканер портов (хотя зачем, если есть nmap), также можно реализовывать кастомные брутеры, например по не особо изученному сетевому протоколу, да и в целом, нужно иметь базовые представления и навыки о сетевом программировании, если вы хотите считаться хакером.

Теории в данной теме не много, поэтому перейдём сразу к практики, то есть к написанию кода.

Практика.

Сетевые сокеты представлены в Python 2.7 одноимённой библиотекой “socket” (документация библиотеки тут).

Подключим данную библиотеку с помощью “import socket” и создадим сокет (“socket.socket()”), с помощью которого можно подключаться к удалённым сервисам и взаимодействовать с ним (сокет сохраняется в переменную sock).

Отлично, правда пока наш код особо ничего не делает. Но мы уже имеем объект с помощью которого можем взаимодействовать по сети (это объект sock, имя может быть любое, надеюсь понятно).

Попробуем подключитmся к какому нибудь серверу, но к какому?

Возьмём например FTP (файловый сервер) яндекса и подключимся к нему. Для того чтобы куда-либо подключиться нам надо знать IP-адрес, порт подключения и протокол (по дефолту создаваемый сокет через socket.socket() использует обычный TCP). Адресом в нашем случае будет доменное имя “ftp.yandex.ru”, которое преобразуется в IP-адрес на DNS-сервере, а портом – стандартный порт для FTP – 21/TCP. Занесём данные в переменные.

Обратите внимание, что host (адрес подключения) всегда должен иметь тип “str” (то есть строковый), даже если у вас просто ip-адрес в виде “X.X.X.X.”, а порт всегда имеет тип “int” (целое число) и варьируется в переделах от 0-65535.

Теперь нам надо осуществить подключение, это можно сделать с помощью функции connect (обратите внимание на специфичность передачи аргументов в функцию).

Дело в том, что данная функция принимает 1 аргумент – это кортеж (вспоминаем типы данных в Python), состоящий из 2-ух элементов, на первом месте (индекс 0) стоит адрес (тип строковый), на втором месте (индекс 1) стоит порт (тип целочисленный).

После успешного завершения работы данной функции (она может завершится не успешно, тогда произойдёт исключение связанное с ошибкой подключения по какой-либо причине, например временное ограничение) устанавливается соединение между нашим клиентом и сервером. Теперь обмен информацией возможен.

Обмен сообщениями представлен двумя методами – отправить сообщение, принять сообщение. Кракто рассмотрим каждый из них.

Отправить сообщение.

Данная возможность реализуется с помощью метода send(). Метод принимает один аргумент – строку (по сути любые данные превращаются в набор байт, который можно представить в виде строки) и отправляет её на сервер, вот и всё.

На изображении выше идёт отправка строки “Hello” и символа перевода строки на сервер.

Принять сообщение.

Данная возможность реализуется с помощью метода recv(). Метод принимает один аргумент – размер принимаемого сообщения и возвращает принятое сообщение, поэтому данный метод чаще всего вызывается подобным образом (прнимается сообщение максимальной длиной 1024 байта)

Для сохранения данных в некоторый буфер с последюущей обработкой. Если же вам не надо обрабатывать данные, а нужно лишь посмотреть, что возвращается, то можно испльзовать его вот так.

В данном методе много подводных камней, связанных с протоколом TCP (например можно указать большой размер данных, но в итоге принять не совсем то, что ожидалось), но в этом уроке мы их опустим. Стоит отметить, что число передаваемое в recv обозначает максимальное количество байт, которые будут приняты и возвращены. То есть может вернуться и меньше.

Полный пример.

Итак, мы поняли как создать клиентский сокет, подключиться с помощью него и как принимать и отправлять данные. Объединим всё это в один небольшой скрипт, который будет подключаться к файловому серверу яндекса принимать от туда сообщение и отправлять сообщение “Hello” с переводом строки, после чего опять принимать сообщение от сервера.

Запустим данный код.

Видим, что первое принятое сообщение – является приветствием и мы понимаем, что мы верно подключились туда, куда хотели. После отправки нашего сообщение сервер сообщил нам, что нам надо залогиниться.

После завершения сетевого взаимодействия правилом хорошего кода, считается самостоятельно закрывать сокет, это можно сделать с помощью метода “close”, также это необходимо делать, если в дальнейшем вы будете использовать имя сокета в других местах кода или захотите создать новое подключение с этого же сокета. Добавьте в конце кода (17 строка) следующую строчку.

И всё, наш простой скрипт готов.

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

Вас ебали, ебут и будут ебать. Государство, хакеры, чиновники.
Остановить эту свингер-пати невозможно. Но мы научим предохраняться.
Следите за новостями на нашем канале @cybersecs или на сайте
cybersec.org