pass config file as parameter everywhere

This commit is contained in:
Michel Oosterhof
2015-06-11 13:33:29 +00:00
parent 8e06a886da
commit b234efa489
10 changed files with 60 additions and 83 deletions

View File

@@ -108,12 +108,6 @@ rsa_private_key = data/ssh_host_rsa_key
dsa_public_key = data/ssh_host_dsa_key.pub dsa_public_key = data/ssh_host_dsa_key.pub
dsa_private_key = data/ssh_host_dsa_key dsa_private_key = data/ssh_host_dsa_key
# Enables passing commands using ssh execCommand
# e.g. ssh root@localhost <command>
#
# (default: false)
exec_enabled = true
# sftp_enabled enables the sftp subsystem # sftp_enabled enables the sftp subsystem
sftp_enabled = true sftp_enabled = true

View File

@@ -3,14 +3,13 @@
from cowrie.core.honeypot import HoneyPotCommand from cowrie.core.honeypot import HoneyPotCommand
from cowrie.core.fs import * from cowrie.core.fs import *
from cowrie.core.config import config
from cowrie.core import utils from cowrie.core import utils
commands = {} commands = {}
class command_last(HoneyPotCommand): class command_last(HoneyPotCommand):
def call(self): def call(self):
fn = '%s/lastlog.txt' % (config().get('honeypot', 'data_path'),) fn = '%s/lastlog.txt' % self.honeypot.env.cfg.get('honeypot', 'data_path')
if not os.path.exists(fn): if not os.path.exists(fn):
return return
l = list(self.args) l = list(self.args)

View File

