make telnet optional, small prompt fixes

This commit is contained in:
Michel Oosterhof
2016-08-22 15:56:19 +04:00
parent 31bdc68b0d
commit 1602fa735a
4 changed files with 61 additions and 43 deletions

View File

@@ -248,22 +248,26 @@ forward_redirect_587 = 127.0.0.1:12525
# ============================================================================ # ============================================================================
# Telnet Specific Options # Telnet Specific Options
# ============================================================================ # ============================================================================
[telnet]
# Enable Telnet support, disabled by default
enabled = false
# IP addresses to listen for incoming Telnet connections. # IP addresses to listen for incoming Telnet connections.
# #
# (default: 0.0.0.0) = any IPv4 address # (default: 0.0.0.0) = any IPv4 address
#listen_telnet_addr = 0.0.0.0 #listen_addr = 0.0.0.0
# (use :: for listen to all IPv6 and IPv4 addresses) # (use :: for listen to all IPv6 and IPv4 addresses)
#listen_telnet_addr = :: #listen_addr = ::
# Port to listen for incoming Telnet connections. # Port to listen for incoming Telnet connections.
# #
# (default: 2223) # (default: 2223)
#listen_telnet_port = 2223 #listen_port = 2223
# Source Port to report in logs (useful if you use iptables to forward ports to Cowrie) # Source Port to report in logs (useful if you use iptables to forward ports to Cowrie)
#reported_telnet_port = 23 #reported_port = 23
# ============================================================================ # ============================================================================

View File

@@ -81,9 +81,9 @@ class HoneyPotRealm(object):
user = avatar.CowrieUser(avatarId, serv) user = avatar.CowrieUser(avatarId, serv)
return interfaces[0], user, user.logout return interfaces[0], user, user.logout
elif ITelnetProtocol in interfaces: elif ITelnetProtocol in interfaces:
cs = server.CowrieServer(self) serv = server.CowrieServer(self)
av = session.HoneyPotTelnetSession(avatarId, cs) user = session.HoneyPotTelnetSession(avatarId, serv)
return interfaces[0], av, lambda:None return interfaces[0], user, user.logout
log.msg('No supported interfaces found.') log.msg('No supported interfaces found.')
# TODO: this exception doesn't raise for a reason I don't understand # TODO: this exception doesn't raise for a reason I don't understand

View File

@@ -101,15 +101,20 @@ class HoneyPotTelnetFactory(protocol.ServerFactory):
class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin): class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin):
""" """
Telnet Transport that takes care of Authentication. Once authenticated this TelnetAuthProtocol that takes care of Authentication. Once authenticated this
transport is replaced with HoneyPotTelnetSession. protocol is replaced with HoneyPotTelnetSession.
""" """
def connectionMade(self): loginPrompt = 'login: '
passwordPrompt = 'Password: '
def connectionMade(self):
"""
"""
self.transportId = uuid.uuid4().hex[:8] self.transportId = uuid.uuid4().hex[:8]
sessionno = self.transport.transport.sessionno sessionno = self.transport.transport.sessionno
self.factory.sessions[sessionno] = self.transportId self.factory.sessions[sessionno] = self.transportId
self.setTimeout(120)
log.msg(eventid='cowrie.session.connect', log.msg(eventid='cowrie.session.connect',
format='New connection: %(src_ip)s:%(src_port)s (%(dst_ip)s:%(dst_port)s) [session: %(sessionno)s]', format='New connection: %(src_ip)s:%(src_port)s (%(dst_ip)s:%(dst_port)s) [session: %(sessionno)s]',
@@ -120,10 +125,7 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin):
# I need to doubly escape here since my underlying # I need to doubly escape here since my underlying
# StripCrTelnetTransport hack would remove it and leave just \n # StripCrTelnetTransport hack would remove it and leave just \n
self.transport.write(self.factory.banner.replace('\n', '\r\r\n')) self.transport.write(self.factory.banner.replace('\n', '\r\r\n'))
# FIXME: this should be configurable or provided via filesystem self.transport.write(self.loginPrompt)
self.transport.write("User Access Verification\n\nUsername: ".replace('\n', '\r\r\n'))
self.setTimeout(120)
def connectionLost(self, reason): def connectionLost(self, reason):
@@ -145,10 +147,10 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin):
""" """
self.username = line self.username = line
# only send ECHO option if we are chatting with a real Telnet client # only send ECHO option if we are chatting with a real Telnet client
if self.transport.options: #if self.transport.options: <-- doesn't work
self.transport.will(ECHO) self.transport.will(ECHO)
# FIXME: this should be configurable or provided via filesystem # FIXME: this should be configurable or provided via filesystem
self.transport.write("Password: ") self.transport.write(self.passwordPrompt)
return 'Password' return 'Password'
@@ -195,7 +197,12 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin):
protocol.makeConnection(self.transport) protocol.makeConnection(self.transport)
self.transport.protocol = protocol self.transport.protocol = protocol
def _ebLogin(self, failure):
# TODO: provide a way to have user configurable strings for wrong password # TODO: provide a way to have user configurable strings for wrong password
self.transport.write("\nLogin incorrect\n")
self.transport.write(self.loginPrompt)
self.state = "User"
class StripCrTelnetTransport(TelnetTransport): class StripCrTelnetTransport(TelnetTransport):

