
बॉटनेट कमांड एवं नियंत्रण मॉनिटर
Hale एक बॉटनेट कमांड एवं कंट्रोल मॉनिटर/जासूस है, जिसमें मॉड्यूलर डिज़ाइन है ताकि C&C सर्वरों द्वारा उपयोग किए जाने वाले नए प्रोटोकॉल की निगरानी करने वाले नए मॉड्यूल आसानी से विकसित किए जा सकें। Hale के साथ Twisted का उपयोग करके विकसित IRC और HTTP मॉनिटर आते हैं, जो बड़ी संख्या में कनेक्शनों की स्केलेबिलिटी को संभालते हैं। इन मॉड्यूलों में कॉन्फ़िगर करने योग्य प्रोटोकॉल व्याकरण (grammar) और बॉट सेटिंग्स होती हैं, लेकिन इन्हें आपकी आवश्यकताओं के अनुसार भी संशोधित किया जा सकता है। सभी कैप्चर किए गए लॉग और फ़ाइलें डेटाबेस में सहेजी जाती हैं, और IRC के मामले में, ट्रैक किए गए IP नंबर भी सहेजे जाते हैं।
ऑपरेटर का स्थान छिपाने के लिए, कनेक्शन SOCKSv5 प्रॉक्सी के माध्यम से किए जा सकते हैं, और यह वेब इंटरफ़ेस के माध्यम से कॉन्फ़िगर करने योग्य है, जहाँ सभी लॉग सांख्यिकीय चार्ट और टाइमलाइन के साथ ब्राउज़ करने के लिए उपलब्ध हैं। इंटरफ़ेस को Django और Google Visualization API के साथ विकसित किया गया था। वेब UI में कुछ अतिरिक्त सुविधाओं में OAuth समर्थन के साथ RESTful API और एक खोज इंजन का समर्थन शामिल है।
Hale का मुख्य विचार सेंसरों (Hale मॉनिटर) का एक नेटवर्क बनाकर बॉटनेट शिकार और शोध में सहयोग करने में मदद करना है। इस विचार को बेहतर बनाने के लिए, एक केंद्रीकृत XMPP सर्वर से जुड़ने के लिए एक XMPP बॉट उपलब्ध है, जहाँ वर्तमान में सेंसरों के बीच समन्वय के लिए दो अलग-अलग ग्रुपरूम और लॉग एवं फ़ाइलें साझा करने के लिए एक कक्ष का उपयोग किया जाता है। समन्वय कक्ष बॉटनेट हैश का उपयोग करता है, जो बॉटनेट सेटिंग्स में अद्वितीय कुंजियों से बनाए जाते हैं; इस प्रकार, समान हैश (पहचान) वाले दो बॉटनेटों को एक साथ मॉनिटर नहीं करना पड़ता और उपयोग में सुधार होता है। तीसरे पक्षों को इस नेटवर्क का उपयोग करने में मदद करने के लिए, एक बॉट समन्वय कक्ष में शामिल हो सकता है और किसी सेंसर से किसी बॉटनेट को ट्रैक करना शुरू करने के लिए कह सकता है, यदि वह ट्रैक नहीं किया गया है, तो उसके लिए कॉन्फ़िगरेशन भेजकर। इसके अतिरिक्त, शेयर कक्ष में, तीसरे पक्ष के बॉट वास्तविक समय में सेंसरों द्वारा कैप्चर किए गए लॉग और फ़ाइलें प्राप्त कर सकते हैं। लॉग इतिहास में सहायता के लिए वेब API का उपयोग किया जा सकता है, जो GET अनुरोधों का समर्थन करता है।
Hale की निम्नलिखित निर्भरताएँ हैं:
Python == 2.6
Django == 1.2.1
Twisted == 10.1.0
GeoIP-Python == 1.2.4 (and GeoIP C lib)
Whoosh == 0.3.18
django-haystack == 1.0.1-final
django-piston == 0.2.3rc1
pefile == 1.2.10-63
sleekxmpp == 0.9Rrc1
wsgiref == 0.1.2
zope.interface == 3.6.1
oauth2 == 1.2.0
httplib2 == 0.6.0
इसके अतिरिक्त मॉनिटर को django द्वारा उपयोग किए जाने वाले डेटाबेस के अनुरूप एक डेटाबेस बैकएंड ड्राइवर की आवश्यकता होती है। जब ये लाइब्रेरीज़ स्थापित हो जाएँ, तो यहाँ से स्रोत डाउनलोड करें और इसे कहीं भी निकालें।
पहले एक डेटाबेस बनाएँ जिसका उपयोग Hale द्वारा किया जाएगा; डेटाबेस इंजन आपकी पसंद का कोई भी हो सकता है। यदि आप किसी मौजूदा डेटाबेस का उपयोग कर रहे हैं तो इस चरण को छोड़ दें।
अगला चरण सर्वर इंजन द्वारा उपयोग किए गए ड्राइवर के अनुरूप python डेटाबेस बैकएंड ड्राइवर स्थापित करना है।
hale/src/webdb/ में settings.py को संपादित करें और निम्नलिखित कॉन्फ़िगरेशन संपादित करें: ENGINE, NAME, USER, PASSWORD, HOST और PORT, जहाँ इंजन सेटिंग उदाहरण के लिए django.db.backends.mysql है, यदि आपका सर्वर इंजन MySQL है। NAME सेटिंग आपके डेटाबेस का नाम है, जिसका उपयोग इसे बनाते समय किया गया था।
यदि आप अपना स्वयं का वेब UI शुरू नहीं करना चाहते हैं, तो इस चरण को छोड़ें और 8) पर जाएँ। settings.py में, PATH_TO_APP को Django एप्लिकेशन के पूर्ण पथ की ओर इंगित करने के लिए बदलें, उदाहरण के लिए: '/home/..../Hale/src/webdb'। webdb निर्देशिका में निम्नलिखित कमांड चलाएँ: python manage.py syncdb। यदि आपको यहाँ कोई त्रुटि मिलती है, तो संभवतः settings.py में डेटाबेस सेटिंग्स गलत हैं। साथ ही, सिंक के दौरान सुपरयूज़र सेट करें, जिसका उपयोग उपयोगकर्ताओं को प्रशासित करते समय किया जाएगा।
वेब इंटरफ़ेस में खोज का समर्थन करने के लिए, खोज इंजन को पहली बार इंडेक्स करने देने हेतु python manage.py rebuild_index चलाएँ। यह नामक एक निर्देशिका बनाएगा; वेब सर्वर को यहाँ लिखने देने के लिए, जारी करें। इसके बाद आप इसके बजाय चलाएँ और इसे अपनी पसंद के नियमित अंतराल पर इंडेक्स अपडेट करने हेतु एक cron job के रूप में रखें।
Alias /media /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media/
<Location /media>
Order allow,deny
Allow from all
</Location>
WSGIDaemonProcess username processes=2 maximum-requests=500 threads=10
WSGIProcessGroup group
WSGIScriptAlias / /home/..../webdb/django.wsgi
और उस username और group को संपादित करें जिसके रूप में WSGI डेमॉन को चलना चाहिए। WSGIScriptAlias को webdb निर्देशिका में स्थित django.wsgi फ़ाइल के पूर्ण पथ पर सेट किया जाना चाहिए। ऊपर निर्दिष्ट Alias प्रशासन पृष्ठ को सही ढंग से प्रस्तुत करने के लिए आवश्यक है। वेब इंटरफ़ेस के माध्यम से मॉड्यूल अपलोड करने में सक्षम होने के लिए, chmod o+w webdb/modules जारी करें।
hale/src/modules/ से उपयोग किए जाने वाले मॉड्यूल अपलोड करें या अपना स्वयं का लिखें (विकास अनुभाग देखें)। एडमिन इंटरफ़ेस में वांछित मॉड्यूल अपलोड करें और उदाहरण के लिए मॉड्यूल का नाम irc और फ़ाइल नाम ircModule.py संपादित करें। hale/conf/modules.conf में स्थित संबंधित अनुभाग में मॉड्यूल के लिए कॉन्फ़िगरेशन नियम निर्दिष्ट करें और उसे टेक्स्टबॉक्स में रखें; साथ ही अपलोड किए जा रहे मॉड्यूल के लिए uniqueKeys अनुभाग भी जोड़ें।
मॉनिटर चलाने से पहले, यदि आप XMPP सर्वर का उपयोग करना चाहते हैं, तो hale/src/conf/ में hale.conf संपादित करें। XMPP बॉट सक्रिय करने के लिए use सेटिंग को True पर सेट करें, और या तो लॉगिन जानकारी को किसी मौजूदा खाते और सर्वर के लिए संपादित करें या अपना स्वयं का XMPP सर्वर शुरू करें। XMPP सर्वर शुरू करते समय एक महत्वपूर्ण कदम अधिकतम स्टैंज़ा आकार को डिफ़ॉल्ट मान से बढ़ाकर लगभग 10Mb करना है; अन्यथा मैलवेयर विज्ञापन संभव नहीं होगा। hale.conf में channel सेटिंग्स का उपयोग बॉट द्वारा उपयोग किए जाने वाले शेयर ग्रुपरूम के लिए किया जाता है, और coord सेटिंग का उपयोग उस ग्रुपरूम के लिए किया जाता है जहाँ सेंसरों के बीच सभी समन्वय होता है।
hale.conf संपादित करें और क्लाइंट एवं सर्वर सेटिंग्स सेट करें।
मॉनिटर शुरू करने के लिए hale/src/ पर जाएँ और python server.py चलाएँ। यदि यह त्रुटियों के साथ शुरू होता है, तो django settings.py फ़ाइल सही ढंग से सेट नहीं है या कुछ लाइब्रेरीज़ गायब हैं। क्लाइंट के साथ सर्वर को कमांड जारी करना संभव है, लेकिन इसके लिए उपयोगकर्ता को सर्वर के विरुद्ध स्वयं को प्रमाणित करना आवश्यक है; उन उपयोगकर्ताओं को पहुँच प्रदान की जाती है, जिन्हें वेब इंटरफ़ेस के माध्यम से स्टाफ सदस्यों के रूप में सेट किया गया है। जब क्लाइंट चल रहा हो, तो उपलब्ध कमांड पाने के लिए help या ? टाइप करें। किसी विशिष्ट कमांड के बारे में अधिक जानकारी पाने के लिए help कमांड टाइप करें। मॉनिटर बॉट शुरू करना पहले hale/src/conf/modules.conf फ़ाइल को संपादित करके किया जाता है, उदाहरण के लिए निम्नानुसार एक IRC कॉन्फ़िगरेशन का उपयोग करके:
[uniqueKeys]
irc = botnet, *grammar
[ircConf]
module = irc
botnet = irc.freenode.net
port = 6667
password = None
nick = nickname
username = agent007
realname = Spying
channel = #channelname
channel_pass = somepass
pass_grammar = PASS
nick_grammar = NICK
user_grammar = USER
join_grammar = JOIN
version_grammar = VERSION
time_grammar = TIME
privmsg_grammar = PRIVMSG
topic_grammar = TOPIC
currenttopic_grammar = 332
ping_grammar = PING
pong_grammar = PONG
एक नया विशिष्ट रूप से नामित अनुभाग ([ircConf] भाग) निर्दिष्ट करके एक नया कॉन्फ़िग संपादित या बनाएँ। कॉन्फ़िग फ़ाइल के शीर्ष पर uniqueKeys नामक एक अनुभाग है, जहाँ मॉड्यूल के लिए सभी अद्वितीय फ़ील्ड निर्दिष्ट हैं और बॉटनेट हैश उत्पन्न करने के लिए उपयोग किए जाते हैं; सही बॉटनेट ट्रैकिंग बनाए रखने के लिए इसे आमतौर पर नहीं बदला जाना चाहिए। जब यह हो जाए, तो कॉन्फ़िगरेशन लोड करने के लिए useconf section चलाएँ, और फिर बॉट को exec modulename id के साथ शुरू करें, जहाँ id बॉटनेट की पहचान करने के लिए आपके द्वारा सेट की जाती है।
वेब इंटरफ़ेस डेटाबेस में सभी कैप्चर किए गए डेटा तक पहुँच प्रदान करता है, जो इंडेक्स पृष्ठ से सुलभ है। एक खोज फ़ंक्शन भी है, जो उपयोगकर्ता को बॉटनेट और फ़ाइल हैश, संबंधित IP नंबर, बॉटनेट ID, उपयोग किए गए बॉटनेट मॉड्यूल और बॉटनेट होस्ट खोजने में सक्षम बनाता है। यदि उपयोगकर्ता के पास प्रॉक्सी या मॉड्यूल संपादित करने की पहुँच है, तो यह एडमिन अनुभाग में किया जा सकता है; इसका URL http://.../admin है। व्यवस्थापक उपयोगकर्ता मोड सेट कर सकता है और वेब API के लिए उपभोक्ता (consumers) भी जोड़ सकता है।
मॉड्यूल कार्यान्वित करें, उदाहरण के लिए:
import moduleManager from utils import moduleInterface
@moduleManager.register("irc") def module_setup(config, hash): """ Function to register modules, simply implement this to pass along the config and hash to the module object and return the it back. """
return IRC(config, hash)
class IRC(moduleInterface.Module):
def __init__(self, config, hash):
self.config = config
self.hash = hash
# must be implemented
def stop(self):
# stop execution
# must be implemented
def run(self):
# start execution
# must be implemented
def getConfig(self):
return self.config
रजिस्टर फ़ंक्शन (इस मामले में module_setup) के लिए डेकोरेटर जोड़ें, जिसे तर्क के रूप में वर्तमान कॉन्फ़िगरेशन और अद्वितीय कुंजियों से बने कॉन्फ़िग हैश के साथ कॉल किया जाएगा। इस फ़ंक्शन का कोई भी नाम हो सकता है। कॉन्फ़िगरेशन को मॉड्यूल ऑब्जेक्ट को भेजें; configHandler KeyErrors को पकड़ता है, इसलिए यदि इस फ़ंक्शन को गलत कॉन्फ़िगरेशन भेजे जाते हैं, तो configHandler आपको इसके बारे में सूचित करेगा।
नामकरण परंपरा nameModule.py और @moduleManager.register("name") का पालन करें और moduleManager को आयात करें; यदि नहीं, तो moduleManager आपको किसी भी त्रुटि के बारे में सूचित करेगा।
शेष मॉड्यूल कोड यहाँ छोड़ दिया गया है, लेकिन उसे एक twisted फ़ैक्टरी ऑब्जेक्ट बनाना चाहिए और इसे run विधि में रिएक्टर के साथ शुरू करना चाहिए; उदाहरण के लिए मौजूदा मॉड्यूल देखें। Twisted के साथ प्रोग्रामिंग के ट्यूटोरियल के लिए, कृपया यहाँ देखें। मॉड्यूल विकसित करते समय उपयोग करने के लिए कुछ उपयोगिताएँ (utils) भी हैं; यह निम्नानुसार किया जाता है:
Socksify:
# import all utils
from utils import *
# in the constructor create a new proxy object
self.prox = proxySelector.ProxySelector()
# in the run method add the following after having created the factory method.
proxyInfo = self.prox.getRandomProxy()
if proxyInfo == None:
self.connector = reactor.connectTCP(host, port, factory)
else:
proxyHost = proxyInfo['HOST']
proxyPort = proxyInfo['PORT']
proxyUser = proxyInfo['USER']
proxyPass = proxyInfo['PASS']
socksify = socks5.ProxyClientCreator(reactor, factory)
if len(proxyUser) == 0:
self.connector = socksify.connectSocks5Proxy(host, port, proxyHost, proxyPort, "HALE")
else:
self.connector = socksify.connectSocks5Proxy(host, port, proxyHost, proxyPort, "HALE", proxyUser, proxyPass)
फ़ैक्टरी ऑब्जेक्ट में कनेक्शन त्रुटि प्रबंधन:
def clientConnectionFailed(self, connector, reason):
"""
Called on failed connection to server
"""
moduleCoordinator.ModuleCoordinator().putError("Error connecting to " + self.config['botnet'], self.module)
def clientConnectionLost(self, connector, reason):
"""
Called on lost connection to server
"""
moduleCoordinator.ModuleCoordinator().putError("Connection lost to " + self.config['botnet'], self.module)
यह त्रुटियों को एरर बकेट (error bucket) में भेजेगा, जो CLI में showlog जारी करके सुलभ है।
लॉगिंग:
# in the factory create the following method to handle logs (note that the hash and config must be sent to the factory)
# and call it in the protocol class with: self.factory.putLog(data)
def putLog(self, log):
"""
Put log to the event handler
"""
moduleCoordinator.ModuleCoordinator().addEvent(moduleCoordinator.LOG_EVENT, log, self.hash, self.config)
# apply reg expression to look for URLs containing possible malware
# and call it in the protocol class with: self.factory.checkForURL(data)
def checkForURL(self, data):
"""
Check for URL in the event handler
"""
moduleCoordinator.ModuleCoordinator().addEvent(moduleCoordinator.URL_EVENT, data, self.hash)
# if you module should detect IP numbers of other bots and herders implement the following method in the factory
def addRelIP(self, data):
"""
Put possible ip related to the botnet being monitored
in the event handler.
"""
moduleCoordinator.ModuleCoordinator().addEvent(moduleCoordinator.RELIP_EVENT, data, self.hash)
संबंधित IP का प्रबंधन उस प्रोटोकॉल के लिए उपयोग किए जाने वाले एक रेगुलर एक्सप्रेशन को लागू करके किया जाता है, जिसे मॉड्यूल समर्थन करने जा रहा है; irc मॉड्यूल के मामले में, कोड इस प्रकार दिखता है:
checkHost = data.split(':')[1].split(' ')[0].strip()
match = self.factory.expr.findall(checkHost)
if match:
self.factory.addRelIP(data.split('@')[1].split(' ')[0].strip())
जहाँ रेगुलर एक्सप्रेशन निम्नानुसार है:
self.expr = re.compile('!~.*?@')
2) फ़ाइल को modules निर्देशिका में खींचें। moduleManager फिर स्वचालित रूप से इसे आयात करेगा और त्रुटियों की जाँच करेगा।
modules.conf में कॉन्फ़िगरेशन संपादित करें
मॉड्यूल का नाम उदाहरण के लिए irc, फ़ाइल नाम ircModule.py सेट करके मॉड्यूल को वेब UI पर अपलोड करें, और फिर इस मॉड्यूल के लिए एक कॉन्फ़िग उदाहरण जोड़ें।
किसी बॉटनेट को ट्रैक करने के लिए अनुरोध भेजते समय, अनुरोध ग्रुपचैट समन्वय कक्ष में निम्नानुसार किया जाता है:
sensorLoadReq
जहाँ सभी सेंसर अपनी id और कतार लंबाई (मॉनिटर किए गए बॉटनेटों की संख्या) के साथ उत्तर देते हैं:
sensorLoadAck id=353f6650859547ed06597dbfa1dcfd88 queue=0
फीडर फिर इस जानकारी के आधार पर एक सेंसर चुनता है, जैसे सबसे कम कतार लंबाई; और यदि कई सेंसरों के लिए ये बराबर हैं, तो वर्णानुक्रम में क्रमबद्ध सेंसर id जिसका मान सबसे कम है, चुना जाता है।
जब फीडर ने एक सेंसर चुन लिया होता है, तो वह सेंसर को एक निजी चैट संदेश भेजता है:
startTrackReq config
जहाँ config कॉन्फ़िगरेशन का एक स्ट्रिंग प्रतिनिधित्व है, उदाहरण के लिए:
module=irc botnet=irc.freenode.net etc..
सेंसर फिर कॉन्फ़िग हैश के साथ एक स्वीकृति (acknowledgement) के साथ उत्तर देता है, जिसका उपयोग बॉटनेट लॉग को शेयर चैनल में अन्य लॉग से अलग करने के लिए किया जा सकता है। स्वीकृति का उदाहरण:
startTrackAck hash
यदि कोई और इस बॉटनेट की निगरानी नहीं कर रहा है; अन्यथा एक startTrackNack प्राप्त होता है, यदि बॉटनेट पहले से मॉनिटर किया जा रहा है या सेंसर के पास इस बॉटनेट के लिए मॉड्यूल स्थापित नहीं है। मैलवेयर साझाकरण सेंसरों द्वारा निम्न जैसा संदेश भेजकर किया जाता है:
fileCaptured hash=353f6650... file content
जहाँ सामग्री Base64 एन्कोडेड है और फ़ाइल हैश मान के ठीक बाद आती है।
API तक पहुँच प्राप्त करने के लिए आपको एक consumer key और secret key की आवश्यकता होती है; इन्हें एडमिन द्वारा बनाया जा सकता है और प्रमाणित करने के लिए OAuth के साथ उपयोग किया जाता है। JSON प्रारूप में डेटा प्राप्त करने के लिए निम्नलिखित URL उपलब्ध हैं:
http://.../api/botnet सभी मॉनिटर किए गए बॉटनेटों के साथ उत्तर देगा
http://.../api/botnet/botnethash botnethash के बराबर हैश वाले बॉटनेट के साथ उत्तर देगा
http://.../api/host/hostname hostname के बराबर होस्ट वाले सभी मॉनिटर किए गए बॉटनेटों के साथ उत्तर देगा
http://.../api/type/module उस मॉड्यूल के साथ मॉनिटर किए गए सभी बॉटनेटों के साथ उत्तर देगा
http://.../api/botips/hash hash मान वाले बॉटनेट द्वारा कैप्चर किए गए सभी IP के साथ उत्तर देगा
http://.../api/bologs/hash hash मान वाले बॉटनेट के लिए सभी लॉग के साथ उत्तर देगा
http://.../api/bofiles/hash hash मान वाले बॉटनेट द्वारा कैप्चर की गई फ़ाइल हैश के साथ उत्तर देगा
http://.../api/file/hash उन बॉटनेटों की जानकारी लौटाता है, जिन्होंने निर्दिष्ट हैश वाली फ़ाइल कैप्चर की है
http://.../api/ip/addr उन बॉटनेटों की जानकारी के साथ उत्तर देगा, जिन्होंने addr नंबर वाला IP का पता लगाया है
ध्यान दें कि वर्तमान में केवल GET अनुरोध संभव हैं।
whoosh.index/chmod o+w whoosh.index/python manage.py update_indexpython manage.py runserver चलाएँ और यह जाँचने के लिए http://127.0.0.1:8000 पर जाएँ कि सेटअप सही ढंग से किया गया था या नहीं।
runserver कमांड एक डेवलपमेंट सर्वर तैनात करता है, जो प्रदर्शन समस्याओं के कारण प्रोडक्शन उपयोग के लिए अनुशंसित नहीं है। इसके बजाय Apache के लिए mod_wsgi स्थापित करके वेब UI तैनात करें; यह मानते हुए कि आप Ubuntu चला रहे हैं, apt-get install libapache2-mod-wsgi चलाएँ। /etc/apache2/sites-available/default में निम्नलिखित जोड़ें: