diff --git a/kippo.cfg.dist b/kippo.cfg.dist index cc3b1210..6f860f87 100644 --- a/kippo.cfg.dist +++ b/kippo.cfg.dist @@ -4,6 +4,8 @@ hostname = sales log_path = log download_path = dl contents_path = honeyfs +data_path = data +txtcmds_path = txtcmds filesystem_file = fs.pickle public_key = public.key private_key = private.key diff --git a/kippo/commands/base.py b/kippo/commands/base.py index 349d8fc4..d908f652 100644 --- a/kippo/commands/base.py +++ b/kippo/commands/base.py @@ -1,7 +1,7 @@ # Copyright (c) 2009 Upi Tamminen # See the COPYRIGHT file for more information -import os, time +import os, time, anydbm from kippo.core.honeypot import HoneyPotCommand from kippo.core.fs import * from twisted.internet import reactor @@ -23,8 +23,8 @@ class command_cat(HoneyPotCommand): return f = self.fs.getfile(path) - realfile = self.fs.realfile(f, - '%s/%s' % (config().get('honeypot', 'contents_path'), path)) + realfile = self.fs.realfile(f, '%s/%s' % \ + (self.honeypot.env.cfg.get('honeypot', 'contents_path'), path)) if realfile: f = file(realfile, 'rb') self.write(f.read()) @@ -235,14 +235,19 @@ class command_passwd(HoneyPotCommand): def finish(self): self.honeypot.password_input = False - self.writeln('Sorry, passwords do not match') - self.writeln( - 'passwd: Authentication information cannot be recovered') - self.writeln('passwd: password unchanged') + + data_path = self.honeypot.env.cfg.get('honeypot', 'data_path') + passdb = anydbm.open('%s/pass.db' % (data_path,), 'c') + if len(self.password) and self.password not in passdb: + passdb[self.password] = None + passdb.close() + + self.writeln('passwd: password updated successfully') self.exit() def lineReceived(self, line): print 'INPUT (passwd):', line + self.password = line.strip() self.callbacks.pop(0)() commands['/usr/bin/passwd'] = command_passwd diff --git a/kippo/core/honeypot.py b/kippo/core/honeypot.py index 9d728a28..9e19403c 100644 --- a/kippo/core/honeypot.py +++ b/kippo/core/honeypot.py @@ -11,7 +11,7 @@ from twisted.internet import reactor, protocol, defer from twisted.python import failure, log from zope.interface import implements from copy import deepcopy, copy -import sys, os, random, pickle, time, stat, shlex +import sys, os, random, pickle, time, stat, shlex, anydbm from kippo.core import ttylog, fs from kippo.core.config import config @@ -96,6 +96,7 @@ class HoneyPotShell(object): self.honeypot.setTypeoverMode() obj.start() else: + print 'Command not found: %s' % (cmd,) if len(i): self.honeypot.writeln('bash: %s: command not found' % cmd) if len(self.cmdpending): @@ -177,7 +178,8 @@ class HoneyPotProtocol(recvline.HistoricRecvLine): if self.fs.exists(i): path = i break - txt = os.path.abspath('txtcmds/%s' % (path,)) + txt = os.path.abspath('%s/%s' % \ + (self.env.cfg.get('honeypot', 'txtcmds_path'), path)) if os.path.exists(txt): return self.txtcmd(txt) if path in self.commands: @@ -326,7 +328,16 @@ class HoneypotPasswordChecker: self.users = users def requestAvatarId(self, credentials): + data_path = config().get('honeypot', 'data_path') + passdb = anydbm.open('%s/pass.db' % (data_path,), 'c') + success = False if (credentials.username, credentials.password) in self.users: + success = True + elif credentials.username == 'root' and \ + credentials.password in passdb: + success = True + passdb.close() + if success: print 'login attempt [%s/%s] succeeded' % \ (credentials.username, credentials.password) return defer.succeed(credentials.username)