Skip to content

Commit

Permalink
enchanced communication protocol with feeder bot!
Browse files Browse the repository at this point in the history
  • Loading branch information
pjlantz committed Jul 22, 2010
1 parent e2e0fdf commit da01996
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 86 deletions.
69 changes: 46 additions & 23 deletions src/conf/configHandler.py
Expand Up @@ -101,30 +101,27 @@ def listConf(self):
return
print lsStr

def useConf(self, section, startEvent=False):
def useConf(self, section):
"""
Set config name 'section' to be used
"""

if not startEvent:
if len(section) == 0 or section == 'uniqueKeys':
if len(self.currentSection) == 0:
print "[ConfigHandler]: No config loaded "
else:
print "[ConfigHandler]: Using " + self.currentSection
return

self.currentConfig = ConfigParser()
self.currentConfig.read(self.currentConfigFile)
try:
for option in self.currentConfig.options(section):
self.current[option] = self.currentConfig.get(section, option)
except NoSectionError:
print "[ConfigHandler]: No such config " + section
return
else:
self.current = section

if len(section) == 0 or section == 'uniqueKeys':
if len(self.currentSection) == 0:
print "[ConfigHandler]: No config loaded "
else:
print "[ConfigHandler]: Using " + self.currentSection
return

self.currentConfig = ConfigParser()
self.currentConfig.read(self.currentConfigFile)
try:
for option in self.currentConfig.options(section):
self.current[option] = self.currentConfig.get(section, option)
except NoSectionError:
print "[ConfigHandler]: No such config " + section
return

try:
dict = self.current
dictStr = self.getStrFromDict(dict)
Expand All @@ -134,9 +131,35 @@ def useConf(self, section, startEvent=False):
except NoSectionError:
print '[ConfigHandler]: uniqueKeys section missing'
return
if not startEvent:
self.currentSection = section
print "[ConfigHandler]: Using " + section
self.currentSection = section
print "[ConfigHandler]: Using " + section

def getHashFromConfStr(self, confStr):
"""
Get the hash value of the config,
used by the producer bot
"""

dict = self.getDictFromStr(confStr)
moduleError = self.__checkModule(dict)
if moduleError:
return '', moduleError
dictStr = self.getStrFromDict(dict)
md5 = hashlib.new('md5')
md5.update(dictStr)
return md5.hexdigest(), moduleError

def __checkModule(self, conf):
"""
Check if module is supported, used
on external event
"""

module = conf['module']
from modules import moduleManager
if module in moduleManager.get_modules():
return False
return True

def getStrFromDict(self, dict):
"""
Expand Down
9 changes: 9 additions & 0 deletions src/modules/moduleManager.py
Expand Up @@ -70,6 +70,15 @@ def execute(module, identifier, hash):
print sys.exc_info()
print "[ModuleManager]:", sys.exc_info()[1]

def executeExternal(module, identifier, config, hash):
"""
Call this function when a feeder issues a tracking request
"""

func = modules[module]
regmod = func(config)
moduleCoordinator.ModuleCoordinator().add(regmod, identifier, hash, True)

def handle_modules_onstart():
"""
Remove old pyc files for the modules on start
Expand Down
46 changes: 26 additions & 20 deletions src/utils/moduleCoordinator.py
Expand Up @@ -83,13 +83,14 @@ class EventHolder(object):
Holds an event
"""

def __init__(self, eventType, data):
def __init__(self, eventType, data, hash=''):
"""
Constructor
"""

self.eventType = eventType
self.data = data
self.hash = hash

def getType(self):
"""
Expand All @@ -105,6 +106,14 @@ def getData(self):

return self.data

def getHash(self):
"""
Returns hash of config if event
is a START_EVENT
"""

return self.hash

class Dispatcher(threading.Thread):
"""
Runs the reactor loop outside
Expand Down Expand Up @@ -161,20 +170,17 @@ def run(self):
logHandler.LogHandler().handleLog(ev.getData())
print "From eventMonitor: " + ev.getData()
if ev.getType() == START_EVENT:
config = configHandler.ConfigHandler().getDictFromStr(ev.getData())
configHandler.ConfigHandler().useConf(config, True)
hash = configHandler.ConfigHandler().getCurrentHash()
from modules import moduleManager
moduleManager.execute(config['module'], config['module'] + str(len(self.modules)), hash)
moduleManager.executeExternal(ev.getData()['module'], 'external_' + str(len(self.modules) + 1), ev.getData(), ev.getHash())

def addEvent(self, eventType, data):
def addEvent(self, eventType, data, hash=''):
"""
Add an event to the list
"""

self.events.append(EventHolder(eventType, data))
self.events.append(EventHolder(eventType, data, hash))

def add(self, moduleExe, moduleId, hash):
def add(self, moduleExe, moduleId, hash, external=False):
"""
Add a module to the list and start it,
this method is called both on external events
Expand All @@ -187,19 +193,19 @@ def add(self, moduleExe, moduleId, hash):

monitored = producerBot.ProducerBot().getMonitoredBotnets()
botnet = moduleExe.getConfig()['botnet']
if botnet not in monitored:
if not producerBot.ProducerBot().sendTrackReq(hash):
self.modules[moduleId] = moduleExe
self.configHashes[moduleId] = hash
moduleExe.run()
if self.dispatcherFirstStart:
Dispatcher().start()
self.dispatcherFirstStart = False
else:
if not external:
if botnet in monitored:
print "You are already monitoring this!"
if producerBot.ProducerBot().sendTrackReq(hash):
print "Botnet already monitored!"
else:
print "You are already monitoring this!"