@@ -19,14 +19,12 @@ from twisted.python import log, failure
from twisted.conch import error from twisted.conch import error
from twisted.conch.ssh import keys from twisted.conch.ssh import keys
from config import config
# by Walter de Jong <walter@sara.nl> # by Walter de Jong <walter@sara.nl>
class UserDB(object): class UserDB(object):
def __init__(self): def __init__(self, cfg):
self.userdb = [] self.userdb = []
self.userdb_file = '%s/userdb.txt' % (config().get('honeypot', 'data_path'),) self.userdb_file = '%s/userdb.txt' % cfg.get('honeypot', 'data_path')
self.load() self.load()
def load(self): def load(self):
@@ -126,7 +124,7 @@ class AuthRandom(object):
Users will be authenticated after a random number of attempts. Users will be authenticated after a random number of attempts.
""" """
def __init__(self, parameters): def __init__(self, cfg, parameters):
# Default values # Default values
self.mintry, self.maxtry, self.maxcache = 2, 5, 10 self.mintry, self.maxtry, self.maxcache = 2, 5, 10
parlist = parameters.split(',') parlist = parameters.split(',')
@@ -139,7 +137,7 @@ class AuthRandom(object):
self.maxtry = self.mintry + 1 self.maxtry = self.mintry + 1
log.msg('maxtry < mintry, adjusting maxtry to: %d' % self.maxtry) log.msg('maxtry < mintry, adjusting maxtry to: %d' % self.maxtry)
self.uservar = {} self.uservar = {}
self.uservar_file = '%s/uservar.json' % (config().get('honeypot', 'data_path')) self.uservar_file = '%s/uservar.json' % cfg.get('honeypot', 'data_path'))
self.loadvars() self.loadvars()
def loadvars(self): def loadvars(self):
@@ -245,6 +243,9 @@ class HoneypotPublicKeyChecker:
credentialInterfaces = (ISSHPrivateKey,) credentialInterfaces = (ISSHPrivateKey,)
def __init__(self, cfg):
pass
def requestAvatarId(self, credentials): def requestAvatarId(self, credentials):
_pubKey = keys.Key.fromString(credentials.blob) _pubKey = keys.Key.fromString(credentials.blob)
log.msg(format='public key attempt for user %(username)s with fingerprint %(fingerprint)s', log.msg(format='public key attempt for user %(username)s with fingerprint %(fingerprint)s',
@@ -278,6 +279,9 @@ class HoneypotPasswordChecker:
credentialInterfaces = (IUsernamePassword, IPluggableAuthenticationModules) credentialInterfaces = (IUsernamePassword, IPluggableAuthenticationModules)
def __init__(self, cfg):
self.cfg = cfg
def requestAvatarId(self, credentials): def requestAvatarId(self, credentials):
if hasattr(credentials, 'password'): if hasattr(credentials, 'password'):
if self.checkUserPass(credentials.username, credentials.password, if self.checkUserPass(credentials.username, credentials.password,
@@ -303,19 +307,19 @@ class HoneypotPasswordChecker:
def checkUserPass(self, theusername, thepassword, ip): def checkUserPass(self, theusername, thepassword, ip):
# UserDB is the default auth_class # UserDB is the default auth_class
authname = UserDB authname = UserDB
parameters = None parameters = self.cfg
# Is the auth_class defined in the config file? # Is the auth_class defined in the config file?
if config().has_option('honeypot', 'auth_class'): if self.cfg.has_option('honeypot', 'auth_class'):
authclass = config().get('honeypot', 'auth_class') authclass = self.cfg.get('honeypot', 'auth_class')
# Check if authclass exists in this module # Check if authclass exists in this module
if hasattr(modules[__name__], authclass): if hasattr(modules[__name__], authclass):
authname = getattr(modules[__name__], authclass) authname = getattr(modules[__name__], authclass)
# Are there auth_class parameters? # Are there auth_class parameters?
if config().has_option('honeypot', 'auth_class_parameters'): if self.cfg.has_option('honeypot', 'auth_class_parameters'):
parameters = config().get('honeypot', 'auth_class_parameters') parameters = self.cfg.get('honeypot', 'auth_class_parameters')
else: else:
log.msg('auth_class: %s not found in %s' % (authclass, __name__)) log.msg('auth_class: %s not found in %s' % (authclass, __name__))

View File

@@ -1,16 +1,9 @@
# Copyright (c) 2009-2014 Upi Tamminen <desaster@gmail.com> # Copyright (c) 2009-2014 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information # See the COPYRIGHT file for more information
import os
import ConfigParser import ConfigParser
def config(): def readConfigFile(cfgfile):
cfg = ConfigParser.SafeConfigParser()
f = 'cowrie.cfg'
cfg.readfp(open(f))
return cfg
def readConfigFile(cfgfile)
cfg = ConfigParser.SafeConfigParser() cfg = ConfigParser.SafeConfigParser()
cfg.readfp(open(cfgfile)) cfg.readfp(open(cfgfile))
return cfg return cfg

View File

@@ -11,8 +11,6 @@ import errno
from twisted.python import log from twisted.python import log
from config import config
A_NAME, \ A_NAME, \
A_TYPE, \ A_TYPE, \
A_UID, \ A_UID, \
@@ -38,8 +36,9 @@ class FileNotFound(Exception):
pass pass
class HoneyPotFilesystem(object): class HoneyPotFilesystem(object):
def __init__(self, fs): def __init__(self, fs, cfg):
self.fs = fs self.fs = fs
self.cfg = cfg
# keep track of open file descriptors # keep track of open file descriptors
self.tempfiles = {} self.tempfiles = {}
@@ -152,7 +151,7 @@ class HoneyPotFilesystem(object):
return self.file_contents(f[A_TARGET], count + 1) return self.file_contents(f[A_TARGET], count + 1)
realfile = self.realfile(f, '%s/%s' % \ realfile = self.realfile(f, '%s/%s' % \
(config().get('honeypot', 'contents_path'), path)) (self.cfg.get('honeypot', 'contents_path'), path))
if realfile: if realfile:
return file(realfile, 'rb').read() return file(realfile, 'rb').read()
@@ -226,7 +225,7 @@ class HoneyPotFilesystem(object):
#log.msg("fs.open wronly") #log.msg("fs.open wronly")
tempfile = '%s/%s_%s' % \ tempfile = '%s/%s_%s' % \
(config().get('honeypot', 'download_path'), (self.cfg.get('honeypot', 'download_path'),
time.strftime('%Y%m%d%H%M%S'), time.strftime('%Y%m%d%H%M%S'),
re.sub('[^A-Za-z0-9]', '_', filename)) re.sub('[^A-Za-z0-9]', '_', filename))
#log.msg("fs.open file for writing, saving to %s" % safeoutfile) #log.msg("fs.open file for writing, saving to %s" % safeoutfile)
@@ -256,7 +255,7 @@ class HoneyPotFilesystem(object):
if self.tempfiles[fd] is not None: if self.tempfiles[fd] is not None:
shasum = hashlib.sha256(open(self.tempfiles[fd], 'rb').read()).hexdigest() shasum = hashlib.sha256(open(self.tempfiles[fd], 'rb').read()).hexdigest()
log.msg("SHA sum %s" % (shasum)) log.msg("SHA sum %s" % (shasum))
shasumfile = config().get('honeypot', 'download_path') + "/" + shasum shasumfile = self.cfg.get('honeypot', 'download_path') + "/" + shasum
if (os.path.exists(shasumfile)): if (os.path.exists(shasumfile)):
os.remove(self.tempfiles[fd]) os.remove(self.tempfiles[fd])
else: else:

View File

@@ -10,7 +10,6 @@ import pickle
from twisted.python import log from twisted.python import log
import fs import fs
from config import config
class HoneyPotCommand(object): class HoneyPotCommand(object):
def __init__(self, protocol, *args): def __init__(self, protocol, *args):
@@ -253,8 +252,8 @@ class HoneyPotShell(object):
self.honeypot.terminal.write(newbuf) self.honeypot.terminal.write(newbuf)
class HoneyPotEnvironment(object): class HoneyPotEnvironment(object):
def __init__(self): def __init__(self, cfg):
self.cfg = config() self.cfg = cfg
self.commands = {} self.commands = {}
import cowrie.commands import cowrie.commands
for c in cowrie.commands.__all__: for c in cowrie.commands.__all__:
@@ -262,6 +261,6 @@ class HoneyPotEnvironment(object):
globals(), locals(), ['commands']) globals(), locals(), ['commands'])
self.commands.update(module.commands) self.commands.update(module.commands)
self.fs = pickle.load(file( self.fs = pickle.load(file(
self.cfg.get('honeypot', 'filesystem_file'), 'rb')) cfg.get('honeypot', 'filesystem_file'), 'rb'))
# vim: set sw=4 et: # vim: set sw=4 et:

View File

@@ -13,12 +13,12 @@ from twisted.python import log
import honeypot import honeypot
import ttylog import ttylog
import utils import utils
from config import config
class HoneyPotBaseProtocol(insults.TerminalProtocol): class HoneyPotBaseProtocol(insults.TerminalProtocol):
def __init__(self, avatar, env): def __init__(self, avatar, env):
self.user = avatar self.user = avatar
self.env = env self.env = env
self.cfg = self.env.cfg
self.hostname = avatar.hostname self.hostname = avatar.hostname
self.fs = avatar.fs self.fs = avatar.fs
if self.fs.exists(avatar.home): if self.fs.exists(avatar.home):
@@ -44,14 +44,13 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol):
self.logintime = time.time() self.logintime = time.time()
# source IP of client in user visible reports (can be fake or real) # source IP of client in user visible reports (can be fake or real)
cfg = config() if self.cfg.has_option('honeypot', 'fake_addr'):
if cfg.has_option('honeypot', 'fake_addr'): self.clientIP = self.cfg.get('honeypot', 'fake_addr')
self.clientIP = cfg.get('honeypot', 'fake_addr')
else: else:
self.clientIP = self.realClientIP self.clientIP = self.realClientIP
if cfg.has_option('honeypot', 'internet_facing_ip'): if self.cfg.has_option('honeypot', 'internet_facing_ip'):
self.kippoIP = cfg.get('honeypot', 'internet_facing_ip') self.kippoIP = self.cfg.get('honeypot', 'internet_facing_ip')
else: else:
# Hack to get ip # Hack to get ip
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@@ -184,8 +183,10 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin
endtime = time.strftime('%H:%M', endtime = time.strftime('%H:%M',
time.localtime(time.time())) time.localtime(time.time()))
duration = utils.durationHuman(time.time() - self.logintime) duration = utils.durationHuman(time.time() - self.logintime)
utils.addToLastlog('root\tpts/0\t%s\t%s - %s (%s)' % \ f = file('%s/lastlog.txt' % self.env.cfg.get('honeypot', 'data_path'), 'a')
f.write('root\tpts/0\t%s\t%s - %s (%s)\n' % \
(self.clientIP, starttime, endtime, duration)) (self.clientIP, starttime, endtime, duration))
f.close()
# this doesn't seem to be called upon disconnect, so please use # this doesn't seem to be called upon disconnect, so please use
# HoneyPotTransport.connectionLost instead # HoneyPotTransport.connectionLost instead
@@ -243,10 +244,16 @@ class LoggingServerProtocol(insults.ServerProtocol):
""" """
Wrapper for ServerProtocol that implements TTY logging Wrapper for ServerProtocol that implements TTY logging
""" """
def __init__(self, prot=None, *a, **kw):
insults.ServerProtocol.__init__(self, prot, *a, **kw)
self.cfg = a[1].cfg
def connectionMade(self): def connectionMade(self):
transport = self.transport.session.conn.transport transport = self.transport.session.conn.transport
transport.ttylog_file = '%s/tty/%s-%s.log' % \ transport.ttylog_file = '%s/tty/%s-%s.log' % \
(config().get('honeypot', 'log_path'), (self.cfg.get('honeypot', 'log_path'),
time.strftime('%Y%m%d-%H%M%S'), transport.transportId) time.strftime('%Y%m%d-%H%M%S'), transport.transportId)
self.ttylog_file = transport.ttylog_file self.ttylog_file = transport.ttylog_file
@@ -257,7 +264,7 @@ class LoggingServerProtocol(insults.ServerProtocol):
self.ttylog_open = True self.ttylog_open = True
self.stdinlog_file = '%s/%s-%s-stdin.log' % \ self.stdinlog_file = '%s/%s-%s-stdin.log' % \
(config().get('honeypot', 'download_path'), (self.cfg.get('honeypot', 'download_path'),
time.strftime('%Y%m%d-%H%M%S'), transport.transportId) time.strftime('%Y%m%d-%H%M%S'), transport.transportId)
self.stdinlog_open = False self.stdinlog_open = False

View File

@@ -28,7 +28,6 @@ import honeypot
import protocol import protocol
import sshserver import sshserver
import exceptions import exceptions
from config import config
class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer): class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
def serviceStarted(self): def serviceStarted(self):
@@ -38,7 +37,7 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
def sendBanner(self): def sendBanner(self):
if self.bannerSent: if self.bannerSent:
return return
cfg = config() cfg = self.portal.realm.cfg
try: try:
honeyfs = cfg.get('honeypot', 'contents_path') honeyfs = cfg.get('honeypot', 'contents_path')
issuefile = honeyfs + "/etc/issue.net" issuefile = honeyfs + "/etc/issue.net"
@@ -90,6 +89,8 @@ class HoneyPotSSHFactory(factory.SSHFactory):
def __init__(self, cfg): def __init__(self, cfg):
self.cfg = cfg
# protocol^Wwhatever instances are kept here for the interact feature # protocol^Wwhatever instances are kept here for the interact feature
self.sessions = {} self.sessions = {}
@@ -97,8 +98,8 @@ class HoneyPotSSHFactory(factory.SSHFactory):
self.starttime = time.time() self.starttime = time.time()
# load/create keys # load/create keys
rsa_pubKeyString, rsa_privKeyString = getRSAKeys() rsa_pubKeyString, rsa_privKeyString = getRSAKeys(self.cfg)
dsa_pubKeyString, dsa_privKeyString = getDSAKeys() dsa_pubKeyString, dsa_privKeyString = getDSAKeys(self.cfg)
self.publicKeys = {'ssh-rsa': keys.Key.fromString(data=rsa_pubKeyString), self.publicKeys = {'ssh-rsa': keys.Key.fromString(data=rsa_pubKeyString),
'ssh-dss': keys.Key.fromString(data=dsa_pubKeyString)} 'ssh-dss': keys.Key.fromString(data=dsa_pubKeyString)}
self.privateKeys = {'ssh-rsa': keys.Key.fromString(data=rsa_privKeyString), self.privateKeys = {'ssh-rsa': keys.Key.fromString(data=rsa_privKeyString),
@@ -158,13 +159,12 @@ class HoneyPotSSHFactory(factory.SSHFactory):
""" """
_moduli = '/etc/ssh/moduli' _moduli = '/etc/ssh/moduli'
cfg = config()
# FIXME: try to mimic something real 100% # FIXME: try to mimic something real 100%
t = HoneyPotTransport() t = HoneyPotTransport()
if cfg.has_option('honeypot', 'ssh_version_string'): if self.cfg.has_option('honeypot', 'ssh_version_string'):
t.ourVersionString = cfg.get('honeypot', 'ssh_version_string') t.ourVersionString = self.cfg.get('honeypot', 'ssh_version_string')
else: else:
t.ourVersionString = "SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u2" t.ourVersionString = "SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u2"
@@ -192,9 +192,9 @@ class HoneyPotSSHFactory(factory.SSHFactory):
@implementer(portal.IRealm) @implementer(portal.IRealm)
class HoneyPotRealm: class HoneyPotRealm:
def __init__(self): def __init__(self, cfg):
# I don't know if i'm supposed to keep static stuff here self.cfg = cfg
self.env = honeypot.HoneyPotEnvironment() self.env = honeypot.HoneyPotEnvironment(cfg)
def requestAvatar(self, avatarId, mind, *interfaces): def requestAvatar(self, avatarId, mind, *interfaces):
if conchinterfaces.IConchUser in interfaces: if conchinterfaces.IConchUser in interfaces:
@@ -324,7 +324,7 @@ class HoneyPotAvatar(avatar.ConchUser):
if (self.env.cfg.get('honeypot', 'sftp_enabled') == "true"): if (self.env.cfg.get('honeypot', 'sftp_enabled') == "true"):
self.subsystemLookup['sftp'] = filetransfer.FileTransferServer self.subsystemLookup['sftp'] = filetransfer.FileTransferServer
self.uid = self.gid = auth.UserDB().getUID(self.username) self.uid = self.gid = auth.UserDB(self.env.cfg).getUID(self.username)
if not self.uid: if not self.uid:
self.home = '/root' self.home = '/root'
else: else:
@@ -348,15 +348,6 @@ class HoneyPotAvatar(avatar.ConchUser):
return None return None
def execCommand(self, proto, cmd): def execCommand(self, proto, cmd):
cfg = config()
if not cfg.has_option('honeypot', 'exec_enabled') or \
cfg.get('honeypot', 'exec_enabled').lower() not in \
('yes', 'true', 'on'):
log.msg('Exec disabled. Not executing command: "%s"' % cmd)
raise exceptions.NotEnabledException(
'exec_enabled not enabled in configuration file!')
return
serverProtocol = protocol.LoggingServerProtocol( serverProtocol = protocol.LoggingServerProtocol(
protocol.HoneyPotExecProtocol, self, self.env, cmd) protocol.HoneyPotExecProtocol, self, self.env, cmd)
self.protocol = serverProtocol self.protocol = serverProtocol
@@ -376,8 +367,7 @@ class HoneyPotAvatar(avatar.ConchUser):
def windowChanged(self, windowSize): def windowChanged(self, windowSize):
self.windowSize = windowSize self.windowSize = windowSize
def getRSAKeys(): def getRSAKeys(cfg):
cfg = config()
public_key = cfg.get('honeypot', 'rsa_public_key') public_key = cfg.get('honeypot', 'rsa_public_key')
private_key = cfg.get('honeypot', 'rsa_private_key') private_key = cfg.get('honeypot', 'rsa_private_key')
if not (os.path.exists(public_key) and os.path.exists(private_key)): if not (os.path.exists(public_key) and os.path.exists(private_key)):
@@ -399,8 +389,7 @@ def getRSAKeys():
privateKeyString = f.read() privateKeyString = f.read()
return publicKeyString, privateKeyString return publicKeyString, privateKeyString
def getDSAKeys(): def getDSAKeys(cfg):
cfg = config()
public_key = cfg.get('honeypot', 'dsa_public_key') public_key = cfg.get('honeypot', 'dsa_public_key')
private_key = cfg.get('honeypot', 'dsa_private_key') private_key = cfg.get('honeypot', 'dsa_private_key')
if not (os.path.exists(public_key) and os.path.exists(private_key)): if not (os.path.exists(public_key) and os.path.exists(private_key)):

View File

@@ -1,13 +1,6 @@
# Copyright (c) 2010-2014 Upi Tamminen <desaster@gmail.com> # Copyright (c) 2010-2014 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information # See the COPYRIGHT file for more information
from config import config
def addToLastlog(message):
f = file('%s/lastlog.txt' % config().get('honeypot', 'data_path'), 'a')
f.write('%s\n' % (message,))
f.close()
def durationHuman(seconds): def durationHuman(seconds):
seconds = long(round(seconds)) seconds = long(round(seconds))
minutes, seconds = divmod(seconds, 60) minutes, seconds = divmod(seconds, 60)

View File

@@ -9,7 +9,7 @@ from twisted.application.service import IServiceMaker
from twisted.application import internet, service from twisted.application import internet, service
from twisted.cred import portal from twisted.cred import portal
from cowrie.core.config import config from cowrie.core.config import readConfigFile
from cowrie import core from cowrie import core
import cowrie.core.ssh import cowrie.core.ssh
@@ -34,7 +34,7 @@ class CowrieServiceMaker(object):
print 'ERROR: You must not run cowrie as root!' print 'ERROR: You must not run cowrie as root!'
sys.exit(1) sys.exit(1)
cfg = readCfgFile(options["config"])) cfg = readConfigFile(options["config"])
if cfg.has_option('honeypot', 'listen_addr'): if cfg.has_option('honeypot', 'listen_addr'):
listen_addr = cfg.get('honeypot', 'listen_addr') listen_addr = cfg.get('honeypot', 'listen_addr')
@@ -49,10 +49,10 @@ class CowrieServiceMaker(object):
else: else:
listen_port = 2222 listen_port = 2222
factory = core.ssh.HoneyPotSSHFactory(cfg)) factory = core.ssh.HoneyPotSSHFactory(cfg)
factory.portal = portal.Portal(core.ssh.HoneyPotRealm()) factory.portal = portal.Portal(core.ssh.HoneyPotRealm(cfg))
factory.portal.registerChecker(core.auth.HoneypotPublicKeyChecker()) factory.portal.registerChecker(core.auth.HoneypotPublicKeyChecker(cfg))
factory.portal.registerChecker(core.auth.HoneypotPasswordChecker()) factory.portal.registerChecker(core.auth.HoneypotPasswordChecker(cfg))
top_service = top_service = service.MultiService() top_service = top_service = service.MultiService()