diff --git a/cowrie.cfg.dist b/cowrie.cfg.dist index c38c053..7291389 100644 --- a/cowrie.cfg.dist +++ b/cowrie.cfg.dist @@ -90,6 +90,14 @@ auth_class = UserDB #auth_class = AuthRandom #auth_class_parameters = 2, 5, 10 +# No authentication checking at all +# enabling 'auth_none' will enable the ssh2 'auth_none' authentication method +# this allows the requested user in without any verification at all +# +# (default: false) + +auth_none_enabled = false + # Directory for creating simple commands that only output text. # # The command must be placed under this directory with the proper path, such diff --git a/cowrie/core/auth.py b/cowrie/core/auth.py index 1fa963c..71ae120 100644 --- a/cowrie/core/auth.py +++ b/cowrie/core/auth.py @@ -11,7 +11,7 @@ from zope.interface import implementer from twisted.cred.checkers import ICredentialsChecker from twisted.cred.credentials import IUsernamePassword, ISSHPrivateKey, \ - IPluggableAuthenticationModules + IPluggableAuthenticationModules, ICredentials from twisted.cred.error import UnauthorizedLogin, UnhandledCredentials from twisted.internet import defer @@ -253,6 +253,22 @@ class HoneypotPublicKeyChecker: fingerprint=_pubKey.fingerprint()) return failure.Failure(error.ConchError('Incorrect signature')) +class IUsername(ICredentials): + """ + Encapsulate username only + + @type username: C{str} + @ivar username: The username associated with these credentials. + """ + + +@implementer(IUsername) +class Username: + + def __init__(self, username): + self.username = username + + # This credential interface also provides an IP address @implementer(IUsernamePassword) class UsernamePasswordIP: @@ -262,6 +278,21 @@ class UsernamePasswordIP: self.password = password self.ip = ip +@implementer(ICredentialsChecker) +class HoneypotNoneChecker: + """ + Checker that does no authentication check + """ + + credentialInterfaces = (IUsername,) + + def __init__(self): + pass + + def requestAvatarId(self, credentials): + return defer.succeed(credentials.username) + + # This credential interface also provides an IP address @implementer(IPluggableAuthenticationModules) class PluggableAuthenticationModulesIP: diff --git a/cowrie/core/ssh.py b/cowrie/core/ssh.py index be76a41..da2f785 100644 --- a/cowrie/core/ssh.py +++ b/cowrie/core/ssh.py @@ -17,6 +17,7 @@ import twisted.conch.ls from twisted.python import log, components from twisted.conch.openssh_compat import primes from twisted.conch.ssh.common import NS, getNS +from twisted.internet import defer import ConfigParser @@ -25,10 +26,11 @@ import auth import connection import honeypot import protocol -import exceptions class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer): + def serviceStarted(self): + self.interfaceToMethod[auth.IUsername] = 'none' userauth.SSHUserAuthServer.serviceStarted(self) self.bannerSent = False @@ -52,13 +54,17 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer): self.sendBanner() return userauth.SSHUserAuthServer.ssh_USERAUTH_REQUEST(self, packet) + def auth_none(self, packet): + c = auth.Username(self.user) + return self.portal.login(c, None, conchinterfaces.IConchUser) + # Overridden to pass src_ip to auth.UsernamePasswordIP def auth_password(self, packet): password = getNS(packet[1:])[0] src_ip = self.transport.transport.getPeer().host c = auth.UsernamePasswordIP(self.user, password, src_ip) - return self.portal.login(c, None, conchinterfaces.IConchUser).addErrback( - self._ebPassword) + return self.portal.login(c, None, + conchinterfaces.IConchUser).addErrback(self._ebPassword) # Overridden to pass src_ip to auth.PluggableAuthenticationModulesIP def auth_keyboard_interactive(self, packet): @@ -69,7 +75,8 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer): return defer.fail(error.IgnoreAuthentication()) src_ip = self.transport.transport.getPeer().host c = auth.PluggableAuthenticationModulesIP(self.user, self._pamConv, src_ip) - return self.portal.login(c, None, conchinterfaces.IConchUser) + return self.portal.login(c, None, + conchinterfaces.IConchUser).addErrback(self._ebPassword) # As implemented by Kojoney class HoneyPotSSHFactory(factory.SSHFactory): @@ -126,7 +133,7 @@ class HoneyPotSSHFactory(factory.SSHFactory): self.dbloggers.append(dblogger) # load output modules - self.output_plugins = []; + self.output_plugins = [] for x in self.cfg.sections(): if not x.startswith('output_'): continue diff --git a/twisted/plugins/cowrie_plugin.py b/twisted/plugins/cowrie_plugin.py index 9611c17..398ed31 100644 --- a/twisted/plugins/cowrie_plugin.py +++ b/twisted/plugins/cowrie_plugin.py @@ -54,6 +54,11 @@ class CowrieServiceMaker(object): factory.portal.registerChecker(core.auth.HoneypotPublicKeyChecker(cfg)) factory.portal.registerChecker(core.auth.HoneypotPasswordChecker(cfg)) + if cfg.has_option('honeypot', 'auth_none_enabled') and \ + cfg.get('honeypot', 'auth_none_enabled').lower() in \ + ('yes', 'true', 'on'): + factory.portal.registerChecker(core.auth.HoneypotNoneChecker()) + top_service = top_service = service.MultiService() for i in listen_addr.split():