diff --git a/wsuks/lib/argparser.py b/wsuks/lib/argparser.py index 7b37be0..bef9ac2 100644 --- a/wsuks/lib/argparser.py +++ b/wsuks/lib/argparser.py @@ -47,6 +47,7 @@ def initParser(): advanced.add_argument("--WSUS-Server", metavar="", dest="wsusHost", help="IP or DNS name of the WSUS Server.") advanced.add_argument("--WSUS-Port", metavar="", dest="wsusPort", type=int, help="Port of the WSUS Server. (DEFAULT: 8530 for HTTP, 8531 for HTTPS)") advanced.add_argument("--tls-cert", metavar="", dest="tlsCert", help="Path to a TLS certificate that is valid for the WSUS Server. Turns on HTTPS mode.") + advanced.add_argument("--tls-cert-key", metavar="", dest="tlsCertKey", help="Path to a TLS certificate private key that is valid for the WSUS Server. Turns on HTTPS mode.") webserver = mode_parser.add_argument_group("SERVE ONLY MODE", "Only run Webserver. Recommended if you have control over DNS and the traffic comes directly from the victim to your machine.") webserver.add_argument("--serve-only", action="store_true", help="Serve the executable and command without any arp spoofing, network magic or WSUS discovery.") diff --git a/wsuks/wsuks.py b/wsuks/wsuks.py index 0d1b377..a531302 100644 --- a/wsuks/wsuks.py +++ b/wsuks/wsuks.py @@ -4,6 +4,7 @@ import os from pprint import pformat import random +import re from string import digits, ascii_letters import sys from scapy.all import get_if_addr @@ -140,11 +141,34 @@ def run(self): if not os.path.isfile(self.args.tlsCert): self.logger.error(f"TLS certificate file '{self.args.tlsCert}' not found! Exiting...") exit(1) + + if self.args.tlsCertKey and not os.path.isfile(self.args.tlsCertKey): + self.logger.error(f"TLS certificate Key file '{self.args.tlsCertKey}' not found! Exiting...") + exit(1) + self.logger.info(f"Using TLS certificate '{self.args.tlsCert}' for HTTPS WSUS Server") - context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - context.load_cert_chain(certfile=self.args.tlsCert) - context.check_hostname = False - http_server.socket = context.wrap_socket(http_server.socket, server_side=True) + + # checking if the cert has the private key baked within the cert + # https://docs.python.org/3/library/ssl.html#combined-key-and-certificate + if not self.args.tlsCertKey: + with open(self.args.tlsCert) as file: + data = file.read() + # To perform TLS server authentication (decrypt/session key ops, prove ownership) the server needs the corresponding private key. The cert alone cannot do that. + if "-BEGIN CERTIFICATE-" in data and not re.search(r"-BEGIN.*PRIVATE KEY-", data): + self.logger.error("Certificate with no private key found. Please specify the private key using --tls-cert-key") + exit(1) + else: + self.logger.info(f"Using TLS certificate private key '{self.args.tlsCertKey}' for HTTPS WSUS Server") + + try: + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.load_cert_chain(certfile=self.args.tlsCert, keyfile=self.args.tlsCertKey) + context.check_hostname = False + http_server.socket = context.wrap_socket(http_server.socket, server_side=True) + except ssl.SSLError as e: + self.logger.error(f"SSL Error: {e}") + self.logger.error("Make sure the TLS certificate is in PEM format. Exiting...") + exit(1) try: self.logger.info(f"Starting WSUS Server on {self.hostIp}:{self.wsusPort}...")