first commit

This commit is contained in:
keklick1337
2025-03-02 13:16:37 +04:00
commit 3e5ad3972d
4 changed files with 404 additions and 0 deletions

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright 2025 Vladislav Tislenko
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

110
README.md Normal file
View File

@@ -0,0 +1,110 @@
# StealthHTML
Hey, welcome to **StealthHTML**! This little tool is all about scrambling your HTML code to make it a bit more... sneaky. Want to keep your code under wraps or just throw off anyone trying to peek under the hood? StealthHTMLs here to help you turn your HTML into a cryptic masterpiece, all while keeping it looking normal on the surface.
## Whats This All About?
HTML obfuscation is like putting your code through a blender—it still works and looks the same, but good luck to anyone trying to figure it out. Whether youre hiding something clever or just having a laugh, StealthHTML throws in tricks like invisible characters, random junk, and shuffled styles to keep things interesting.
## Cool Stuff It Does
StealthHTMLs got a bunch of neat features to play with:
- **Random Text**: Generates innocent-looking filler text from safe word lists.
- **Invisible Characters**: Slips in zero-width characters to spice things up without changing the look.
- **CSS Shuffle**: Jumbles your CSS properties so its a total guessing game.
- **Extra Bits**: Adds random classes, IDs, and hidden elements to throw people off.
- **Link & Image Twists**: Tosses in random link parameters and sneaky invisible images.
- **Word Lists**: Pick from `general`, `technical`, or `marketing` dictionaries to match your style.
- **Your Rules**: Tweak how wild you want the obfuscation to get.
## How to Get It Running
Setting up is super simple:
1. **Grab the Code**:
```bash
git clone https://github.com/keklick1337/StealthHTML.git
```
2. **Jump In**:
```bash
cd StealthHTML
```
3. **Load It Up**:
```bash
pip install -r requirements.txt
```
## How to Use It
Once youre good to go, its a piece of cake:
- **Make a Sneaky File**:
```bash
python stealthhtml.py input.html -o output.html
```
This spits out a scrambled `output.html` from your `input.html`.
- **Quick Peek**:
```bash
python stealthhtml.py input.html
```
See the magic right in your terminal.
### Tweak It Your Way
Youve got options to mess with the obfuscation:
- `--min_words`: Shortest random text length. (Default: 2 words)
- `--max_words`: Longest random text length. (Default: 5 words)
- `--invisible_char_prob`: Chance of sneaking in invisible characters. (Default: 15%)
- `--span_prob`: Odds of tossing in a hidden `<span>`. (Default: 40%)
- `--comment_count`: How many random comments to add. (Default: 1)
- `--meta_count`: Number of extra meta tags. (Default: 1)
- `--table_count`: How many hidden tables to sneak in. (Default: 1)
- `--style_count`: Number of random style tags. (Default: 1)
- `--image_count`: How many invisible images to drop. (Default: 1)
- `--script_count`: Number of random script tags. (Default: 1)
- `--rare_tag_count`: How many weird tags (like `<article>`) to throw in. (Default: 1)
- `--header_count`: Number of hidden headers (like `<h1>`) to add. (Default: 1)
- `--dictionary`: Word list to use: `general`, `technical`, or `marketing`. (Default: `general`)
## Some Fun Examples
Heres how you might play around with it:
1. **Basic Scramble**:
```bash
python stealthhtml.py template.html -o obfuscated.html
```
Turns `template.html` into a sneaky `obfuscated.html`.
2. **Custom Chaos**:
```bash
python stealthhtml.py template.html -o obfuscated.html --comment_count 3 --dictionary technical --invisible_char_prob 0.2
```
Adds 3 comments, uses techy words, and ups the invisible character chance to 20%.
3. **Terminal Teaser**:
```bash
python stealthhtml.py template.html
```
Shows off the scrambled HTML in your console.
## Wanna Chip In?
Love to have you onboard! Heres how to contribute:
1. Fork the repo.
2. Start a new branch (`git checkout -b cool-idea`).
3. Make your tweaks and commit (`git commit -m 'Added something awesome'`).
4. Push it up (`git push origin cool-idea`).
5. Open a pull request.
Just keep it clean and maybe toss in some tests if you can.
## License
This is under the [MIT License](LICENSE). Use it, tweak it, share it—just give a nod back to us.