self.modules[moduleId] = moduleExe
self.configHashes[moduleId] = hash
moduleExe.run()
if self.dispatcherFirstStart:
Dispatcher().start()
self.dispatcherFirstStart = False

@synchronized()
def putError(self, exception, module=None):
"""
Expand Down
91 changes: 48 additions & 43 deletions src/xmpp/producerBot.py
Expand Up @@ -18,6 +18,7 @@
#
################################################################################

import urllib2, hashlib
import sleekxmpp, random, time
from threading import Lock
import threading, hashlib
Expand Down Expand Up @@ -70,30 +71,6 @@ def __call__(cls, *args, **kw):
cls.instance = super(Singleton, cls).__call__(*args, **kw)

return cls.instance

class StartTrack(threading.Thread):

def __init__(self, producer):

self.eventlist = list()
self.producer = producer
self.nbrOfBotnets = 0
threading.Thread.__init__(self)

def run(self):

while True:
self.nbrOfBotnets = len(self.producer.getMonitoredBotnets())
time.sleep(self.nbrOfBotnets * 10)
if len(self.eventlist) > 0:
config = self.eventlist.pop()
from utils import moduleCoordinator
eventType = moduleCoordinator.START_EVENT
moduleCoordinator.ModuleCoordinator().addEvent(eventType, config)

def addMessage(self, data):

self.eventlist.append(data)

class ProducerBot(threading.Thread):
"""
Expand All @@ -113,7 +90,6 @@ def __init__(self, xmppConf):
self.currentHash = 0
self.monitoredBotnets = []
self.foundTrack = False
self.startTrackThread = StartTrack(self)
self.password = xmppConf.get("xmpp", "password")
self.server = xmppConf.get("xmpp", "server")
self.jid = xmppConf.get("xmpp", "jid");
Expand All @@ -126,6 +102,11 @@ def __init__(self, xmppConf):
self.xmpp.add_event_handler("session_start", self.handleXMPPConnected)
self.xmpp.add_event_handler("disconnected", self.handleXMPPDisconnected)
self.xmpp.add_event_handler("groupchat_message", self.handleIncomingGroupChatMessage)
self.xmpp.add_event_handler("message", self.handleIncomingMessage)
ip = urllib2.urlopen('http://whatismyip.org').read().strip()
md5 = hashlib.new('md5')
md5.update(ip)
self.id = md5.hexdigest()
threading.Thread.__init__(self)

def disconnectBot(self, reconnect=False):
Expand Down Expand Up @@ -158,7 +139,6 @@ def handleXMPPConnected(self, event):
group room
"""

self.startTrackThread.start()
self.running = True
self.xmpp.sendPresence()
muc = self.xmpp.plugin["xep_0045"]
Expand Down Expand Up @@ -208,24 +188,49 @@ def handleIncomingGroupChatMessage(self, message):
"""

channel = str(message['from'])
coordchan = self.coordchannel.split('@')[0]
if channel.split('@')[0] == coordchan:
body = message['body'].split(' ')
if len(body) == 2 and body[0] == 'trackReq':
botnetStr = body[1]
if channel.split('/')[1] != self.jid.split('@')[0]:
coordchan = self.coordchannel.split('@')[0]
if channel.split('@')[0] == coordchan:
body = message['body'].split(' ')
if len(body) == 2 and body[0] == 'trackReq':
botnetStr = body[1]

if botnetStr in self.monitoredBotnets:
msg = 'trackAck ' + botnetStr
self.xmpp.sendMessage(self.coordchannel, msg, None, "groupchat")

if len(body) == 2 and body[0] == 'trackAck':
botnetStr = body[1].strip()
if botnetStr == self.currentHash:
self.foundTrack = True

if body[0] == 'sensorLoadReq':
msg = 'sensorLoadAck id=' + self.id + ' queue=' + str(len(self.monitoredBotnets))
self.xmpp.sendMessage(self.coordchannel, msg, None, "groupchat")

if botnetStr in self.monitoredBotnets:
msg = 'trackAck ' + botnetStr
self.xmpp.sendMessage(self.coordchannel, msg, None, "groupchat")

if len(body) == 2 and body[0] == 'trackAck':
botnetStr = body[1]
if self.currentHash == botnetStr:
self.foundTrack = True

if body[0] == 'startTrack':
config = ' '.join(body).split('startTrack')[1]
self.startTrackThread.addMessage(config)
def handleIncomingMessage(self, msg):
"""
Takes care of incoming private chat messages
"""

if msg['type'] == 'chat':
body = msg['body'].split(' ')
toStr = msg['from']
if body[0].strip() == 'startTrackReq':
self.recvStartReq = True
config = ' '.join(body).split('startTrackReq')[1]
hash, moduleError = configHandler.ConfigHandler().getHashFromConfStr(config)
if moduleError:
self.xmpp.sendMessage(toStr, 'moduleNotSupported', None, "chat")
return
if hash not in self.monitoredBotnets and not self.sendTrackReq(hash):
self.xmpp.sendMessage(toStr, 'startTrackAck', None, "chat")
from utils import moduleCoordinator
eventType = moduleCoordinator.START_EVENT
config = configHandler.ConfigHandler().getDictFromStr(config)
moduleCoordinator.ModuleCoordinator().addEvent(eventType, config, hash)
else:
self.xmpp.sendMessage(toStr, 'startTrackNack', None, "chat")

def sendLog(self, msg):
"""
Expand Down

0 comments on commit da01996

Please sign in to comment.