Commits

jviide-work  committed 3c0a167

abusehelper.contrib.abusech.*: Converted spyeye bots to use shared helpers. Further refactoring.

  • Participants
  • Parent commits 6ea8670

Comments (0)

Files changed (9)

File abusehelper/contrib/abusech/__init__.py

 from abusehelper.contrib.rssbot.rssbot import RSSBot
 
 
-def is_ip(string):
+def parse_ip(string):
     for addr_type in (socket.AF_INET, socket.AF_INET6):
         try:
-            socket.inet_pton(addr_type, string)
+            return socket.inet_ntop(addr_type, socket.inet_pton(addr_type, string))
         except (ValueError, socket.error):
             pass
-        else:
-            return True
-    return False
+    return None
+
+
+def host_or_ip(host):
+    ip = parse_ip(host)
+    if ip is None:
+        return "host", host
+    else:
+        return "ip", ip
+
+
+def host_or_ip_from_url(url):
+    parsed = urlparse.urlparse(url)
+    return host_or_ip(parsed.netloc)
 
 
 _levels = {
     return tuple(_levels.get(value, []))
 
 
-def host_or_ip_from_url(url):
-    parsed = urlparse.urlparse(url)
-    if is_ip(parsed.netloc):
-        return "ip", parsed.netloc
-    else:
-        return "host", parsed.netloc
+def sanitize_url(url):
+    return re.sub("^http:\/\/", "hxxp://", url)
 
 
 def split_description(description):

File abusehelper/contrib/abusech/abusechbot.py

 from abusehelper.core import events
 from abusehelper.contrib.rssbot.rssbot import RSSBot
 
-from . import is_ip
+from . import parse_ip
 
 
 def parse_title(title):
     for host in query.get("host", []):
         yield "host", host
 
-        if is_ip(host):
+        if parse_ip(host):
             yield "ip", host
 
 

File abusehelper/contrib/abusech/palevoccbot.py

 
 from abusehelper.core import bot
 
-from . import is_ip, split_description, AbuseCHFeedBot
+from . import host_or_ip, split_description, AbuseCHFeedBot
 
 
 class PalevoCcBot(AbuseCHFeedBot):
     def parse_title(self, title):
         pieces = title.split(None, 1)
 
-        host = pieces[0]
-        if is_ip(host):
-            yield "ip", host
-        else:
-            yield "host", host
+        yield host_or_ip(pieces[0])
 
         if len(pieces) > 1:
             yield "source time", pieces[1]

File abusehelper/contrib/abusech/spyeyebinarybot.py

 Maintainer: Lari Huttunen <mit-code@huttu.net>
 """
 
-import re
-import urlparse
-from abusehelper.core import bot, events
-from abusehelper.contrib.rssbot.rssbot import RSSBot
+from abusehelper.core import bot
 
-from . import is_ip
+from . import sanitize_url, host_or_ip_from_url, split_description, AbuseCHFeedBot
 
 
-class SpyEyeBinaryBot(RSSBot):
+class SpyEyeBinaryBot(AbuseCHFeedBot):
+    feed_malware = "SpyEye"
+    feed_type = "malware"
+
     feeds = bot.ListParam(default=["https://spyeyetracker.abuse.ch/monitor.php?rssfeed=binaryurls"])
 
-    def create_event(self, **keys):
-        event = events.Event()
-        # handle link data
-        link = keys.get("link", None)
-        if link:
-            event.add("description url", link)
-        # handle title data
-        br = re.compile('[()]')
-        title = keys.get("title")
-        parts = []
-        parts = title.split()
-        tstamp = parts[1]
-        tstamp = br.sub('', tstamp)
-        event.add("source time", tstamp)
-        # handle description data
-        description = keys.get("description", None)
-        if description:
-            for part in description.split(","):
-                pair = part.split(":", 1)
-                if len(pair) < 2:
-                    continue
-
-                key = pair[0].strip()
-                value = pair[1].strip()
-                if not key or not value:
-                    continue
-                if key == "SpyEye BinaryURL":
-                    proto = re.compile('^http:\/\/')
-                    url = proto.sub('hxxp://', value)
-                    event.add("url", url)
-                    parsed = urlparse.urlparse(value)
-                    host = parsed.netloc
-                    if is_ip(host):
-                        event.add("ip", host)
-                    else:
-                        event.add("host", host)
-                elif key in ["Virustotal", "Status"]:
-                    event.add(key.lower(), value)
-                elif key == "MD5 hash":
-                    event.add("md5", value)
-        event.add("feed", "abuse.ch")
-        event.add("malware", "SpyEye")
-        event.add("type", "malware")
-        return event
+    def parse_description(self, description):
+        for key, value in split_description(description):
+            if key == "spyeye binaryurl":
+                yield "url", sanitize_url(value)
+                yield host_or_ip_from_url(value)
+            elif key in ["virustotal", "status"]:
+                yield key, value
+            elif key == "md5 hash":
+                yield "md5", value
 
 if __name__ == "__main__":
     SpyEyeBinaryBot.from_command_line().execute()

File abusehelper/contrib/abusech/spyeyeccbot.py

 """
 
 import re
-from abusehelper.core import bot, events
-from abusehelper.contrib.rssbot.rssbot import RSSBot
+from abusehelper.core import bot
 
-from . import is_ip, resolve_level
+from . import host_or_ip, split_description, resolve_level, AbuseCHFeedBot
 
 
-class SpyEyeCcBot(RSSBot):
+class SpyEyeCcBot(AbuseCHFeedBot):
+    feed_malware = "SpyEye"
+    feed_type = "c&c"
+
     feeds = bot.ListParam(default=["https://spyeyetracker.abuse.ch/monitor.php?rssfeed=tracker"])
     # If treat_as_dns_source is set, the feed ip is dropped.
     treat_as_dns_source = bot.BoolParam()
 
-    def create_event(self, **keys):
-        event = events.Event()
-        # handle link data
-        link = keys.get("link", None)
-        if link:
-            event.add("description url", link)
-        # handle title data
-        title = keys.get("title", None)
-        if title:
-            t = []
-            t = title.split()
-            host = t[0]
-            date = " ".join(t[1:])
-            if is_ip(host):
-                event.add("ip", host)
-            else:
-                event.add("host", host)
-            br = re.compile('[()]')
-            date = br.sub('', date)
-            date = date + " UTC"
-            event.add("source time", date)
-        # handle description data
-        description = keys.get("description", None)
-        if description:
-            for part in description.split(","):
-                pair = part.split(":", 1)
-                if len(pair) < 2:
-                    continue
-                key = pair[0].strip()
-                value = pair[1].strip()
-                if not key or not value:
-                    continue
-                if key == "Status":
-                    event.add(key.lower(), value)
-                elif key == "Level":
-                    event.update("description", resolve_level(value))
-                elif key == "SBL" and value != "Not listed":
-                    key = key.lower() + " id"
-                    event.add(key, value)
-                elif key == "IP address":
-                    if not self.treat_as_dns_source:
-                        event.add("ip", value)
-        event.add("feed", "abuse.ch")
-        event.add("malware", "SpyEye")
-        event.add("type", "c&c")
-        return event
+    def parse_title(self, title):
+        pieces = title.split(None, 1)
+
+        yield host_or_ip(pieces[0])
+
+        if len(pieces) > 1:
+            date = pieces[1]
+            date = re.sub("[()]", "", date)
+            yield "source time", date + " UTC"
+
+    def parse_description(self, description):
+        for key, value in split_description(description):
+            if key == "status":
+                yield key, value
+            elif key == "level":
+                yield "description", resolve_level(value)
+            elif key == "sbl" and value.lower() != "not listed":
+                yield key + " id", value
+            elif key == "ip address" and not self.treat_as_dns_source:
+                yield "ip", value
 
 if __name__ == "__main__":
     SpyEyeCcBot.from_command_line().execute()

File abusehelper/contrib/abusech/spyeyeconfigbot.py

 Maintainer: Lari Huttunen <mit-code@huttu.net>
 """
 
-import re
-import urlparse
-from abusehelper.core import bot, events
-from abusehelper.contrib.rssbot.rssbot import RSSBot
+from abusehelper.core import bot
 
-from . import is_ip
+from . import host_or_ip_from_url, split_description, AbuseCHFeedBot
 
 
-class SpyEyeConfigBot(RSSBot):
+class SpyEyeConfigBot(AbuseCHFeedBot):
+    feed_malware = "SpyEye"
+    feed_type = "malware configuration"
+
     feeds = bot.ListParam(default=["https://spyeyetracker.abuse.ch/monitor.php?rssfeed=configurls"])
 
-    def create_event(self, **keys):
-        event = events.Event()
-        # handle link data
-        link = keys.get("link", None)
-        if link:
-            event.add("description url", link)
-        # handle title data
-        br = re.compile('[()]')
-        title = keys.get("title")
-        parts = []
-        parts = title.split()
-        tstamp = parts[1]
-        tstamp = br.sub('', tstamp)
-        event.add("source time", tstamp)
-        # handle description data
-        description = keys.get("description", None)
-        if description:
-            for part in description.split(","):
-                pair = part.split(":", 1)
-                if len(pair) < 2:
-                    continue
-                key = pair[0].strip()
-                value = pair[1].strip()
-                if not key or not value:
-                    continue
-                if key == "Status":
-                    event.add(key.lower(), value)
-                elif key == "SpyEye ConfigURL":
-                    event.add("url", value)
-                    parsed = urlparse.urlparse(value)
-                    host = parsed.netloc
-                    if is_ip(host):
-                        event.add("ip", host)
-                    else:
-                        event.add("host", host)
-                elif key == "MD5 hash":
-                    event.add("md5", value)
-        event.add("feed", "abuse.ch")
-        event.add("malware", "SpyEye")
-        event.add("type", "malware configuration")
-        return event
+    def parse_description(self, description):
+        for key, value in split_description(description):
+            if key == "status":
+                yield key, value
+            if key == "spyeye configurl":
+                yield "url", value
+                yield host_or_ip_from_url(value)
+            elif key == "md5 hash":
+                yield "md5", value
 
 if __name__ == "__main__":
     SpyEyeConfigBot.from_command_line().execute()

File abusehelper/contrib/abusech/spyeyedropzonebot.py

 Maintainer: Lari Huttunen <mit-code@huttu.net>
 """
 
-import re
-import urlparse
-from abusehelper.core import bot, events
-from abusehelper.contrib.rssbot.rssbot import RSSBot
+from abusehelper.core import bot
 
-from . import is_ip
+from . import host_or_ip_from_url, split_description, AbuseCHFeedBot
 
 
-class ZeusDropzoneBot(RSSBot):
+class ZeusDropzoneBot(AbuseCHFeedBot):
+    feed_malware = "SpyEye"
+    feed_type = "dropzone"
+
     feeds = bot.ListParam(default=["https://spyeyetracker.abuse.ch/monitor.php?rssfeed=dropurls"])
 
-    def create_event(self, **keys):
-        event = events.Event()
-        # handle link data
-        link = keys.get("link", None)
-        if link:
-            event.add("description url", link)
-        # handle title data
-        br = re.compile('[()]')
-        title = keys.get("title")
-        parts = []
-        parts = title.split()
-        tstamp = parts[1]
-        tstamp = br.sub('', tstamp)
-        event.add("source time", tstamp)
-        # handle description data
-        description = keys.get("description", None)
-        if description:
-            for part in description.split(","):
-                pair = part.split(":", 1)
-                if len(pair) < 2:
-                    continue
-                key = pair[0].strip()
-                value = pair[1].strip()
-                if not key or not value:
-                    continue
-                if key == "Status":
-                    event.add(key.lower(), value)
-                elif key == "SpyEye DropURL":
-                    event.add("url", value)
-                    parsed = urlparse.urlparse(value)
-                    host = parsed.netloc
-                    if is_ip(host):
-                        event.add("ip", host)
-                    else:
-                        event.add("host", host)
-        event.add("feed", "abuse.ch")
-        event.add("malware", "SpyEye")
-        event.add("type", "dropzone")
-        return event
+    def parse_description(self, description):
+        for key, value in split_description(description):
+            if key == "status":
+                yield key, value
+            if key == "spyeye dropurl":
+                yield "url", value
+                yield host_or_ip_from_url(value)
 
 if __name__ == "__main__":
     ZeusDropzoneBot.from_command_line().execute()

File abusehelper/contrib/abusech/zeusbinarybot.py

 Maintainer: Lari Huttunen <mit-code@huttu.net>
 """
 
-import re
 from abusehelper.core import bot
 
-from . import host_or_ip_from_url, split_description, AbuseCHFeedBot
+from . import sanitize_url, host_or_ip_from_url, split_description, AbuseCHFeedBot
 
 
 class ZeusBinaryBot(AbuseCHFeedBot):
     def parse_description(self, description):
         for key, value in split_description(description):
             if key == "url":
-                url = re.sub("^http:\/\/", "hxxp://", value)
-                yield "url", url
-                yield host_or_ip_from_url(url)
+                yield "url", sanitize_url(value)
+                yield host_or_ip_from_url(value)
             if key in ["virustotal", "status"]:
                 yield key, value
             if key == "md5 hash":

File abusehelper/contrib/abusech/zeusccbot.py

 import re
 from abusehelper.core import bot
 
-from . import is_ip, resolve_level, split_description, AbuseCHFeedBot
+from . import host_or_ip, resolve_level, split_description, AbuseCHFeedBot
 
 
 class ZeusCcBot(AbuseCHFeedBot):
     def parse_title(self, title):
         pieces = title.split(None, 1)
 
-        host = pieces[0]
-        if is_ip(host):
-            yield "ip", host
-        else:
-            yield "host", host
+        yield host_or_ip(pieces[0])
 
         if len(pieces) > 1:
             date = pieces[1]