286
generate_emails.py Executable file
View File

@@ -0,0 +1,286 @@
#!/usr/bin/env python3
# HTML Obfuscator by Vladislav Tislenko aka keklick1337
import copy
import os
import random
import string
import argparse
from bs4 import BeautifulSoup, Comment
# Dictionaries of safe words
DICTIONARIES = {
'general': [
'news', 'update', 'info', 'alert', 'notice', 'message', 'reminder', 'notification',
'report', 'summary', 'announcement', 'bulletin', 'memo', 'brief', 'digest', 'release',
'statement', 'communication', 'dispatch', 'correspondence', 'letter', 'note', 'post',
'article', 'piece', 'item', 'story', 'feature', 'column', 'editorial'
],
'technical': [
'code', 'system', 'data', 'network', 'server', 'software', 'hardware', 'update',
'patch', 'bug', 'feature', 'release', 'version', 'protocol', 'interface', 'module',
'function', 'algorithm', 'process', 'thread', 'query', 'database', 'backup', 'log',
'monitor', 'config', 'deploy', 'test', 'build', 'compile'
],
'marketing': [
'offer', 'deal', 'sale', 'discount', 'promo', 'gift', 'bonus', 'special', 'event',
'campaign', 'launch', 'product', 'service', 'brand', 'exclusive', 'limited', 'free',
'trial', 'benefit', 'value', 'opportunity', 'package', 'subscription', 'plan',
'feature', 'highlight', 'trend', 'news', 'update', 'announce'
]
}
# Safe fonts
SAFE_FONTS = [
'Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia',
'Trebuchet MS', 'Comic Sans MS', 'Impact', 'Lucida Sans'
]
# Function to generate random text
def generate_random_text(min_words=2, max_words=5, dictionary='general'):
count = random.randint(min_words, max_words)
return ' '.join(random.choice(DICTIONARIES[dictionary]) for _ in range(count))
# Function to generate a random class or ID name
def generate_random_class():
return ''.join(random.choices(string.ascii_lowercase, k=random.randint(5, 10)))
# Function to generate a random color
def generate_random_color():
return random.choice([
f"#{random.randint(0, 255):02x}{random.randint(0, 255):02x}{random.randint(0, 255):02x}",
f"rgb({random.randint(0, 255)}, {random.randint(0, 255)}, {random.randint(0, 255)})"
])
# Function to shuffle CSS properties
def shuffle_styles(style_string):
styles = [s.strip() for s in style_string.split(';') if s.strip()]
random.shuffle(styles)
return '; '.join(styles) + ';'
# Function to create a random hidden element
def insert_random_hidden_element(soup, dictionary='general'):
hidden_span = soup.new_tag('span', style='font-size:0px; display:inline;')
hidden_span.string = generate_random_text(1, 3, dictionary)
hidden_span['class'] = generate_random_class()
hidden_span['id'] = generate_random_class()
hidden_span[f'data-{generate_random_class()}'] = str(random.randint(0, 1000))
return hidden_span
# Function to insert invisible characters
def insert_invisible_chars(text, invisible_char_prob=0.15):
invisible_chars = ['\u200B', '\u200C', '\u200D', '\uFEFF', '\u2060']
result = ''
for char in text:
result += char
if random.random() < invisible_char_prob:
result += random.choice(invisible_chars)
return result
# Function to add random attributes
def add_random_attributes(tag):
if random.random() < 0.6:
tag['class'] = ' '.join([generate_random_class() for _ in range(random.randint(1, 3))])
if random.random() < 0.4:
tag['data-' + generate_random_class()] = str(random.randint(0, 1000))
if random.random() < 0.2:
tag['id'] = generate_random_class()
# Function to insert random comments
def insert_random_comments(soup, count=1, dictionary='general'):
for _ in range(count):
comment = Comment(generate_random_text(3, 7, dictionary))
soup.body.insert(random.randint(0, len(soup.body.contents)), comment)
# Function to add random meta tags
def add_random_meta(soup, count=1, dictionary='general'):
for _ in range(count):
meta = soup.new_tag('meta')
meta['name'] = generate_random_class()
meta['content'] = generate_random_text(1, 3, dictionary)
soup.head.append(meta)
# Function to add random parameters to links
def add_random_link_params(soup):
for a in soup.find_all('a', href=True):
if '?' not in a['href']:
a['href'] += '?' + '&'.join(f"{generate_random_class()}={random.randint(0, 999)}" for _ in range(random.randint(1, 3)))
# Function to insert random tables
def insert_random_tables(soup, count=1, dictionary='general'):
for _ in range(count):
table = soup.new_tag('table', style=f'display:none;color:{generate_random_color()};font-family:{random.choice(SAFE_FONTS)};')
for _ in range(random.randint(1, 3)):
tr = soup.new_tag('tr')
for _ in range(random.randint(1, 3)):
td = soup.new_tag('td')
td.string = generate_random_text(1, 2, dictionary)
tr.append(td)
table.append(tr)
soup.body.append(table)
# Function to add random styles
def add_random_styles(soup, count=1):
for _ in range(count):
style_tag = soup.new_tag('style')
style_tag.string = f".{generate_random_class()} {{ {shuffle_styles(f'color:{generate_random_color()};display:none;font-family:{random.choice(SAFE_FONTS)};')} }}"
soup.head.append(style_tag)
# Function to add random images
def add_random_images(soup, count=1):
for _ in range(count):
img = soup.new_tag('img', src='data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', style=f'display:none;border:{random.randint(0, 1)}px solid {generate_random_color()};')
soup.body.append(img)
# Function to add random scripts
def add_random_scripts(soup, count=1, dictionary='general'):
for _ in range(count):
script = soup.new_tag('script')
script.string = f"// {generate_random_text(3, 7, dictionary)}"
soup.body.append(script)
# Function to insert random rare tags
def insert_random_rare_tags(soup, count=1, dictionary='general'):
rare_tags = ['article', 'section', 'footer', 'aside', 'nav']
for _ in range(count):
tag = soup.new_tag(random.choice(rare_tags), style=f'display:none;color:{generate_random_color()};font-family:{random.choice(SAFE_FONTS)};')
tag.string = generate_random_text(2, 4, dictionary)
soup.body.insert(random.randint(0, len(soup.body.contents)), tag)
# Function to insert random headers
def insert_random_headers(soup, count=1, dictionary='general'):
for _ in range(count):
header = soup.new_tag(f'h{random.randint(1, 6)}', style=f'display:none;color:{generate_random_color()};font-size:0;')
header.string = generate_random_text(2, 5, dictionary)
soup.body.append(header)
# Main function to generate the email
def generate_emails(args):
input_file = args.input_file
output = args.output
min_words = args.min_words
max_words = args.max_words
invisible_char_prob = args.invisible_char_prob
span_prob = args.span_prob
comment_count = args.comment_count
meta_count = args.meta_count
table_count = args.table_count
style_count = args.style_count
image_count = args.image_count
script_count = args.script_count
rare_tag_count = args.rare_tag_count
header_count = args.header_count
dictionary = args.dictionary
with open(input_file, 'r', encoding='utf-8') as f:
html_template = f.read()
soup = BeautifulSoup(html_template, 'html.parser')
# Randomizing the title
title = soup.find('title')
if title:
title.string = insert_invisible_chars(generate_random_text(min_words, max_words, dictionary), invisible_char_prob)
# Hidden content with randomization
hidden_div = soup.new_tag('div', style=f"display:none;font-size:0;line-height:0;{shuffle_styles(f'opacity:0;color:{generate_random_color()};font-family:{random.choice(SAFE_FONTS)}')}")
hidden_div.string = insert_invisible_chars(generate_random_text(5, 10, dictionary), invisible_char_prob)
hidden_span = soup.new_tag('span')
hidden_span.string = str(random.random())
hidden_div.append(hidden_span)
body = soup.find('body')
if body:
body.insert(0, hidden_div)
body.append(copy.deepcopy(hidden_div)) # Clone to add at the end
# Shuffling styles
for el in soup.find_all(style=True):
el['style'] = shuffle_styles(el['style'])
# Randomizing text while preserving <p> tag structure
for p_tag in soup.find_all('p'):
text_nodes = [node for node in p_tag.contents if isinstance(node, str)]
if not text_nodes:
continue
new_content = []
for text in text_nodes:
words = text.split()
for i, word in enumerate(words):
new_content.append(soup.new_string(insert_invisible_chars(word, invisible_char_prob)))
if random.random() < span_prob:
hidden_element = insert_random_hidden_element(soup, dictionary)
new_content.append(hidden_element)
if i < len(words) - 1:
new_content.append(soup.new_string(' ')) # Preserve spaces
# Clear the content of <p> and add new content
p_tag.clear()
for item in new_content:
p_tag.append(item)
# Adding random attributes to all tags
for tag in soup.find_all():
add_random_attributes(tag)
# Inserting random comments
insert_random_comments(soup, comment_count, dictionary)
# Inserting random empty tags
for _ in range(random.randint(1, 4)):
empty_tag = soup.new_tag(random.choice(['div', 'span', 'p']), style=shuffle_styles(f'display:none;opacity:0;color:{generate_random_color()};'))
soup.body.insert(random.randint(0, len(soup.body.contents)), empty_tag)
# Adding random meta tags
add_random_meta(soup, meta_count, dictionary)
# Randomizing links
add_random_link_params(soup)
# Inserting random tables
insert_random_tables(soup, table_count, dictionary)
# Adding random styles
add_random_styles(soup, style_count)
# Adding random images
add_random_images(soup, image_count)
# Adding random scripts
add_random_scripts(soup, script_count, dictionary)
# Adding random rare tags
insert_random_rare_tags(soup, rare_tag_count, dictionary)
# Adding random headers
insert_random_headers(soup, header_count, dictionary)
# Save the file or print to stdout
if output == '-':
print(str(soup))
else:
os.makedirs(os.path.dirname(output) or '.', exist_ok=True)
with open(output, 'w', encoding='utf-8') as f:
f.write(str(soup))
print(f"Saved to {output}")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Generator of randomized HTML emails to bypass spam filters')
parser.add_argument('input_file', help='Path to the input HTML file')
parser.add_argument('-o', '--output', default='-', help='Output file path (default: - for stdout)')
parser.add_argument('--min_words', type=int, default=2, help='Minimum number of words in generated text (default: 2)')
parser.add_argument('--max_words', type=int, default=5, help='Maximum number of words in generated text (default: 5)')
parser.add_argument('--invisible_char_prob', type=float, default=0.15, help='Probability of inserting an invisible character (default: 0.15)')
parser.add_argument('--span_prob', type=float, default=0.4, help='Probability of inserting a span tag (default: 0.4)')
parser.add_argument('--comment_count', type=int, default=1, help='Number of random comments (default: 1)')
parser.add_argument('--meta_count', type=int, default=1, help='Number of random meta tags (default: 1)')
parser.add_argument('--table_count', type=int, default=1, help='Number of random tables (default: 1)')
parser.add_argument('--style_count', type=int, default=1, help='Number of random styles (default: 1)')
parser.add_argument('--image_count', type=int, default=1, help='Number of random images (default: 1)')
parser.add_argument('--script_count', type=int, default=1, help='Number of random scripts (default: 1)')
parser.add_argument('--rare_tag_count', type=int, default=1, help='Number of random rare tags (default: 1)')
parser.add_argument('--header_count', type=int, default=1, help='Number of random headers (default: 1)')
parser.add_argument('--dictionary', choices=['general', 'technical', 'marketing'], default='general', help='Dictionary for text generation (default: general)')
args = parser.parse_args()
generate_emails(args)

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
beautifulsoup4