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

Статья Обфускация с рандомизацией HTML-писем с использованием Node.js

kidkdk

(L3) cache
Забанен
Регистрация
28.05.2022
Сообщения
199
Решения
1
Реакции
78
Пожалуйста, обратите внимание, что пользователь заблокирован
Автор kidkdk
Источник https://xss.pro/threads/133743/

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

Введение

Многие люди, которые занимались или занимаются E-mail спамом зачастую испытывают большие затруднения при отправке писем - рассылка даже на маленьких объёмах может быть очень быстро забанена. А для успеха рассылки на больших объёмах требуется достаточное количество чистых качественных расходников. Поэтому суммарные затраты на отправку миллиона писем могут достигать 500$, и даже 1000$. Соответственно по многим причинам рассылка может просто не окупиться, и затратив большое количество времени на тесты и подготовку расходников можно получить разочарование.

Данный материал поможет вам найти решение как значительного упрощения, так и снижения затрат на рассылку путём превращения ваших писем из "спамерских" в "обычные".

I. Разбор кода

1. Рандомизация при помощи создания скрытых слов в боди, как метод добавления шумов. Создает <span> и <div> теги в письме, делая их невидимыми для получателя

JavaScript:
const safeWords = [ // Cлова для заголовков и скрытых блоков
    'news', 'update', 'info', 'alert', 'notice', 'message',
    'reminder', 'notification', 'report', 'summary'];
const generatorTexts = (minWords = 2, maxWords = 5) => {
    const count = Math.floor(Math.random() * (maxWords - minWords + 1)) + minWords;
    const words = [shreksosetbibu];
    while (words.length < count) {
        const word = safeWords[Math.floor(Math.random() * safeWords.length)];
        words.push(word);
    }
    return words.join(' ');
};

2. Изменение порядка CSS-тегов случайным образом. Изменяется style="*" в HTML верстке.
JavaScript:
const shuffleStyles = (styleString) => {
    const styles = styleString.split(';').filter(s => s.trim()); // Разделяем стили и убираем пустые
    for (let i = styles.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1)); // Случайный индекс
        [styles[i], styles[j]] = [styles[j], styles[i]]; // Меняем местами
    }
    return styles.join(';') + ';'; // Собираем обратно в строку
};

3. Добавление элементов в текст. Непроизвольное добавление тега <span> в тексте
JavaScript:
const randomSpans = (text) => { // Рандомизация span-тегов в тексте
    let result = '';
    let i = 0;
    while (i < text.length) {
        if (Math.random() < 0.3 && i < text.length - 1) { // 30% вероятность обертки
            const length = Math.floor(Math.random() * 2) + 1; // через 1-2 символа
            result += `<span>${text.substr(i, length)}</span>`;
            i += length;
        } else {
            result += text[i++];
        }
    }
    return result;
};

4. Основной функционал по развертке и созданию 100,000 вариантов при по помощи шаблона.
JavaScript:
async function generateEmails() {
    try {
        const htmlTemplate = fs.readFileSync(inputFile, 'utf8');
        if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);

        for (let i = 1; i <= 100000; i++) {
            const $ = cheerio.load(htmlTemplate);        
            $('title').text(generatorTexts());
            const hiddenContent = `
                <div style="display:none;font-size:0;line-height:0;">
                    ${generatorTexts(5, 10)}
                    <span style="color:transparent">${Math.random().toString(36).substr(2)}</span>
                </div>`;
            $('body').prepend(hiddenContent);
            $('body').append(hiddenContent);
            $('[style]').each((_, el) => {
                const $el = $(el);
                const style = $el.attr('style');
                if (style) {
                    $el.attr('style', shuffleStyles(style));
                }
            });
            $('body *').contents().each((_, el) => {
                if (el.type === 'text' && !$(el).parent().is('style, script')) {
                    const processed = randomSpans($(el).text());
                    if (processed !== $(el).text()) {
                        $(el).replaceWith($.html(processed));
                    }
                }
            });
            fs.writeFileSync(
                path.join(outputDir, `email_${i}.html`),
                $.html()
            );

            if (i % 1000 === 0) console.log(`Generated ${i} files...`);
        }
        console.log(`Generated ${i} files in ${outputDir}/`);
    } catch (error) {
        process.exit(1);
    }
}
generateEmails();

II. Небольшое лирическое отступление

