mirror of
https://github.com/cowrie/cowrie.git
synced 2025-07-01 18:07:27 -04:00
remove environment. a few other optimizations. better cleanup
This commit is contained in:
@ -11,6 +11,7 @@ from twisted.python import log
|
|||||||
from . import fs
|
from . import fs
|
||||||
|
|
||||||
class HoneyPotCommand(object):
|
class HoneyPotCommand(object):
|
||||||
|
|
||||||
def __init__(self, protocol, *args):
|
def __init__(self, protocol, *args):
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
self.args = args
|
self.args = args
|
||||||
@ -25,7 +26,7 @@ class HoneyPotCommand(object):
|
|||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def call(self):
|
def call(self):
|
||||||
self.protocol.writeln('Hello World! [%s]' % (repr(self.args),))
|
self.writeln('Hello World! [%s]' % (repr(self.args),))
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
self.protocol.cmdstack.pop()
|
self.protocol.cmdstack.pop()
|
||||||
@ -258,17 +259,3 @@ class HoneyPotShell(object):
|
|||||||
self.protocol.lineBufferIndex = len(self.protocol.lineBuffer)
|
self.protocol.lineBufferIndex = len(self.protocol.lineBuffer)
|
||||||
self.protocol.terminal.write(newbuf)
|
self.protocol.terminal.write(newbuf)
|
||||||
|
|
||||||
class HoneyPotEnvironment(object):
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
def __init__(self, cfg):
|
|
||||||
self.cfg = cfg
|
|
||||||
self.commands = {}
|
|
||||||
|
|
||||||
import cowrie.commands
|
|
||||||
for c in cowrie.commands.__all__:
|
|
||||||
module = __import__('cowrie.commands.%s' % (c,),
|
|
||||||
globals(), locals(), ['commands'])
|
|
||||||
self.commands.update(module.commands)
|
|
||||||
|
|
||||||
# vim: set sw=4 et:
|
|
||||||
|
|||||||
@ -16,18 +16,26 @@ from . import ttylog
|
|||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin):
|
class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin):
|
||||||
|
|
||||||
def __init__(self, avatar):
|
def __init__(self, avatar):
|
||||||
self.user = avatar
|
self.user = avatar
|
||||||
self.env = avatar.env
|
self.cfg = self.user.cfg
|
||||||
self.cfg = self.env.cfg
|
|
||||||
self.hostname = avatar.server.hostname
|
self.hostname = avatar.server.hostname
|
||||||
self.fs = avatar.server.fs
|
self.fs = avatar.server.fs
|
||||||
if self.fs.exists(avatar.home):
|
if self.fs.exists(avatar.home):
|
||||||
self.cwd = avatar.home
|
self.cwd = avatar.home
|
||||||
else:
|
else:
|
||||||
self.cwd = '/'
|
self.cwd = '/'
|
||||||
|
|
||||||
# commands is also a copy so we can add stuff on the fly
|
# commands is also a copy so we can add stuff on the fly
|
||||||
self.commands = copy.copy(self.env.commands)
|
# self.commands = copy.copy(self.commands)
|
||||||
|
self.commands = {}
|
||||||
|
import cowrie.commands
|
||||||
|
for c in cowrie.commands.__all__:
|
||||||
|
module = __import__('cowrie.commands.%s' % (c,),
|
||||||
|
globals(), locals(), ['commands'])
|
||||||
|
self.commands.update(module.commands)
|
||||||
|
|
||||||
self.password_input = False
|
self.password_input = False
|
||||||
self.cmdstack = []
|
self.cmdstack = []
|
||||||
|
|
||||||
@ -54,14 +62,14 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin):
|
|||||||
if self.cfg.has_option('honeypot', 'internet_facing_ip'):
|
if self.cfg.has_option('honeypot', 'internet_facing_ip'):
|
||||||
self.kippoIP = self.cfg.get('honeypot', 'internet_facing_ip')
|
self.kippoIP = self.cfg.get('honeypot', 'internet_facing_ip')
|
||||||
else:
|
else:
|
||||||
# Hack to get ip
|
|
||||||
try:
|
try:
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
s.connect(("8.8.8.8", 80))
|
s.connect(("8.8.8.8", 80))
|
||||||
self.kippoIP = s.getsockname()[0]
|
self.kippoIP = s.getsockname()[0]
|
||||||
s.close()
|
|
||||||
except:
|
except:
|
||||||
self.kippoIP = '192.168.0.1'
|
self.kippoIP = '192.168.0.1'
|
||||||
|
finally:
|
||||||
|
s.close()
|
||||||
|
|
||||||
def timeoutConnection(self):
|
def timeoutConnection(self):
|
||||||
self.writeln( 'timed out waiting for input: auto-logout' )
|
self.writeln( 'timed out waiting for input: auto-logout' )
|
||||||
@ -69,13 +77,16 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin):
|
|||||||
self.terminal.transport.session.sendClose()
|
self.terminal.transport.session.sendClose()
|
||||||
|
|
||||||
# this is only called on explicit logout, not on disconnect
|
# this is only called on explicit logout, not on disconnect
|
||||||
# this indicates the closing of the channel/session, not the closing of the connection
|
# this indicates the closing of the channel/session, not the closing of the transport
|
||||||
def connectionLost(self, reason):
|
def connectionLost(self, reason):
|
||||||
pass
|
self.terminal = None # (this should be done by super below)
|
||||||
# not sure why i need to do this:
|
insults.TerminalProtocol.connectionLost(self, reason)
|
||||||
# scratch that, these don't seem to be necessary anymore:
|
self.cmdstack = None
|
||||||
#del self.fs
|
del self.commands
|
||||||
#del self.commands
|
self.fs = None
|
||||||
|
self.cfg = None
|
||||||
|
self.user = None
|
||||||
|
log.msg( "honeypot terminal protocol connection lost %s" % reason)
|
||||||
|
|
||||||
def txtcmd(self, txt):
|
def txtcmd(self, txt):
|
||||||
class command_txtcmd(honeypot.HoneyPotCommand):
|
class command_txtcmd(honeypot.HoneyPotCommand):
|
||||||
@ -103,7 +114,7 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin):
|
|||||||
path = i
|
path = i
|
||||||
break
|
break
|
||||||
txt = os.path.normpath('%s/%s' % \
|
txt = os.path.normpath('%s/%s' % \
|
||||||
(self.env.cfg.get('honeypot', 'txtcmds_path'), path))
|
(self.cfg.get('honeypot', 'txtcmds_path'), path))
|
||||||
if os.path.exists(txt) and os.path.isfile(txt):
|
if os.path.exists(txt) and os.path.isfile(txt):
|
||||||
return self.txtcmd(txt)
|
return self.txtcmd(txt)
|
||||||
if path in self.commands:
|
if path in self.commands:
|
||||||
@ -153,6 +164,7 @@ class HoneyPotExecProtocol(HoneyPotBaseProtocol):
|
|||||||
self.cmdstack = [honeypot.HoneyPotShell(self, interactive=False)]
|
self.cmdstack = [honeypot.HoneyPotShell(self, interactive=False)]
|
||||||
self.cmdstack[0].lineReceived(self.execcmd)
|
self.cmdstack[0].lineReceived(self.execcmd)
|
||||||
|
|
||||||
|
|
||||||
class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLine):
|
class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLine):
|
||||||
|
|
||||||
def __init__(self, avatar):
|
def __init__(self, avatar):
|
||||||
@ -195,7 +207,7 @@ 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)
|
||||||
f = file('%s/lastlog.txt' % self.env.cfg.get('honeypot', 'data_path'), 'a')
|
f = file('%s/lastlog.txt' % self.cfg.get('honeypot', 'data_path'), 'a')
|
||||||
f.write('root\tpts/0\t%s\t%s - %s (%s)\n' % \
|
f.write('root\tpts/0\t%s\t%s - %s (%s)\n' % \
|
||||||
(self.clientIP, starttime, endtime, duration))
|
(self.clientIP, starttime, endtime, duration))
|
||||||
f.close()
|
f.close()
|
||||||
@ -312,7 +324,8 @@ class LoggingServerProtocol(insults.ServerProtocol):
|
|||||||
# FIXME: this method is called 4 times on logout....
|
# FIXME: this method is called 4 times on logout....
|
||||||
# it's called once from Avatar.closed() if disconnected
|
# it's called once from Avatar.closed() if disconnected
|
||||||
def connectionLost(self, reason):
|
def connectionLost(self, reason):
|
||||||
# log.msg("received call to LSP.connectionLost")
|
self.cfg = None
|
||||||
|
log.msg("received call to LSP.connectionLost")
|
||||||
transport = self.transport.session.conn.transport
|
transport = self.transport.session.conn.transport
|
||||||
if self.ttylog_open:
|
if self.ttylog_open:
|
||||||
log.msg(eventid='KIPP0012', format='Closing TTY Log: %(ttylog)s',
|
log.msg(eventid='KIPP0012', format='Closing TTY Log: %(ttylog)s',
|
||||||
|
|||||||
@ -44,23 +44,25 @@ class HoneyPotRealm:
|
|||||||
|
|
||||||
def __init__(self, cfg):
|
def __init__(self, cfg):
|
||||||
self.cfg = cfg
|
self.cfg = cfg
|
||||||
self.servers = {}
|
# self.servers = {}
|
||||||
|
|
||||||
def requestAvatar(self, avatarId, mind, *interfaces):
|
def requestAvatar(self, avatarId, mind, *interfaces):
|
||||||
|
|
||||||
if mind in self.servers:
|
# if mind in self.servers:
|
||||||
log.msg( "Using existing server for mind %s" % mind )
|
# log.msg( "Using existing server for mind %s" % mind )
|
||||||
else:
|
# for i in self.servers[mind].avatars:
|
||||||
log.msg( "Starting new server for mind %s" % mind )
|
# log.msg( "attached avatar: %s" % repr(i) )
|
||||||
self.servers[mind] = _server = server.CowrieServer(self.cfg)
|
#else:
|
||||||
|
# log.msg( "Starting new server for mind %s" % mind )
|
||||||
|
# self.servers[mind] = server.CowrieServer(self.cfg)
|
||||||
|
|
||||||
for i in list(self.servers.keys()):
|
# for i in list(self.servers.keys()):
|
||||||
log.msg( "REFCOUNT: key: %s, refcount %d" % ( i, sys.getrefcount(self.servers[i])))
|
# log.msg( "REFCOUNT: key: %s, refcount %d" % ( i, sys.getrefcount(self.servers[i])))
|
||||||
log.msg( "Refer: %s" % repr( gc.get_referrers(self.servers[i])))
|
# log.msg( "Refer: %s" % repr( gc.get_referrers(self.servers[i])))
|
||||||
|
|
||||||
if conchinterfaces.IConchUser in interfaces:
|
if conchinterfaces.IConchUser in interfaces:
|
||||||
return interfaces[0], \
|
return interfaces[0], \
|
||||||
ssh.HoneyPotAvatar(avatarId, self.servers[mind]), lambda: None
|
ssh.HoneyPotAvatar(avatarId, server.CowrieServer(self.cfg)), lambda:None
|
||||||
else:
|
else:
|
||||||
raise Exception("No supported interfaces found.")
|
raise Exception("No supported interfaces found.")
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
# SUCH DAMAGE.
|
# SUCH DAMAGE.
|
||||||
|
|
||||||
import copy
|
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
import twisted.python.log as log
|
import twisted.python.log as log
|
||||||
@ -45,9 +44,8 @@ class CowrieServer:
|
|||||||
"""
|
"""
|
||||||
def __init__(self, cfg):
|
def __init__(self, cfg):
|
||||||
self.cfg = cfg
|
self.cfg = cfg
|
||||||
self.env = honeypot.HoneyPotEnvironment(cfg)
|
self.avatars = []
|
||||||
self.hostname = self.cfg.get('honeypot', 'hostname')
|
self.hostname = self.cfg.get('honeypot', 'hostname')
|
||||||
log.msg ("Loading pickle file...")
|
pckl = pickle.load(file(cfg.get('honeypot', 'filesystem_file'), 'rb'))
|
||||||
self.pickle = pickle.load(file(cfg.get('honeypot', 'filesystem_file'), 'rb'))
|
self.fs = fs.HoneyPotFilesystem(pckl,self.cfg)
|
||||||
self.fs = fs.HoneyPotFilesystem(self.pickle,self.cfg)
|
|
||||||
|
|
||||||
|
|||||||
@ -39,9 +39,8 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
|
|||||||
if self.bannerSent:
|
if self.bannerSent:
|
||||||
return
|
return
|
||||||
self.bannerSent = True
|
self.bannerSent = True
|
||||||
cfg = self.portal.realm.cfg
|
|
||||||
try:
|
try:
|
||||||
honeyfs = cfg.get('honeypot', 'contents_path')
|
honeyfs = self.portal.realm.cfg.get('honeypot', 'contents_path')
|
||||||
issuefile = honeyfs + "/etc/issue.net"
|
issuefile = honeyfs + "/etc/issue.net"
|
||||||
data = file(issuefile).read()
|
data = file(issuefile).read()
|
||||||
except IOError:
|
except IOError:
|
||||||
@ -91,7 +90,7 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
|
|||||||
Convert a list of PAM authentication questions into a
|
Convert a list of PAM authentication questions into a
|
||||||
MSG_USERAUTH_INFO_REQUEST. Returns a Deferred that will be called
|
MSG_USERAUTH_INFO_REQUEST. Returns a Deferred that will be called
|
||||||
back when the user has responses to the questions.
|
back when the user has responses to the questions.
|
||||||
|
|
||||||
@param items: a list of 2-tuples (message, kind). We only care about
|
@param items: a list of 2-tuples (message, kind). We only care about
|
||||||
kinds 1 (password) and 2 (text).
|
kinds 1 (password) and 2 (text).
|
||||||
@type items: C{list}
|
@type items: C{list}
|
||||||
@ -129,7 +128,7 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
|
|||||||
string response n
|
string response n
|
||||||
"""
|
"""
|
||||||
d, self._pamDeferred = self._pamDeferred, None
|
d, self._pamDeferred = self._pamDeferred, None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resp = []
|
resp = []
|
||||||
numResps = struct.unpack('>L', packet[:4])[0]
|
numResps = struct.unpack('>L', packet[:4])[0]
|
||||||
@ -219,6 +218,8 @@ class HoneyPotSSHFactory(factory.SSHFactory):
|
|||||||
@return: The built transport.
|
@return: The built transport.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
log.msg(" MICHEL: currently open session %s" % self.sessions )
|
||||||
|
|
||||||
_modulis = '/etc/ssh/moduli', '/private/etc/moduli'
|
_modulis = '/etc/ssh/moduli', '/private/etc/moduli'
|
||||||
|
|
||||||
# FIXME: try to mimic something real 100%
|
# FIXME: try to mimic something real 100%
|
||||||
@ -343,6 +344,8 @@ class HoneyPotTransport(transport.SSHServerTransport):
|
|||||||
if self.transport.sessionno in self.factory.sessions:
|
if self.transport.sessionno in self.factory.sessions:
|
||||||
del self.factory.sessions[self.transport.sessionno]
|
del self.factory.sessions[self.transport.sessionno]
|
||||||
transport.SSHServerTransport.connectionLost(self, reason)
|
transport.SSHServerTransport.connectionLost(self, reason)
|
||||||
|
self.transport.connectionLost(reason)
|
||||||
|
self.transport = None
|
||||||
log.msg(eventid='KIPP0011', format='Connection lost')
|
log.msg(eventid='KIPP0011', format='Connection lost')
|
||||||
|
|
||||||
def sendDisconnect(self, reason, desc):
|
def sendDisconnect(self, reason, desc):
|
||||||
@ -418,18 +421,18 @@ class HoneyPotAvatar(avatar.ConchUser):
|
|||||||
self.username = username
|
self.username = username
|
||||||
self.server = server
|
self.server = server
|
||||||
self.cfg = self.server.cfg
|
self.cfg = self.server.cfg
|
||||||
self.env = self.server.env
|
|
||||||
self.protocol = None
|
self.protocol = None
|
||||||
|
self.IAMAVATAR = server
|
||||||
|
|
||||||
self.channelLookup.update({'session': HoneyPotSSHSession})
|
self.channelLookup.update({'session': HoneyPotSSHSession})
|
||||||
self.channelLookup['direct-tcpip'] = CowrieOpenConnectForwardingClient
|
self.channelLookup['direct-tcpip'] = CowrieOpenConnectForwardingClient
|
||||||
|
|
||||||
# sftp support enabled only when option is explicitly set
|
# sftp support enabled only when option is explicitly set
|
||||||
if self.env.cfg.has_option('honeypot', 'sftp_enabled'):
|
if self.cfg.has_option('honeypot', 'sftp_enabled'):
|
||||||
if (self.env.cfg.get('honeypot', 'sftp_enabled') == "true"):
|
if (self.cfg.get('honeypot', 'sftp_enabled') == "true"):
|
||||||
self.subsystemLookup['sftp'] = filetransfer.FileTransferServer
|
self.subsystemLookup['sftp'] = filetransfer.FileTransferServer
|
||||||
|
|
||||||
self.uid = self.gid = auth.UserDB(self.env.cfg).getUID(self.username)
|
self.uid = self.gid = auth.UserDB(self.cfg).getUID(self.username)
|
||||||
if not self.uid:
|
if not self.uid:
|
||||||
self.home = '/root'
|
self.home = '/root'
|
||||||
else:
|
else:
|
||||||
@ -465,6 +468,7 @@ class HoneyPotAvatar(avatar.ConchUser):
|
|||||||
def closed(self):
|
def closed(self):
|
||||||
if self.protocol:
|
if self.protocol:
|
||||||
self.protocol.connectionLost("disconnected")
|
self.protocol.connectionLost("disconnected")
|
||||||
|
self.protocol = None
|
||||||
|
|
||||||
def eofReceived(self):
|
def eofReceived(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user