def attempt_success(src, user, time): # send mail formatted_time = strftime("%a, %d %b %Y %H:%M:%S", localtime()) body = "Successful attempt from %s on %s (user %s)" % (src, formatted_time, user) msg = MIMEText(body) msg['From'] = "%s <%s>" % (config().get('mailer', 'from'), config().get('mailer', 'envelope_from')) msg['Subject'] = "[Kippo] Successful login attempt by %s" % (src) smtp = smtplib.SMTP(config().get('mailer', 'smtp_server')) smtp.sendmail(config().get('mailer', 'envelope_from'), config().get('mailer', 'envelope_to'), msg.as_string())
def __init__(self): cfg = config() # protocol^Wwhatever instances are kept here for the interact feature self.sessions = {} # for use by the uptime command self.starttime = time.time() # load db loggers self.dbloggers = [] for x in cfg.sections(): if not x.startswith('database_'): continue engine = x.split('_')[1] dbengine = 'database_' + engine lcfg = ConfigParser.ConfigParser() lcfg.add_section(dbengine) for i in cfg.options(x): lcfg.set(dbengine, i, cfg.get(x, i)) lcfg.add_section('honeypot') for i in cfg.options('honeypot'): lcfg.set('honeypot', i, cfg.get('honeypot', i)) print 'Loading dblog engine: %s' % (engine, ) dblogger = __import__('kippo.dblog.%s' % (engine, ), globals(), locals(), ['dblog']).DBLogger(lcfg) log.startLoggingWithObserver(dblogger.emit, setStdout=False) self.dbloggers.append(dblogger)
def load(self): '''load the user db''' userdb_file = '%s/userdb.txt' % \ (config().get('honeypot', 'data_path'),) f = open(userdb_file, 'r') while True: line = f.readline() if not line: break line = string.strip(line) if not line: continue (login, uid_str, passwd) = line.split(':', 2) uid = 0 try: uid = int(uid_str) except ValueError: uid = 1001 self.userdb.append((login, uid, passwd)) f.close()
def connectionMade(self): transport = self.transport.session.conn.transport transport.ttylog_file = '%s/tty/%s-%s.log' % \ (config().get('honeypot', 'log_path'), time.strftime('%Y%m%d-%H%M%S'), transport.transportId ) log.msg('Opening TTY log: %s' % transport.ttylog_file) ttylog.ttylog_open(transport.ttylog_file, time.time()) transport.ttylog_open = True transport.stdinlog_file = '%s/%s-%s-stdin.log' % \ (config().get('honeypot', 'download_path'), time.strftime('%Y%m%d-%H%M%S'), transport.transportId ) transport.stdinlog_open = False insults.ServerProtocol.connectionMade(self)
def connectionMade(self): self.displayMOTD() transport = self.terminal.transport.session.conn.transport self.realClientIP = transport.transport.getPeer().host self.realClientPort = transport.transport.getPeer().port self.clientVersion = transport.otherVersionString self.logintime = transport.logintime self.ttylog_file = transport.ttylog_file # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP if cfg.has_option('honeypot', 'internet_facing_ip'): self.kippoIP = cfg.get('honeypot', 'internet_facing_ip') else: # Hack to get ip s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) self.kippoIP = s.getsockname()[0] s.close()
def connectionMade(self): self.displayMOTD() transport = self.terminal.transport.session.conn.transport self.realClientIP = transport.transport.getPeer().host self.realClientPort = transport.transport.getPeer().port self.clientVersion = transport.otherVersionString self.logintime = transport.logintime self.ttylog_file = transport.ttylog_file # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP if cfg.has_option('honeypot', 'internet_facing_ip'): self.kippoIP = cfg.get('honeypot', 'internet_facing_ip') else: # Hack to get ip s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8",80)) self.kippoIP = s.getsockname()[0] s.close()
def sendEmail(subject, message): cfg = config() msg = MIMEText(message) msg['Subject'] = subject toEmail = cfg.get('smtp', 'email_to') msg['To'] = toEmail fromEmail = cfg.get('smtp', 'email_from') msg['From'] = fromEmail smtpHost = cfg.get('smtp', 'smtp_host') smtpPort = cfg.get('smtp', 'smtp_port') smtpUsername = cfg.get('smtp', 'smtp_username') smtpPassword = cfg.get('smtp', 'smtp_Password') smtpEnc = cfg.get('smtp', 'smtp_enc') s = smtplib.SMTP(smtpHost, smtpPort) if smtpEnc == 'ssl': s = smtplib.SMTP_SSL(smtpHost, smtpPort) elif smtpEnc == 'tls': s.starttls() s.login(smtpUsername, smtpPassword) s.sendmail(fromEmail, [toEmail], msg.as_string()) s.quit()
def load(self): '''load the user db''' userdb_file = '%s/userdb.txt' % \ (config().get('honeypot', 'data_path'),) f = open(userdb_file, 'r') while True: line = f.readline() if not line: break line = string.strip(line) if not line: continue if line.startswith('#'): continue (login, uid_str, passwd) = line.split(':', 2) uid = 0 try: uid = int(uid_str) except ValueError: uid = 1001 self.userdb.append((login, uid, passwd)) f.close()
def __init__(self): cfg = config() # protocol^Wwhatever instances are kept here for the interact feature self.sessions = {} # for use by the uptime command self.starttime = time.time() # load db loggers self.dbloggers = [] for x in cfg.sections(): if not x.startswith('database_'): continue engine = x.split('_')[1] dbengine = 'database_' + engine lcfg = ConfigParser.ConfigParser() lcfg.add_section(dbengine) for i in cfg.options(x): lcfg.set(dbengine, i, cfg.get(x, i)) lcfg.add_section('honeypot') for i in cfg.options('honeypot'): lcfg.set('honeypot', i, cfg.get('honeypot', i)) print 'Loading dblog engine: %s' % (engine,) dblogger = __import__( 'kippo.dblog.%s' % (engine,), globals(), locals(), ['dblog']).DBLogger(lcfg) log.startLoggingWithObserver(dblogger.emit, setStdout=False) self.dbloggers.append(dblogger)
def connectionMade(self): recvline.HistoricRecvLine.connectionMade(self) self.displayMOTD() self.cmdstack = [HoneyPotShell(self)] transport = self.terminal.transport.session.conn.transport transport.factory.sessions[transport.transport.sessionno] = self self.realClientIP = transport.transport.getPeer().host self.clientVersion = transport.otherVersionString self.logintime = transport.logintime self.ttylog_file = transport.ttylog_file # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP self.keyHandlers.update({ '\x04': self.handle_CTRL_D, '\x15': self.handle_CTRL_U, '\x03': self.handle_CTRL_C, '\x09': self.handle_TAB, }) if cfg.has_section('mailer'): mailer.attempt_success(self.realClientIP, self.user.username, self.logintime)
def connectionMade(self): recvline.HistoricRecvLine.connectionMade(self) self.displayMOTD() self.cmdstack = [HoneyPotShell(self)] transport = self.terminal.transport.session.conn.transport # You are in a maze of twisty little passages, all alike p = transport.transport.getPeer() # real source IP of client self.realClientIP = p.host self.clientVersion = transport.otherVersionString # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP self.logintime = time.time() self.keyHandlers.update({ '\x04': self.handle_CTRL_D, '\x15': self.handle_CTRL_U, '\x03': self.handle_CTRL_C, '\x09': self.handle_TAB, })
def connectionMade(self): recvline.HistoricRecvLine.connectionMade(self) self.displayMOTD() self.cmdstack = [HoneyPotShell(self)] transport = self.terminal.transport.session.conn.transport transport.factory.sessions[transport.transport.sessionno] = self self.realClientIP = transport.transport.getPeer().host self.clientVersion = transport.otherVersionString self.logintime = transport.logintime self.ttylog_file = transport.ttylog_file # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP if self.execcmd != None: print 'Running exec cmd "%s"' % self.execcmd self.cmdstack[0].lineReceived(self.execcmd) self.terminal.transport.session.conn.sendRequest(self.terminal.transport.session, 'exit-status', struct.pack('>L', 0)) self.terminal.transport.session.conn.sendClose(self.terminal.transport.session) return # self.terminal.transport.session.conn.sendEOF(self) # key handlers after execcmd so they don't distrub binary stdin self.keyHandlers.update({ '\x04': self.handle_CTRL_D, '\x15': self.handle_CTRL_U, '\x03': self.handle_CTRL_C, '\x09': self.handle_TAB, })
def __init__(self, clientip): self.clientip = clientip performBruteforce = config().getboolean('dirtybastard', 'bruteforce_ssh_on_login') if performBruteforce: threading.Thread(target=self.bruteforceThread).start()
def loginThread(self): client = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) loginDetailString = self.username + "@" + self.clientip +" (" + self.password + ")" print "Attempting login with", loginDetailString try: client.connect(hostname=self.clientip, username=self.username, password=self.password) except: print "Authentication failed for", loginDetailString return sendEmail('New login success!', "Successfully logged in to remote box: " + loginDetailString) configName = "not_root_command" if (self.username == "root"): configName = "root_command" command = config().get('dirtybastard', configName)[1:-1] # Remove quotes print "SUCCESS! Running command: " + command stdin, stdout, stderr = client.exec_command(command) print "stdout:" stdoutString = "" for line in stdout.readlines(): print line.strip() stdoutString = stdoutString + line.strip() + "\n" sendEmail('Output from command', "stdout:\n" + stdoutString);
def connectionMade(self): recvline.HistoricRecvLine.connectionMade(self) self.displayMOTD() self.cmdstack = [HoneyPotShell(self)] transport = self.terminal.transport.session.conn.transport transport.factory.sessions[transport.transport.sessionno] = self self.realClientIP = transport.transport.getPeer().host self.clientVersion = transport.otherVersionString self.logintime = transport.logintime self.ttylog_file = transport.ttylog_file # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP self.keyHandlers.update({ '\x04': self.handle_CTRL_D, '\x15': self.handle_CTRL_U, '\x03': self.handle_CTRL_C, '\x09': self.handle_TAB, })
def buildProtocol(self, addr): _moduli = '/etc/ssh/moduli' cfg = config() # FIXME: try to mimic something real 100% t = HoneyPotTransport() if cfg.has_option('honeypot', 'ssh_version_string'): t.ourVersionString = cfg.get('honeypot','ssh_version_string') else: t.ourVersionString = "SSH-2.0-OpenSSH_5.1p1 Debian-5" t.supportedPublicKeys = self.privateKeys.keys() if ( os.path.exists( _moduli ) ): self.primes = primes.parseModuliFile( _moduli ) if not self.primes: ske = t.supportedKeyExchanges[:] ske.remove('diffie-hellman-group-exchange-sha1') t.supportedKeyExchanges = ske # reorder supported ciphers to resemble current openssh more t.supportedCiphers = ['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'blowfish-cbc', 'cast128-cbc', 'aes192-cbc', 'aes256-cbc' ] t.supportedPublicKeys = ['ssh-rsa', 'ssh-dss'] t.supportedMACs = [ 'hmac-md5', 'hmac-sha1'] t.factory = self return t
def connectionMade(self): transport = self.transport.session.conn.transport transport.ttylog_file = '%s/tty/%s-%s.log' % \ (config().get('honeypot', 'log_path'), time.strftime('%Y%m%d-%H%M%S'), transport.transportId ) log.msg( 'Opening TTY log: %s' % transport.ttylog_file ) ttylog.ttylog_open(transport.ttylog_file, time.time()) transport.ttylog_open = True transport.stdinlog_file = '%s/%s-%s-stdin.log' % \ (config().get('honeypot', 'download_path'), time.strftime('%Y%m%d-%H%M%S'), transport.transportId ) transport.stdinlog_open = False insults.ServerProtocol.connectionMade(self)
def __init__(self): #self.protocol = self.makeProtocol() cfg = config() self.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol, insults.ServerProtocol, TelnetShell, #telnetShellArg, #telnetShellKWArg="zxcv" ) self.dbloggers = [] engine = 'mysql' dbengine = 'database_' + engine lcfg = ConfigParser.ConfigParser() lcfg.add_section(dbengine) for i in cfg.options(dbengine): lcfg.set(dbengine, i, cfg.get(dbengine, i)) lcfg.add_section('honeypot') for i in cfg.options('honeypot'): lcfg.set('honeypot', i, cfg.get('honeypot', i)) dbloggerModule = __import__( 'kippo.dblog.%s' % (engine,), globals(), locals(), ['dblog']).dblog dblogger = dbloggerModule.mainLogger self.dbloggers.append(dblogger)
class HoneyPotTransport(transport.SSHServerTransport): hadVersion = False if config().has_section('packet_capture'): packetcapper = PacketCap() packetcapper.daemon = True packetcapper.start() def connectionMade(self): print 'New connection: %s:%s (%s:%s) [session: %d]' % \ (self.transport.getPeer().host, self.transport.getPeer().port, self.transport.getHost().host, self.transport.getHost().port, self.transport.sessionno) self.interactors = [] self.logintime = time.time() self.ttylog_open = False transport.SSHServerTransport.connectionMade(self) def sendKexInit(self): # Don't send key exchange prematurely if not self.gotVersion: return transport.SSHServerTransport.sendKexInit(self) def dataReceived(self, data): transport.SSHServerTransport.dataReceived(self, data) if config().has_section('packet_capture'): self.packetcapper.start_capture(self.transport.getPeer().host) # later versions seem to call sendKexInit again on their own if twisted.version.major < 11 and \ not self.hadVersion and self.gotVersion: self.sendKexInit() self.hadVersion = True def ssh_KEXINIT(self, packet): print 'Remote SSH version: %s' % (self.otherVersionString, ) return transport.SSHServerTransport.ssh_KEXINIT(self, packet) def lastlogExit(self): starttime = time.strftime('%a %b %d %H:%M', time.localtime(self.logintime)) endtime = time.strftime('%H:%M', time.localtime(time.time())) duration = utils.durationHuman(time.time() - self.logintime) clientIP = self.transport.getPeer().host utils.addToLastlog('root\tpts/0\t%s\t%s - %s (%s)' % \ (clientIP, starttime, endtime, duration)) # this seems to be the only reliable place of catching lost connection def connectionLost(self, reason): for i in self.interactors: i.sessionClosed() if self.transport.sessionno in self.factory.sessions: del self.factory.sessions[self.transport.sessionno] self.lastlogExit() if self.ttylog_open: ttylog.ttylog_close(self.ttylog_file, time.time()) self.ttylog_open = False transport.SSHServerTransport.connectionLost(self, reason)
def connectionMade(self): self.ttylog_file = '%s/tty/%s-%s.log' % \ (config().get('honeypot', 'log_path'), time.strftime('%Y%m%d-%H%M%S'), int(random.random() * 10000)) print 'Opening TTY log: %s' % self.ttylog_file ttylog.ttylog_open(self.ttylog_file, time.time()) self.ttylog_open = True insults.ServerProtocol.connectionMade(self)
def dataReceived(self, data): transport.SSHServerTransport.dataReceived(self, data) if config().has_section('packet_capture'): self.packetcapper.start_capture(self.transport.getPeer().host) # later versions seem to call sendKexInit again on their own if twisted.version.major < 11 and \ not self.hadVersion and self.gotVersion: self.sendKexInit() self.hadVersion = True
def __init__(self): self.cfg = config() self.commands = {} import kippo.commands for c in kippo.commands.__all__: module = __import__('kippo.commands.%s' % c, globals(), locals(), ['commands']) self.commands.update(module.commands) self.fs = pickle.load(file( self.cfg.get('honeypot', 'filesystem_file'), 'rb'))
def __init__(self): self.cfg = config() self.commands = {} import kippo.commands for c in kippo.commands.__all__: module = __import__('kippo.commands.%s' % c, globals(), locals(), ['commands']) self.commands.update(module.commands) self.fs = pickle.load( file(self.cfg.get('honeypot', 'filesystem_file'), 'rb'))
def save(self): '''save the user db''' userdb_file = '%s/userdb.txt' % \ (config().get('honeypot', 'data_path'),) # Note: this is subject to races between kippo instances, but hey ... f = open(userdb_file, 'w') for (login, uid, passwd) in self.userdb: f.write('%s:%d:%s\n' % (login, uid, passwd)) f.close()
def call(self): if len(self.args) and (self.args[0].strip() == '-a' or self.args[0].strip() == '--all'): cfg = config() self.system_version_string = '2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686 GNU/Linux' if cfg.has_option('honeypot', 'system_version_string'): self.system_version_string = cfg.get('honeypot', 'system_version_string') self.writeln( 'Linux %s %s' % \ (self.honeypot.hostname, self.system_version_string)) else: self.writeln('Linux')
def execCommand(self, protocol, cmd): cfg = config() if cfg.has_option('honeypot', 'exec_enabled'): if ( cfg.get('honeypot', 'exec_enabled') != "true" ): print 'exec disabled not executing command: "%s"' % cmd raise os.OSError print 'Executing command: "%s"' % cmd serverProtocol = LoggingServerProtocol(HoneyPotProtocol, self, self.env, cmd) serverProtocol.makeConnection(protocol) protocol.makeConnection(session.wrapProtocol(serverProtocol))
def sendBanner(self): if self.bannerSent: return cfg = config() if not cfg.has_option('honeypot', 'banner_file'): return data = file(cfg.get('honeypot', 'banner_file')).read() if not data or not len(data.strip()): return data = '\r\n'.join(data.splitlines() + ['']) self.transport.sendPacket(userauth.MSG_USERAUTH_BANNER, NS(data) + NS('en')) self.bannerSent = True
def sendBanner(self): if self.bannerSent: return cfg = config() if not cfg.has_option('honeypot', 'banner_file'): return data = file(cfg.get('honeypot', 'banner_file')).read() if not data or not len(data.strip()): return data = '\r\n'.join(data.splitlines() + ['']) self.transport.sendPacket( userauth.MSG_USERAUTH_BANNER, NS(data) + NS('en')) self.bannerSent = True
def checkUserPass(self, username, password): cfg = config() if UserDB().checklogin(username, password): print 'login attempt [%s/%s] succeeded' % (username, password) if cfg.has_option('smtp', 'alert_login'): if cfg.get('smtp', 'alert_login') == 'true': print 'Emailing about login notification (alert_login = true).' emailMessage = 'There was a succesfully login (%s/%s).' % (username, password) sendEmail('SSH Succesful Login', emailMessage) return True else: print 'login attempt [%s/%s] failed' % (username, password) return False
def file_contents(self, target, count=0): if count > 10: raise TooManyLevels path = self.resolve_path(target, os.path.dirname(target)) print '%s resolved into %s' % (target, path) if not path or not self.exists(path): raise FileNotFound f = self.getfile(path) if f[A_TYPE] == T_LINK: return self.file_contents(f[A_TARGET], count + 1) realfile = self.realfile(f, '%s/%s' % \ (config().get('honeypot', 'contents_path'), path)) if realfile: return file(realfile, 'rb').read()
def __init__(self, wget, fakeoutfile, url, outfile, headers=None): wget_version = 'Wget/1.11.4' cfg = config() if cfg.has_option('honeypot', 'wget_version_string'): wget_version = (cfg.get('honeypot', 'wget_version_string'), 0) client.HTTPDownloader.__init__(self, url, outfile, headers=headers, agent=wget_version) self.status = None self.wget = wget self.fakeoutfile = fakeoutfile self.lastupdate = 0 self.started = time.time() self.proglen = 0 self.nomore = False
def file_contents(self, target, count = 0): if count > 10: raise TooManyLevels path = self.resolve_path(target, os.path.dirname(target)) print '%s resolved into %s' % (target, path) if not path or not self.exists(path): raise FileNotFound f = self.getfile(path) if f[A_TYPE] == T_LINK: return self.file_contents(f[A_TARGET], count + 1) realfile = self.realfile(f, '%s/%s' % \ (config().get('honeypot', 'contents_path'), path)) if realfile: return file(realfile, 'rb').read()
def execCommand(self, protocol, cmd): cfg = config() if not cfg.has_option('honeypot', 'exec_enabled') or \ cfg.get('honeypot', 'exec_enabled').lower() not in \ ('yes', 'true', 'on'): print 'Exec disabled. Not executing command: "%s"' % cmd raise core.exceptions.NotEnabledException, \ 'exec_enabled not enabled in configuration file!' return print 'exec command: "%s"' % cmd serverProtocol = kippo.core.protocol.LoggingServerProtocol( kippo.core.protocol.HoneyPotExecProtocol, self, self.env, cmd) serverProtocol.makeConnection(protocol) protocol.makeConnection(session.wrapProtocol(serverProtocol))
def connectionMade(self): self.displayMOTD() transport = self.terminal.transport.session.conn.transport self.realClientIP = transport.transport.getPeer().host self.clientVersion = transport.otherVersionString self.logintime = transport.logintime self.ttylog_file = transport.ttylog_file # source IP of client in user visible reports (can be fake or real) cfg = config() if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = cfg.get('honeypot', 'fake_addr') else: self.clientIP = self.realClientIP
def sendBanner(self): if self.bannerSent: return cfg = config() try: honeyfs = cfg.get('honeypot', 'contents_path') issuefile = honeyfs + "/etc/issue.net" data = file(issuefile).read() except IOError: return if not data or not len(data.strip()): return data = '\r\n'.join(data.splitlines()) self.transport.sendPacket(userauth.MSG_USERAUTH_BANNER, NS(data) + NS('en')) self.bannerSent = True
def call(self): fn = '%s/lastlog.txt' % (config().get('honeypot', 'data_path'),) if not os.path.exists(fn): return l = list(self.args) numlines = 25 while len(l): arg = l.pop(0) if not arg.startswith('-'): continue elif arg[1:].isdigit(): numlines = int(arg[1:]) elif arg == '-n' and len(l) and l[0].isdigit(): numlines = int(l.pop(0)) data = utils.tail(file(fn), numlines) self.writeln(''.join(data))
def sendBanner(self): if self.bannerSent: return cfg = config() try: honeyfs = cfg.get('honeypot', 'contents_path') issuefile = honeyfs + "/etc/issue.net" data = file( issuefile ).read() except IOError: return if not data or not len(data.strip()): return data = '\r\n'.join(data.splitlines() ) self.transport.sendPacket( userauth.MSG_USERAUTH_BANNER, NS(data) + NS('en')) self.bannerSent = True
def connectionLost(self, reason): cfg = config() for i in self.interactors: i.sessionClosed() if self.transport.sessionno in self.factory.sessions: del self.factory.sessions[self.transport.sessionno] self.lastlogExit() if self.ttylog_open: ttylog.ttylog_close(self.ttylog_file, time.time()) self.ttylog_open = False if cfg.has_option('smtp', 'alert_quit'): if cfg.get('smtp', 'alert_quit') == 'true': print 'Emailing about attack being over (alert_quit = true).' emailMessage = 'The attacker quit.\n\nPlease check the logs (%s)!' % (self.ttylog_file) sendEmail('SSH Attack Finished', emailMessage) transport.SSHServerTransport.connectionLost(self, reason)
def call(self): fn = "%s/lastlog.txt" % (config().get("honeypot", "data_path"),) if not os.path.exists(fn): return l = list(self.args) numlines = 25 while len(l): arg = l.pop(0) if not arg.startswith("-"): continue elif arg[1:].isdigit(): numlines = int(arg[1:]) elif arg == "-n" and len(l) and l[0].isdigit(): numlines = int(l.pop(0)) data = utils.tail(file(fn), numlines) self.writeln("".join(data))
def buildProtocol(self, addr): cfg = config() t = HoneyPotTransport() if cfg.has_option('honeypot', 'ssh_version_string'): t.ourVersionString = cfg.get('honeypot','ssh_version_string') else: t.ourVersionString = "SSH-2.0-OpenSSH_5.1p1 Debian-5" t.supportedPublicKeys = self.privateKeys.keys() if not self.primes: ske = t.supportedKeyExchanges[:] ske.remove('diffie-hellman-group-exchange-sha1') t.supportedKeyExchanges = ske t.factory = self return t
def call(self): cfg = config() self.exit_jail = False if cfg.has_option('honeypot', 'exit_jail'): if (cfg.get('honeypot', 'exit_jail') == "true"): self.exit_jail = True if 'PuTTY' in self.honeypot.clientVersion or \ 'libssh' in self.honeypot.clientVersion or \ 'sshlib' in self.honeypot.clientVersion or \ self.exit_jail is False: self.honeypot.terminal.loseConnection() return self.writeln('Connection to server closed.') self.honeypot.hostname = 'localhost' self.honeypot.cwd = '/root' if not self.fs.exists(self.honeypot.cwd): self.honeypot.cwd = '/'
def buildProtocol(self, addr): cfg = config() t = HoneyPotTransport() if cfg.has_option('honeypot', 'ssh_version_string'): t.ourVersionString = cfg.get('honeypot', 'ssh_version_string') else: t.ourVersionString = "SSH-2.0-OpenSSH_5.1p1 Debian-5" t.supportedPublicKeys = self.privateKeys.keys() if not self.primes: ske = t.supportedKeyExchanges[:] ske.remove('diffie-hellman-group-exchange-sha1') t.supportedKeyExchanges = ske t.factory = self return t
class HonsshServerFactory(factory.SSHFactory): cfg = config() otherVersionString = '' connections = connections.Connections() hpLog = None dbLog = None def __init__(self): clientFactory = client.HonsshSlimClientFactory() clientFactory.server = self reactor.connectTCP(self.cfg.get('honeypot', 'honey_addr'), int(self.cfg.get('honeypot', 'honey_port')), clientFactory) if self.cfg.get('hpfeeds', 'enabled') == 'true': hp = hpfeeds.HPLogger() self.hpLog = hp.start(self.cfg) if self.cfg.get('database_mysql', 'enabled') == 'true': db = mysql.DBLogger() self.dbLog = db.start(self.cfg) log.msg( '[SERVER] Acquiring SSH Version String from honey_addr:honey_port') def buildProtocol(self, addr): t = HonsshServerTransport() t.ourVersionString = self.ourVersionString t.factory = self t.supportedPublicKeys = self.privateKeys.keys() if not self.primes: ske = t.supportedKeyExchanges[:] ske.remove('diffie-hellman-group-exchange-sha1') t.supportedKeyExchanges = ske t.supportedCiphers = [ 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'blowfish-cbc', 'cast128-cbc', 'aes192-cbc', 'aes256-cbc' ] t.supportedPublicKeys = ['ssh-rsa', 'ssh-dss'] t.supportedMACs = ['hmac-md5', 'hmac-sha1'] return t
def __init__(self): cfg = config() # protocol^Wwhatever instances are kept here for the interact feature self.sessions = {} # for use by the uptime command self.starttime = time.time() # convert old pass.db root passwords passdb_file = '%s/pass.db' % (cfg.get('honeypot', 'data_path'),) if os.path.exists(passdb_file): userdb = UserDB() print 'pass.db deprecated - copying passwords over to userdb.txt' if os.path.exists('%s.bak' % (passdb_file,)): print 'ERROR: %s.bak already exists, skipping conversion!' % \ (passdb_file,) else: passdb = anydbm.open(passdb_file, 'c') for p in passdb: userdb.adduser('root', 0, p) passdb.close() os.rename(passdb_file, '%s.bak' % (passdb_file,)) print 'pass.db backed up to %s.bak' % (passdb_file,) # load db loggers self.dbloggers = [] for x in cfg.sections(): if not x.startswith('database_'): continue engine = x.split('_')[1] dbengine = 'database_' + engine lcfg = ConfigParser.ConfigParser() lcfg.add_section(dbengine) for i in cfg.options(x): lcfg.set(dbengine, i, cfg.get(x, i)) lcfg.add_section('honeypot') for i in cfg.options('honeypot'): lcfg.set('honeypot', i, cfg.get('honeypot', i)) print 'Loading dblog engine: %s' % (engine,) dblogger = __import__( 'kippo.dblog.%s' % (engine,), globals(), locals(), ['dblog']).DBLogger(lcfg) log.startLoggingWithObserver(dblogger.emit, setStdout=False) self.dbloggers.append(dblogger)
def connectionMade(self): cfg = config() print 'New connection: %s:%s (%s:%s) [session: %d]' % \ (self.transport.getPeer().host, self.transport.getPeer().port, self.transport.getHost().host, self.transport.getHost().port, self.transport.sessionno) self.interactors = [] self.logintime = time.time() self.ttylog_open = False if cfg.has_option('smtp', 'alert_probe'): if cfg.get('smtp', 'alert_probe') == 'true': print 'Emailing about SSH probe (alert_probe = true).' emailMessage = 'There was an SSH probe request.\nFrom: %s:%s.\nTo: %s:%s.\nKippo Session: %s.' % \ (self.transport.getPeer().host, self.transport.getPeer().port, self.transport.getHost().host, self.transport.getHost().port, self.transport.sessionno) sendEmail('SSH Probe', emailMessage) transport.SSHServerTransport.connectionMade(self)
def sendBanner(self): # 发送欢迎信息 if self.bannerSent: return cfg = config() if not cfg.has_option('honeypot', 'banner_file'): return try: data = file(cfg.get('honeypot', 'banner_file')).read() except IOError: print 'Banner file %s does not exist!' % \ cfg.get('honeypot', 'banner_file') return if not data or not len(data.strip()): return data = '\r\n'.join(data.splitlines() + ['']) self.transport.sendPacket(userauth.MSG_USERAUTH_BANNER, NS(data) + NS('en')) self.bannerSent = True