Речь пойдет про спам баллы связанные с адресатом From. Засылать письма можно разными способами: шеллы/смтп/бота/своиподсети/акки , в этом и конкретно плюс. Вариантов различное множество, но какой выбрать зависит от ваших потребностей/целей. И так, для того чтобы попасть в инбокс нужно набрать к примеру 100 баллов. Скажем у Яндекса доверие к почтам Маил ру 70 очков, маил - маил 50 очков, рамблер - гмаил 10 очков. Яндекс - гмаил 50 очков, маил - гмаил 30 очков. Это все сугубо мое мнение без прогрева, помимо этого есть множество мелких почтовиков EU стран, где доверие гмаил 100 баллов и любое письмо в инбокс. В связи с этим нужны определенные связи, прокачка почт либо доменов, айпи адресов, высылкой писем на свои почты или таргет базы.

Далее ссылки, трастовые домены +50 очков, заспамленные домены -50 соответственно. Хороший айпи +25, грязный -25. И так далее, собирайте качественный шаблон хтмл, с разными тегами, уникальным объемным текстом, что может помочь засылать даже с новых доменом в инбокс.

III. Примеры работы функционала

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

1.png

2.png



Здесь можно понять, что структура письма никак не затронута, а добавляются лишь скрытые теги. Сюда же можно добавить аналогично и замену тегов, например с <p> на <div>, <strong> = <b> и так далее, но нужны наработки к определенным шабам. Тот скрипт что отправил я, работает на большинстве шаблонов без ошибок, будь то таблицы, дивы и т.п.

IV. Что умеем и имеем

Обфускацию слов в письме с помощью скрытых тегов <span>, рандомизацию тайтлов, CSS тегов. Что уже позволит создавать как минимум 100,000 уникальных писем для рассылки с различными HTML. Пониманием факторов влияющих на попадания в Inbox, но также хочу сказать не одним инбоксом едины, есть почтовые домены куда невозможно заслать в инбокс, а в спам очень даже конвертит. Либо же наоборот спам ничего не даст, только инбокс. Необходимые связки приходят только с опытом и разбором происходящего. И не забывайте прогревать домены и айпи адреса, рандомизацию текста также никто не отменял.

V. Финал

Здесь содержится собранный код из вышеупомянутых огрызков, а также письмо html с которым работали
JavaScript:
const fs = require('fs');
const path = require('path');
const cheerio = require('cheerio');
const inputFile = process.argv[2];
const outputDir = path.parse(inputFile).name;
const safeWords = [ // Cлова для заголовков и скрытых блоков
    'news', 'update', 'info', 'alert', 'notice', 'message',
    'reminder', 'notification', 'report', 'summary'];
const generatorTexts = (minWords = 2, maxWords = 5) => {
    const count = Math.floor(Math.random() * (maxWords - minWords + 1)) + minWords;
    while (words.length < count) {
        const word = safeWords[Math.floor(Math.random() * safeWords.length)];
        words.push(word);
    }
    return words.join(' ');
};
const shuffleStyles = (styleString) => { // Рандомизация порядка CSS-свойств
    const styles = styleString.split(';').filter(s => s.trim()); // Разделяем стили и убираем пустые
    for (let i = styles.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1)); // Случайный индекс
        [styles[i], styles[j]] = [styles[j], styles[i]]; // Меняем местами
    }
    return styles.join(';') + ';'; // Собираем обратно в строку
};
const randomSpans = (text) => { // Рандомизация span-тегов в тексте
    let result = '';
    let i = 0;
    while (i < text.length) {
        if (Math.random() < 0.3 && i < text.length - 1) { // 30% вероятность обертки
            const length = Math.floor(Math.random() * 2) + 1; // 1-2 символа
            result += `<span>${text.substr(i, length)}</span>`;
            i += length;
        } else {
            result += text[i++];
        }
    }
    return result;
};
// Основная функция
async function generateEmails() {
    try {
        const htmlTemplate = fs.readFileSync(inputFile, 'utf8');
        if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);

        for (let i = 1; i <= 100000; i++) {
            const $ = cheerio.load(htmlTemplate);        
            $('title').text(generatorTexts());
            const hiddenContent = `
                <div style="display:none;font-size:0;line-height:0;">
                    ${generatorTexts(5, 10)}
                    <span style="color:transparent">${Math.random().toString(36).substr(2)}</span>
                </div>`;
            $('body').prepend(hiddenContent);
            $('body').append(hiddenContent);
            $('[style]').each((_, el) => {
                const $el = $(el);
                const style = $el.attr('style');
                if (style) {
                    $el.attr('style', shuffleStyles(style));
                }
            });
            $('body *').contents().each((_, el) => {
                if (el.type === 'text' && !$(el).parent().is('style, script')) {
                    const processed = randomSpans($(el).text());
                    if (processed !== $(el).text()) {
                        $(el).replaceWith($.html(processed));
                    }
                }
            });
            fs.writeFileSync(
                path.join(outputDir, `email_${i}.html`),
                $.html()
            );

            if (i % 1000 === 0) console.log(`Generated ${i} files...`);
        }
        console.log(`Generated ${i} files in ${outputDir}/`);
    } catch (error) {
        process.exit(1);
    }
}
generateEmails();

