<s> from opencanary . modules import CanaryService <EOL> import twisted <EOL> from twisted . cred import portal , checkers , credentials , error <EOL> from twisted . conch import error , avatar , interfaces as conchinterfaces <EOL> from twisted . conch . checkers import SSHPublicKeyDatabase <EOL> from twisted . conch . ssh import factory , userauth , connection , keys , session , transport <EOL> from twisted . internet import reactor , protocol , defer <EOL> from twisted . application import internet <EOL> from zope . interface import implements <EOL> import sys , os , time <EOL> import base64 <EOL> SSH_PATH = "<STR_LIT>" <EOL> from twisted . conch . ssh . common import NS , getNS <EOL> class HoneyPotSSHUserAuthServer ( userauth . SSHUserAuthServer ) : <EOL> def serviceStarted ( self ) : <EOL> userauth . SSHUserAuthServer . serviceStarted ( self ) <EOL> us = self . transport . getHost ( ) <EOL> peer = self . transport . getPeer ( ) <EOL> logdata = { '<STR_LIT>' : self . transport . ourVersionString , '<STR_LIT>' : self . transport . otherVersionString } <EOL> logtype = self . transport . factory . canaryservice . logger . LOG_SSH_REMOTE_VERSION_SENT <EOL> log = self . transport . factory . canaryservice . log <EOL> log ( logdata , <EOL> logtype = logtype , <EOL> src_host = peer . address . host , <EOL> src_port = peer . address . port , <EOL> dst_host = us . address . host , <EOL> dst_port = us . address . port <EOL> ) <EOL> self . bannerSent = False <EOL> def sendBanner ( self ) : <EOL> if self . bannerSent : <EOL> return <EOL> data = '<STR_LIT>' <EOL> data = '<STR_LIT:\r\n>' . join ( data . splitlines ( ) + [ '<STR_LIT>' ] ) <EOL> self . transport . sendPacket ( <EOL> userauth . MSG_USERAUTH_BANNER , NS ( data ) + NS ( '<STR_LIT>' ) ) <EOL> self . bannerSent = True <EOL> def auth_password ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> password = getNS ( packet [ <NUM_LIT:1> : ] ) [ <NUM_LIT:0> ] <EOL> c = credentials . UsernamePassword ( self . user , password ) <EOL> us = self . transport . getHost ( ) <EOL> peer = self . transport . getPeer ( ) <EOL> logdata = { '<STR_LIT>' : self . user , '<STR_LIT>' : password , '<STR_LIT>' : self . transport . ourVersionString , '<STR_LIT>' : self . transport . otherVersionString } <EOL> logtype = self . transport . factory . canaryservice . logger . LOG_SSH_LOGIN_ATTEMPT <EOL> log = self . transport . factory . canaryservice . log <EOL> log ( logdata , <EOL> logtype = logtype , <EOL> src_host = peer . address . host , <EOL> src_port = peer . address . port , <EOL> dst_host = us . address . host , <EOL> dst_port = us . address . port ) <EOL> return self . portal . login ( c , None , conchinterfaces . IConchUser ) . addErrback ( <EOL> self . _ebPassword ) <EOL> def auth_publickey ( self , packet ) : <EOL> try : <EOL> key_blob = getNS ( getNS ( packet [ <NUM_LIT:1> : ] ) [ <NUM_LIT:1> ] ) [ <NUM_LIT:0> ] <EOL> except : <EOL> key_blob = "<STR_LIT>" <EOL> try : <EOL> key = keys . Key . fromString ( key_blob ) . toString ( '<STR_LIT>' ) <EOL> except : <EOL> key = "<STR_LIT>" . format ( key_blob = key_blob . encode ( '<STR_LIT>' ) ) <EOL> for keytype in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> if keytype in key_blob : <EOL> key = '<STR_LIT>' . format ( <EOL> keytype = keytype , <EOL> keydata = base64 . b64encode ( key_blob ) ) <EOL> print '<STR_LIT>' . format ( key = key ) <EOL> c = credentials . SSHPrivateKey ( None , None , None , None , None ) <EOL> return self . portal . login ( c , None , conchinterfaces . IConchUser ) . addErrback ( <EOL> self . _ebPassword ) <EOL> def ssh_USERAUTH_REQUEST ( self , packet ) : <EOL> self . sendBanner ( ) <EOL> return userauth . SSHUserAuthServer . ssh_USERAUTH_REQUEST ( self , packet ) <EOL> class HoneyPotSSHFactory ( factory . SSHFactory ) : <EOL> services = { <EOL> '<STR_LIT>' : HoneyPotSSHUserAuthServer , <EOL> '<STR_LIT>' : connection . SSHConnection , <EOL> } <EOL> def logDispatch ( self , sessionid , msg ) : <EOL> data = { } <EOL> data [ '<STR_LIT>' ] = msg <EOL> self . logger . log ( data ) <EOL> def __init__ ( self , logger = None , version = None ) : <EOL> self . sessions = { } <EOL> self . logger = logger <EOL> self . version = version <EOL> def buildProtocol ( self , addr ) : <EOL> t = HoneyPotTransport ( ) <EOL> if self . version : <EOL> t . ourVersionString = self . version <EOL> else : <EOL> t . ourVersionString = '<STR_LIT>' <EOL> t . supportedPublicKeys = self . privateKeys . keys ( ) <EOL> if not self . primes : <EOL> ske = t . supportedKeyExchanges [ : ] <EOL> ske . remove ( '<STR_LIT>' ) <EOL> t . supportedKeyExchanges = ske <EOL> t . factory = self <EOL> return t <EOL> class HoneyPotRealm : <EOL> implements ( portal . IRealm ) <EOL> def __init__ ( self ) : <EOL> pass <EOL> def requestAvatar ( self , avatarId , mind , * interfaces ) : <EOL> if conchinterfaces . IConchUser in interfaces : <EOL> return interfaces [ <NUM_LIT:0> ] , HoneyPotAvatar ( avatarId , self . env ) , lambda : None <EOL> else : <EOL> raise Exception , "<STR_LIT>" <EOL> class HoneyPotTransport ( transport . SSHServerTransport ) : <EOL> hadVersion = False <EOL> def connectionMade ( self ) : <EOL> logdata = { '<STR_LIT>' : str ( self . transport . sessionno ) } <EOL> logtype = self . factory . canaryservice . logger . LOG_SSH_NEW_CONNECTION <EOL> log = self . factory . canaryservice . log <EOL> log ( logdata , transport = self . transport , logtype = logtype ) <EOL> self . interactors = [ ] <EOL> self . logintime = time . time ( ) <EOL> self . ttylog_open = False <EOL> transport . SSHServerTransport . connectionMade ( self ) <EOL> def sendKexInit ( self ) : <EOL> if not self . gotVersion : <EOL> return <EOL> transport . SSHServerTransport . sendKexInit ( self ) <EOL> def dataReceived ( self , data ) : <EOL> transport . SSHServerTransport . dataReceived ( self , data ) <EOL> isLibssh = data . find ( '<STR_LIT>' , data . find ( '<STR_LIT>' ) ) != - <NUM_LIT:1> <EOL> if ( twisted . version . major < <NUM_LIT:11> or isLibssh ) and not self . hadVersion and self . gotVersion : <EOL> self . sendKexInit ( ) <EOL> self . hadVersion = True <EOL> def ssh_KEXINIT ( self , packet ) : <EOL> return transport . SSHServerTransport . ssh_KEXINIT ( self , packet ) <EOL> def lastlogExit ( self ) : <EOL> starttime = time . strftime ( '<STR_LIT>' , <EOL> time . localtime ( self . logintime ) ) <EOL> endtime = time . strftime ( '<STR_LIT>' , <EOL> time . localtime ( time . time ( ) ) ) <EOL> duration = str ( ( time . time ( ) - self . logintime ) ) <EOL> clientIP = self . transport . getPeer ( ) . host <EOL> def connectionLost ( self , reason ) : <EOL> for i in self . interactors : <EOL> i . sessionClosed ( ) <EOL> if self . transport . sessionno in self . factory . sessions : <EOL> del self . factory . sessions [ self . transport . sessionno ] <EOL> if self . ttylog_open : <EOL> ttylog . ttylog_close ( self . ttylog_file , time . time ( ) ) <EOL> self . ttylog_open = False <EOL> transport . SSHServerTransport . connectionLost ( self , reason ) <EOL> def sendDisconnect ( self , reason , desc ) : <EOL> """<STR_LIT>""" <EOL> if not '<STR_LIT>' in desc : <EOL> transport . SSHServerTransport . sendDisconnect ( self , reason , desc ) <EOL> else : <EOL> self . transport . write ( '<STR_LIT>' ) <EOL> log . msg ( '<STR_LIT>' % ( reason , desc ) ) <EOL> self . transport . loseConnection ( ) <EOL> class HoneyPotSSHSession ( session . SSHSession ) : <EOL> def request_env ( self , data ) : <EOL> pass <EOL> class HoneyPotAvatar ( avatar . ConchUser ) : <EOL> implements ( conchinterfaces . ISession ) <EOL> def __init__ ( self , username , env ) : <EOL> avatar . ConchUser . __init__ ( self ) <EOL> self . username = username <EOL> self . env = env <EOL> self . channelLookup . update ( { '<STR_LIT>' : HoneyPotSSHSession } ) <EOL> def openShell ( self , protocol ) : <EOL> return <EOL> def getPty ( self , terminal , windowSize , attrs ) : <EOL> return None <EOL> def execCommand ( self , protocol , cmd ) : <EOL> return <EOL> def closed ( self ) : <EOL> pass <EOL> def eofReceived ( self ) : <EOL> pass <EOL> def windowChanged ( self , windowSize ) : <EOL> self . windowSize = windowSize <EOL> def getRSAKeys ( ) : <EOL> public_key = os . path . join ( SSH_PATH , '<STR_LIT>' ) <EOL> private_key = os . path . join ( SSH_PATH , '<STR_LIT>' ) <EOL> if not ( os . path . exists ( public_key ) and os . path . exists ( private_key ) ) : <EOL> from Crypto . PublicKey import RSA <EOL> from twisted . python import randbytes <EOL> KEY_LENGTH = <NUM_LIT> <EOL> rsaKey = RSA . generate ( KEY_LENGTH , randbytes . secureRandom ) <EOL> publicKeyString = keys . Key ( rsaKey ) . public ( ) . toString ( '<STR_LIT>' ) <EOL> privateKeyString = keys . Key ( rsaKey ) . toString ( '<STR_LIT>' ) <EOL> with file ( public_key , '<STR_LIT>' ) as f : <EOL> f . write ( publicKeyString ) <EOL> with file ( private_key , '<STR_LIT>' ) as f : <EOL> f . write ( privateKeyString ) <EOL> else : <EOL> with file ( public_key ) as f : <EOL> publicKeyString = f . read ( ) <EOL> with file ( private_key ) as f : <EOL> privateKeyString = f . read ( ) <EOL> return publicKeyString , privateKeyString <EOL> def getDSAKeys ( ) : <EOL> public_key = os . path . join ( SSH_PATH , '<STR_LIT>' ) <EOL> private_key = os . path . join ( SSH_PATH , '<STR_LIT>' ) <EOL> if not ( os . path . exists ( public_key ) and os . path . exists ( private_key ) ) : <EOL> from Crypto . PublicKey import DSA <EOL> from twisted . python import randbytes <EOL> KEY_LENGTH = <NUM_LIT> <EOL> dsaKey = DSA . generate ( KEY_LENGTH , randbytes . secureRandom ) <EOL> publicKeyString = keys . Key ( dsaKey ) . public ( ) . toString ( '<STR_LIT>' ) <EOL> privateKeyString = keys . Key ( dsaKey ) . toString ( '<STR_LIT>' ) <EOL> with file ( public_key , '<STR_LIT>' ) as f : <EOL> f . write ( publicKeyString ) <EOL> with file ( private_key , '<STR_LIT>' ) as f : <EOL> f . write ( privateKeyString ) <EOL> else : <EOL> with file ( public_key ) as f : <EOL> publicKeyString = f . read ( ) <EOL> with file ( private_key ) as f : <EOL> privateKeyString = f . read ( ) <EOL> return publicKeyString , privateKeyString <EOL> class HoneypotPasswordChecker : <EOL> implements ( checkers . ICredentialsChecker ) <EOL> credentialInterfaces = ( credentials . IUsernamePassword , ) <EOL> def __init__ ( self , logger = None ) : <EOL> self . logger = logger <EOL> self . auth_attempt = <NUM_LIT:0> <EOL> def requestAvatarId ( self , credentials ) : <EOL> return defer . fail ( error . UnauthorizedLogin ( ) ) <EOL> class CanaryPublicKeyChecker : <EOL> implements ( checkers . ICredentialsChecker ) <EOL> credentialInterfaces = ( credentials . ISSHPrivateKey , ) <EOL> def __init__ ( self , logger = None ) : <EOL> self . logger = logger <EOL> self . auth_attempt = <NUM_LIT:0> <EOL> def requestAvatarId ( self , credentials ) : <EOL> return defer . fail ( error . UnauthorizedLogin ( ) ) <EOL> class CanarySSH ( CanaryService ) : <EOL> NAME = '<STR_LIT>' <EOL> def __init__ ( self , config = None , logger = None ) : <EOL> CanaryService . __init__ ( self , config = config , logger = logger ) <EOL> self . port = int ( config . getVal ( "<STR_LIT>" , default = <NUM_LIT> ) ) <EOL> self . version = config . getVal ( "<STR_LIT>" , default = "<STR_LIT>" ) . encode ( '<STR_LIT:utf8>' ) <EOL> self . listen_addr = config . getVal ( '<STR_LIT>' , default = '<STR_LIT>' ) <EOL> def getService ( self ) : <EOL> factory = HoneyPotSSHFactory ( version = self . version , logger = self . logger ) <EOL> factory . canaryservice = self <EOL> factory . portal = portal . Portal ( HoneyPotRealm ( ) ) <EOL> rsa_pubKeyString , rsa_privKeyString = getRSAKeys ( ) <EOL> dsa_pubKeyString , dsa_privKeyString = getDSAKeys ( ) <EOL> factory . portal . registerChecker ( HoneypotPasswordChecker ( logger = factory . logger ) ) <EOL> factory . portal . registerChecker ( CanaryPublicKeyChecker ( logger = factory . logger ) ) <EOL> factory . publicKeys = { '<STR_LIT>' : keys . Key . fromString ( data = rsa_pubKeyString ) , <EOL> '<STR_LIT>' : keys . Key . fromString ( data = dsa_pubKeyString ) } <EOL> factory . privateKeys = { '<STR_LIT>' : keys . Key . fromString ( data = rsa_privKeyString ) , <EOL> '<STR_LIT>' : keys . Key . fromString ( data = dsa_privKeyString ) } <EOL> return internet . TCPServer ( self . port , factory , interface = self . listen_addr ) </s>
