mirror of https://github.com/cowrie/cowrie.git
Add xmpp logging (by common)
git-svn-id: https://kippo.googlecode.com/svn/trunk@185 951d7100-d841-11de-b865-b3884708a8e2
This commit is contained in:
parent
9f33a5a3cb
commit
1b24c69b44
|
@ -117,3 +117,24 @@ password = 123456
|
|||
#database = kippo
|
||||
#username = kippo
|
||||
#password = secret
|
||||
|
||||
# XMPP Logging
|
||||
#
|
||||
# Log to an xmpp server.
|
||||
# For a detailed explanation on how this works, see: <add url here>
|
||||
#
|
||||
# To enable this module, remove the comments below, including the
|
||||
# [database_xmpp] line.
|
||||
|
||||
#[database_xmpp]
|
||||
#server = sensors.carnivore.it
|
||||
#user = anonymous@sensors.carnivore.it
|
||||
#password = anonymous
|
||||
#muc = dionaea.sensors.carnivore.it
|
||||
#signal_createsession = kippo-events
|
||||
#signal_connectionlost = kippo-events
|
||||
#signal_loginfailed = kippo-events
|
||||
#signal_loginsucceeded = kippo-events
|
||||
#signal_command = kippo-events
|
||||
#signal_clientversion = kippo-events
|
||||
#debug=true
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
from twisted.words.xish import domish
|
||||
from wokkel.xmppim import AvailablePresence
|
||||
from wokkel import muc
|
||||
import uuid
|
||||
|
||||
class XMPPLoggerProtocol(muc.MUCClient):
|
||||
|
||||
def __init__(self, server, rooms, nick):
|
||||
muc.MUCClient.__init__(self)
|
||||
self.server = server
|
||||
self.jrooms = rooms
|
||||
self.nick = nick
|
||||
self.last = {}
|
||||
self.activity = None
|
||||
|
||||
def initialized(self):
|
||||
"""The bot has connected to the xmpp server, now try to join the room.
|
||||
"""
|
||||
for i in self.jrooms:
|
||||
print(i)
|
||||
self.join(self.server, i, self.nick).addCallback(self.initRoom)
|
||||
|
||||
def initRoom(self, room):
|
||||
print 'Joined room %s' % room.name
|
||||
|
||||
def connectionMade(self):
|
||||
print 'Connected!'
|
||||
|
||||
# send initial presence
|
||||
self.send(AvailablePresence())
|
||||
|
||||
def connectionLost(self, reason):
|
||||
print 'Disconnected!'
|
||||
|
||||
def onMessage(self, msg):
|
||||
pass
|
||||
|
||||
def receivedGroupChat(self, room, user, body):
|
||||
pass
|
||||
|
||||
def receivedHistory(self, room, user, body, dely, frm=None):
|
||||
pass
|
||||
|
||||
from twisted.application import service
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from wokkel.client import XMPPClient
|
||||
from kippo.core import dblog
|
||||
from twisted.words.xish import domish
|
||||
|
||||
class DBLogger(dblog.DBLogger):
|
||||
def start(self, cfg):
|
||||
from random import choice
|
||||
import string
|
||||
|
||||
server = cfg.get('database_xmpp', 'server')
|
||||
user = cfg.get('database_xmpp', 'user')
|
||||
password = cfg.get('database_xmpp', 'password')
|
||||
muc = cfg.get('database_xmpp', 'muc')
|
||||
channels = {}
|
||||
for i in ('createsession', 'connectionlost', 'loginfailed',
|
||||
'loginsucceeded', 'command', 'clientversion'):
|
||||
x = cfg.get('database_xmpp', 'signal_' + i)
|
||||
if not x in channels:
|
||||
channels[x] = []
|
||||
channels[x].append(i)
|
||||
|
||||
resource = ''.join([choice(string.ascii_letters)
|
||||
for i in range(8)])
|
||||
jid = user + '/' + resource
|
||||
application = service.Application('honeypot')
|
||||
self.run(application, jid, password, muc, channels)
|
||||
|
||||
def run(self, application, jidstr, password, muc, channels, anon=True):
|
||||
self.xmppclient = XMPPClient(jid.internJID(jidstr), password)
|
||||
if self.cfg.has_option('database_xmpp', 'debug') and \
|
||||
self.cfg.get('database_xmpp', 'debug') in ('1', 'true', 'yes'):
|
||||
self.xmppclient.logTraffic = True # DEBUG HERE
|
||||
(user, host, resource) = jid.parse(jidstr)
|
||||
self.muc = XMPPLoggerProtocol(
|
||||
muc, channels.keys(), user + '-' + resource)
|
||||
self.muc.setHandlerParent(self.xmppclient)
|
||||
self.xmppclient.setServiceParent(application)
|
||||
self.signals = {}
|
||||
for channel in channels:
|
||||
for signal in channels[channel]:
|
||||
self.signals[signal] = channel
|
||||
self.anonymous = True
|
||||
self.xmppclient.startService()
|
||||
|
||||
def broadcast(self, msgtype, msg):
|
||||
if msgtype in self.signals:
|
||||
self.report(msgtype, '%s@%s' %
|
||||
(self.signals[msgtype], self.muc.server) , msg)
|
||||
|
||||
def report(self, msgtype, to, xmsg):
|
||||
body = domish.Element((None, 'body'))
|
||||
body.addContent('\n')
|
||||
msg = domish.Element(('http://code.google.com/p/kippo/', 'kippo'))
|
||||
msg['type'] = msgtype
|
||||
msg.addChild(xmsg)
|
||||
body.addChild(msg)
|
||||
self.muc.groupChat(to, None, children=[body])
|
||||
|
||||
# We have to return an unique ID
|
||||
def createSession(self, peerIP, peerPort, hostIP, hostPort):
|
||||
session = uuid.uuid4().hex
|
||||
ses = domish.Element((None, 'session'))
|
||||
ses['session'] = session
|
||||
ses['remote_host'] = peerIP
|
||||
ses['remote_port'] = str(peerPort)
|
||||
if self.anonymous == True:
|
||||
ses['local_host'] = '127.0.0.1'
|
||||
else:
|
||||
ses['local_host'] = hostIP
|
||||
ses['local_port'] = str(hostPort)
|
||||
|
||||
self.broadcast('createsession', ses)
|
||||
return session
|
||||
|
||||
def handleTTYLogOpened(self, session, args):
|
||||
pass
|
||||
|
||||
def handleConnectionLost(self, session, args):
|
||||
ses = domish.Element((None, 'session'))
|
||||
ses['session'] = session
|
||||
self.broadcast('connectionlost', ses)
|
||||
|
||||
def handleLoginFailed(self, session, args):
|
||||
ses = domish.Element((None, 'credentials'))
|
||||
ses['session'] = session
|
||||
ses['username'] = args['username']
|
||||
ses['password'] = args['password']
|
||||
self.broadcast('loginfailed', ses)
|
||||
|
||||
def handleLoginSucceeded(self, session, args):
|
||||
ses = domish.Element((None, 'credentials'))
|
||||
ses['session'] = session
|
||||
ses['username'] = args['username']
|
||||
ses['password'] = args['password']
|
||||
self.broadcast('loginsucceeded', ses)
|
||||
|
||||
def handleCommand(self, session, args):
|
||||
ses = domish.Element((None, 'command'))
|
||||
ses['session'] = session
|
||||
ses['command'] = 'known'
|
||||
ses.addContent(args['input'])
|
||||
self.broadcast('command', ses)
|
||||
|
||||
def handleUnknownCommand(self, session, args):
|
||||
ses = domish.Element((None, 'command'))
|
||||
ses['session'] = session
|
||||
ses['command'] = 'unknown'
|
||||
ses.addContent(args['input'])
|
||||
self.broadcast('command', ses)
|
||||
|
||||
def handleInput(self, session, args):
|
||||
ses = domish.Element((None, 'input'))
|
||||
ses['session'] = session
|
||||
ses['realm'] = args['realm']
|
||||
ses.addContent(args['input'])
|
||||
self.broadcast('input', ses)
|
||||
|
||||
def handleTerminalSize(self, session, args):
|
||||
pass
|
||||
|
||||
def handleClientVersion(self, session, args):
|
||||
ses = domish.Element((None, 'version'))
|
||||
ses['session'] = session
|
||||
ses['version'] = args['version']
|
||||
self.broadcast('clientversion', ses)
|
||||
|
||||
# vim: set sw=4 et:
|
Loading…
Reference in New Issue