Создает папку с названием вашего .html файла, а также необходимо установить инструментарий nodejs на вашу ОС

Для MacOS: (предварительно установив менеджер пакетов homebrew)
brew install node

Ubuntu/Debian:
sudo apt install nodejs npm

Windows:
Link

После распаковки ноды, установите зависимость cheerio
npm install cheerio

Затем запустите скрипт в папке с письмом
node script.js filename.html

Файлы используемые в статье Скачать
На этом все. Я считаю рандомизация HTML сильно влияет на попадание в инбокс практически любого спам-фильтра, это крайне важно в текущих реалиях и весьма достижимо благодаря некоторым наработкам. Всем спасибо
 
JavaScript:
const words = [safeWords];
while (words.length < count) {
const word = safeWords[Math.floor(Math.random() * safeWords.length)];
words.push(word);
}
return words.join(' ');
};
95.jpg
 
words = [safeWords] doesn’t do what you likely intended. That actually puts the entire safeWords array as the first element of words. So your first “word” is [ 'news', 'update', 'info' ...], which'll serialize to something messy/nonsensical. You probably meant to start with an empty array, like const words = [], then push strings into it? Or did you not verify if the "random title” piece even works properly?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
words = [safeWords] doesn’t do what you likely intended. That actually puts the entire safeWords array as the first element of words. So your first “word” is [ 'news', 'update', 'info' ...], which'll serialize to something messy/nonsensical. You probably meant to start with an empty array, like const words = [], then push strings into it? Or did you not verify if the "random title” piece even works properly?
abbc.png

body and title
 
Пожалуйста, обратите внимание, что пользователь заблокирован
run this for me console.log(generatorTexts())
 
за старания можно похвалить. а реализация, то такое.
<meta name="GENERATOR" content="MSHTML 11.00.10570.1001"></head>
я когда-то от нативного редактора AMS отказался что бы эта жуть в шаблон не попадала))

<div style="line-height:0;display:none;font-size:0;">
<span> </span><span> </span> <span> </span> <span> </span> <span> </span><span>ne</span>ws<span>,</span><span>up</span>date,in<span>fo</span><span>,</span>ale<span>rt</span>,n<span>o</span>ti<span>c</span>e,message,rem<span>in</span>d<span>e</span>r,n<span>o</span>t<span>i</span>ficati<span>o</span>n<span>,r</span>e<span>po</span>rt,su<span>m</span><span>m</span><span>ar</span>y <span>m</span><span>e</span>ssa<span>ge</span> upd<span>a</span>te news notifi<span>c</span><span>at</span>i<span>on</span> no<span>ti</span>ce s<span>um</span><span>m</span><span>ar</span><span>y</span> <span>ne</span>ws
<span> </span> <span> </span> <span> </span> <span style="color:transparent;"><span>d</span>shin3kn<span>v</span>7i</span>
<span> </span><span> </span> <span> </span> <span> </span> <span> </span> </div>
ТС, не обижайся, но как по мне, то это вредная и бесполезная обфускация, которая палится моментально.
Gmail такое давно уже прохавал, и, к слову, очень не любит. Mailru тоже самое.
тут неподалёку есть сервис, htmlmix, который в данном направлении ушел далеко вперёд.
советую присмотреться, и, возможно даже взять какие-то идеи. их там ахулиард реализовано.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
тут неподалёку есть сервис, htmlmix, который в данном направлении ушел далеко вперёд.
советую присмотреться, и, возможно даже взять какие-то идеи. их там ахулиард реализовано.
ты его тестил? хтмлмикс? он делает тоже самое через каждую букву, видимо даже не открывал письмо))
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Zerofonts реализован у него точно таким способом. За это он просит 100 или 150 в месяц. Здесь бесплатно, но ладно
 
