From 3dcf65828dd900d84725ee815226eb6fb87cb61c Mon Sep 17 00:00:00 2001 From: Evgeniia Date: Wed, 10 Jun 2020 21:48:55 +0200 Subject: [PATCH 1/5] Update Dockerfile --- docker/tanner/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/tanner/Dockerfile b/docker/tanner/Dockerfile index 7d33af2d..d2fdba42 100644 --- a/docker/tanner/Dockerfile +++ b/docker/tanner/Dockerfile @@ -19,7 +19,7 @@ RUN sed -i 's/dl-cdn/dl-2/g' /etc/apk/repositories && \ musl-dev \ python3-dev && \ # Setup Tanner - git clone --depth=1 https://github.com/mushorg/tanner -b develop /opt/tanner && \ + git clone --depth=1 https://github.com/mushorg/tanner /opt/tanner && \ cp /root/dist/config.yaml /opt/tanner/tanner/data/ && \ cd /opt/tanner/ && \ pip3 install --no-cache-dir setuptools && \ From 3fe44eba40fcb7fea1d170bfff52a4ee422e54a4 Mon Sep 17 00:00:00 2001 From: mzfr Date: Sat, 22 Aug 2020 11:36:32 +0530 Subject: [PATCH 2/5] add support for twig injection template --- tanner/data/config.yaml | 4 ++ tanner/emulators/twig_template_injection.py | 77 +++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tanner/emulators/twig_template_injection.py diff --git a/tanner/data/config.yaml b/tanner/data/config.yaml index c34e2b8e..221833b5 100644 --- a/tanner/data/config.yaml +++ b/tanner/data/config.yaml @@ -100,3 +100,7 @@ REMOTE_DOCKERFILE: SESSIONS: delete_timeout: 300 analyze_timeout: 300 + +TWIG_PATH: + autoloader: "path/of/Autoloader.php" + stringloader: "path/of/StringLoader.php" diff --git a/tanner/emulators/twig_template_injection.py b/tanner/emulators/twig_template_injection.py new file mode 100644 index 00000000..74b4e26b --- /dev/null +++ b/tanner/emulators/twig_template_injection.py @@ -0,0 +1,77 @@ +import asyncio +import logging + +from tanner.config import TannerConfig +from tanner.utils.php_sandbox_helper import PHPSandboxHelper +from tanner.utils import patterns + + +class PHPObjectInjection: + def __init__(self, loop=None): + self._loop = loop if loop is not None else asyncio.get_event_loop() + self.logger = logging.getLogger("tanner.twig_template_injection") + self.helper = PHPSandboxHelper(self._loop) + self.autoloader = TannerConfig.get("TWIG_PATH", "autoloader") + self.stringloader = TannerConfig.get("TWIG_PATH", "stringloader") + + async def get_injection_result(self, code): + """ + Injects the code from attacker to vulnerable code and get emulation results from php sandbox. + :param code (str): Input payload from attacker + :return: twig_injection_result (dict): file_md5 (md5 hash), stdout (injection result) as keys. + """ + + vul_code = """ + addExtension(new \\Twig\\Extension\\StringLoaderExtension()); + $payload = "%s"; + $result = $twig->render($payload); + echo $result; + ?> + """ % ( + self.autoloader, + self.stringloader, + code, + ) + + self.logger.debug( + "Getting the twig injection results of %s from php sandbox", code + ) + twig_injection_result = await self.helper.get_result(vul_code) + + return twig_injection_result + + def scan(self, value): + """ + Scans the input payload to detect attack using regex + :param value (str): code from attacker + :return: detection (dict): name (attack name), order (attack order) as keys + """ + + detection = None + if patterns.TEMPLATE_INJECTION_TORNADO.match(value): + detection = dict(name="twig_template_injection", order=3) + return detection + + async def handle(self, attack_params): + """ + Handler of emulator + :param attack_params (list): contains dicts as elements with id and value (payload from attacker) as keys + :return: (dict): value (result of emulator), page (if set to true the payload will be injected to index.html + itself) as keys. + """ + + result = await self.get_injection_result(attack_params[0]["value"]) + if not result or "stdout" not in result: + self.logger.exception( + "Error while getting the injection results from php sandbox.." + ) + return dict(status_code=504) + return dict(value=result["stdout"], page=False) From f01c7f539a715c25e4c60d7b33f7be683c25426d Mon Sep 17 00:00:00 2001 From: mzfr Date: Sat, 22 Aug 2020 12:50:02 +0530 Subject: [PATCH 3/5] update the config template and add the emulator option to base --- tanner/data/config.yaml | 3 ++- tanner/emulators/base.py | 9 ++++++--- tanner/emulators/twig_template_injection.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tanner/data/config.yaml b/tanner/data/config.yaml index 221833b5..fecaf4ac 100644 --- a/tanner/data/config.yaml +++ b/tanner/data/config.yaml @@ -40,7 +40,8 @@ EMULATOR_ENABLED: lfi: True xss: True cmd_exec: True - php_code_injection: True + php_code_injection: True + twig_template_injection: True php_object_injection: True crlf: True xxe_injection: True diff --git a/tanner/emulators/base.py b/tanner/emulators/base.py index 09741b66..e0f37494 100644 --- a/tanner/emulators/base.py +++ b/tanner/emulators/base.py @@ -6,7 +6,7 @@ from tanner import __version__ as tanner_version from tanner.config import TannerConfig from tanner.emulators import lfi, rfi, sqli, xss, cmd_exec, php_code_injection, php_object_injection, crlf, \ - xxe_injection, template_injection # noqa + xxe_injection, template_injection, twig_template_injection # noqa from tanner.utils import patterns @@ -22,7 +22,8 @@ def __init__(self, base_dir, db_name, loop=None): 'php_object_injection': TannerConfig.get('EMULATOR_ENABLED', 'php_object_injection'), 'crlf': TannerConfig.get('EMULATOR_ENABLED', 'crlf'), 'xxe_injection': TannerConfig.get('EMULATOR_ENABLED', 'xxe_injection'), - 'template_injection': TannerConfig.get('EMULATOR_ENABLED', 'template_injection') + 'template_injection': TannerConfig.get('EMULATOR_ENABLED', 'template_injection'), + 'twig_template_injection': TannerConfig.get('EMULATOR_ENABLED', 'twig_template_injection') } self.emulators = { @@ -39,7 +40,9 @@ def __init__(self, base_dir, db_name, loop=None): 'crlf': crlf.CRLFEmulator() if self.emulator_enabled['crlf'] else None, 'xxe_injection': xxe_injection.XXEInjection(loop) if self.emulator_enabled['xxe_injection'] else None, 'template_injection': template_injection.TemplateInjection(loop) if - self.emulator_enabled['template_injection'] else None + self.emulator_enabled['template_injection'] else None, + 'twig_template_injection': twig_template_injection.TwigTemplateInjection(loop) if + self.emulator_enabled['twig_template_injection'] else None } self.get_emulators = ['sqli', 'rfi', 'lfi', 'xss', 'php_code_injection', 'php_object_injection', diff --git a/tanner/emulators/twig_template_injection.py b/tanner/emulators/twig_template_injection.py index 74b4e26b..e210d106 100644 --- a/tanner/emulators/twig_template_injection.py +++ b/tanner/emulators/twig_template_injection.py @@ -6,7 +6,7 @@ from tanner.utils import patterns -class PHPObjectInjection: +class TwigTemplateInjection: def __init__(self, loop=None): self._loop = loop if loop is not None else asyncio.get_event_loop() self.logger = logging.getLogger("tanner.twig_template_injection") From 70bcff2e5037ce9b625f21e49f07f5275b4a2d96 Mon Sep 17 00:00:00 2001 From: mzfr Date: Mon, 24 Aug 2020 11:21:01 +0530 Subject: [PATCH 4/5] Add emulator in GET and POST --- tanner/emulators/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tanner/emulators/base.py b/tanner/emulators/base.py index e0f37494..1b3e9448 100644 --- a/tanner/emulators/base.py +++ b/tanner/emulators/base.py @@ -46,9 +46,9 @@ def __init__(self, base_dir, db_name, loop=None): } self.get_emulators = ['sqli', 'rfi', 'lfi', 'xss', 'php_code_injection', 'php_object_injection', - 'cmd_exec', 'crlf', 'xxe_injection', 'template_injection'] + 'cmd_exec', 'crlf', 'xxe_injection', 'template_injection', 'twig_template_injection'] self.post_emulators = ['sqli', 'rfi', 'lfi', 'xss', 'php_code_injection', 'php_object_injection', - 'cmd_exec', 'crlf', 'xxe_injection', 'template_injection'] + 'cmd_exec', 'crlf', 'xxe_injection', 'template_injection', 'twig_template_injection'] self.cookie_emulators = ['sqli', 'php_object_injection'] def extract_get_data(self, path): From 1bafbf6d7cd27a477f7a25a69d4be7025e384ed8 Mon Sep 17 00:00:00 2001 From: mzfr Date: Fri, 4 Sep 2020 15:37:55 +0530 Subject: [PATCH 5/5] handle twig injection the same way it has been handled for tornado injection --- tanner/emulators/twig_template_injection.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tanner/emulators/twig_template_injection.py b/tanner/emulators/twig_template_injection.py index e210d106..87dd3553 100644 --- a/tanner/emulators/twig_template_injection.py +++ b/tanner/emulators/twig_template_injection.py @@ -60,18 +60,7 @@ def scan(self, value): detection = dict(name="twig_template_injection", order=3) return detection - async def handle(self, attack_params): - """ - Handler of emulator - :param attack_params (list): contains dicts as elements with id and value (payload from attacker) as keys - :return: (dict): value (result of emulator), page (if set to true the payload will be injected to index.html - itself) as keys. - """ - - result = await self.get_injection_result(attack_params[0]["value"]) - if not result or "stdout" not in result: - self.logger.exception( - "Error while getting the injection results from php sandbox.." - ) - return dict(status_code=504) - return dict(value=result["stdout"], page=False) + async def handle(self, attack_params, session=None): + attack_params[0]['value'] = unquote(attack_params[0]['value']) + result = await self.get_injection_result(attack_params[0]['value']) + return result