View File

@@ -100,16 +100,20 @@ class CowrieServiceMaker(object):
factory.portal.registerChecker( factory.portal.registerChecker(
core.checkers.HoneypotNoneChecker()) core.checkers.HoneypotNoneChecker())
if cfg.has_option('honeypot', 'listen_ssh_addr'): if cfg.has_option('ssh', 'listen_addr'):
listen_ssh_addr = cfg.get('honeypot', 'listen_ssh_addr') listen_ssh_addr = cfg.get('ssh', 'listen_addr')
elif cfg.has_option('honeypot', 'listen_addr'):
listen_ssh_addr = cfg.get('honeypot', 'listen_addr')
else: else:
listen_ssh_addr = '0.0.0.0' listen_ssh_addr = '0.0.0.0'
# Preference: 1, option, 2, config, 3, default of 2222 # Preference: 1, option, 2, config, 3, default of 2222
if options['port'] != 0: if options['port'] != 0:
listen_ssh_port = int(options["port"]) listen_ssh_port = int(options["port"])
elif cfg.has_option('honeypot', 'listen_ssh_port'): elif cfg.has_option('ssh', 'listen_port'):
listen_ssh_port = int(cfg.get('honeypot', 'listen_ssh_port')) listen_ssh_port = int(cfg.get('ssh', 'listen_port'))
elif cfg.has_option('honeypot', 'listen_port'):
listen_ssh_port = int(cfg.get('honeypot', 'listen_port'))
else: else:
listen_ssh_port = 2222 listen_ssh_port = 2222
@@ -118,15 +122,18 @@ class CowrieServiceMaker(object):
# FIXME: Use addService on topService ? # FIXME: Use addService on topService ?
svc.setServiceParent(topService) svc.setServiceParent(topService)
# TODO deduplicate telnet and ssh into a generic loop for each service if cfg.has_option('telnet', 'enabled') and \
if cfg.has_option('honeypot', 'listen_telnet_addr'): cfg.get('telnet', 'enabled').lower() in \
listen_telnet_addr = cfg.get('honeypot', 'listen_telnet_addr') ('yes', 'true', 'on'):
if cfg.has_option('telnet', 'listen_addr'):
listen_telnet_addr = cfg.get('telnet', 'listen_addr')
else: else:
listen_telnet_addr = '0.0.0.0' listen_telnet_addr = '0.0.0.0'
# Preference: 1, config, 2, default of 2223 # Preference: 1, config, 2, default of 2223
if cfg.has_option('honeypot', 'listen_telnet_port'): if cfg.has_option('telnet', 'listen_port'):
listen_telnet_port = int(cfg.get('honeypot', 'listen_telnet_port')) listen_telnet_port = int(cfg.get('telnet', 'listen_port'))
else: else:
listen_telnet_port = 2223 listen_telnet_port = 2223