Пожалуйста, обратите внимание, что пользователь заблокирован
ТС, за старания спасибо огромное, но правда в том что сейчас такие письма это 100% в папку спам или вообще баунс.
Баунсить или лететь в спам могут только от того, что код занимает 70+% письма, для этого и выстроены теги спан не через букву, а через 2-3
 
Пожалуйста, обратите внимание, что пользователь заблокирован
за старания можно похвалить. а реализация, то такое.
В целом мне думается, это не ваша тематика. помнится был курс 21г вместе с Терентьевым, Сойером, Гуд Сэмом и как спец по амс сес доктор. Ну и сравнивать бесплатный продукт с тем, где надо за каждый клик платить, немного странно..
 
ты его тестил? хтмлмикс? он делает тоже самое через каждую букву, видимо даже не открывал письмо))
конечно тестил. но он делает далеко не то-же самое. даже на этапе когда Боб его продавал просто как
скрипт на питоне, там уже было в разы больше функционала.

Zerofonts реализован у него точно таким способом. За это он просит 100 или 150 в месяц. Здесь бесплатно, но ладно
там можно отключить зерофонт, если он не нужен. а тут, по факту, кроме него больше ничего и нет.
а там уже апи работает. можно интегрировать другие скрипты и сервисы. поэтому цена полностью оправдана.
но я бы не стал сравнивать вещи, которые не сравниваются. я пример сервиса привёл только как возможность
брать оттуда идеи, потому что вариантов рандомизации хтмл-шаблонов не так уж и много.

В целом мне думается, это не ваша тематика. помнится был курс 21г вместе с Терентьевым, Сойером, Гуд Сэмом и как спец по амс сес доктор. Ну и сравнивать бесплатный продукт с тем, где надо за каждый клик платить, немного странно..
не моя тематика в чём?) ну да, я белые рассылки люблю и практикую, это правда.
и всем советую обязательно ими заниматься, если есть возможность.
но тут мы говорим за очевидные вещи, прямо такие, для которых в обще не нужны даже глубокие познания в рассылках.

Баунсить или лететь в спам могут только от того, что код занимает 70+% письма, для этого и выстроены теги спан не через букву, а через 2-3
он всё правильно написал. такой объём мусорных тегов - это чёрный пояс по спаму. инновации в этом нет.
очередная вариация на тему "я изобрёл велосипед". но опять таки, дареному коню в зубы не смотрят, как говорится.
возможно для кого-то это будет хорошим костылём и откровением в вопросе генерации писем.
как минимум, ты проделал работу и старался, никто тебя за это не хейтит, не подумай.
любая критика в данном деле - она во благо всегда.
мы здесь ради роста, а не ради выяснения, чей код хуже или лучше.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
но он делает далеко не то-же самое. даже на этапе когда Боб его продавал
Ок, я ни коем образом не обижаюсь, а наоборот поддерживаю любую конструктивную критику. В данном случае давайте разберем то, что делает этот сервис стоимостью 100$/месяц.

AI randomization(replace with synonyms) // Подобная функция есть в АМС, через Опенаи
Random table layout // Единственная полезная функция, на мой взгляд, из того, что я не добавил
Split words with inversion // Схожая с тем, что выше. Даже лучше

Остальное либо реализовано, либо есть адекватные альтернативы с помощью АМС. Из того, что видел в письмах у забугор спамеров, используется именно тот функционал, что и у меня. Ребята, посмотрите сколько стоит АМС, большинство из этого делается там, рандом хедеры, рандом текст через ИИ, pандомизация редиректов. все макросы поддерживаются, софт работает на лайфтайм подписке 20 лет и до сих пор обновляется. А весь этот сервис только для лентяев
 
Баунсить или лететь в спам могут только от того, что код занимает 70+% письма, для этого и выстроены теги спан не через букву, а через 2-3
Я повторюсь. Спасибо за старания, но у меня точно такое же есть, только на питоне. и через 4 и через 5 и через 6 букв - не важно. год-полтора назад ты был бы прав. сейчас нет.
 


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