@@ -0,0 +1,1634 @@
+import csv%0Aimport logging%0Afrom datetime import datetime, timedelta%0A%0Afrom dateutil import parser%0Afrom core.feed import Feed%0Afrom core.observables import Url%0Afrom core.errors import ObservableValidationError%0A%0A%0Aclass MalwareCorpusTracker(Feed):%0A%0A    default_values = %7B%0A        %22frequency%22: timedelta(hours=1),%0A        %22name%22: %22MalwareCorpusTracker%22,%0A        %22source%22: %22http://tracker.h3x.eu/api/sites_1day.php%22,%0A        %22description%22: %22This feed contains known Malware C2 servers%22,%0A    %7D%0A%0A    def update(self):%0A%0A        resp = self._make_request()%0A        reader = csv.reader(resp.content.splitlines(), quotechar='%22')%0A        for line in reader:%0A            if line%5B0%5D.startswith('#'):%0A                continue%0A%0A            first_seen = parser.parse(line%5B4%5D)%0A%0A            if self.last_run is not None:%0A                if self.last_run %3E first_seen.replace(tzinfo=None):%0A                    continue%0A%0A            self.analyze(line, first_seen)%0A%0A    # pylint: disable=arguments-differ%0A    def analyze(self, line, first_seen):%0A%0A        # split the entry into observables%0A        # pylint: disable=line-too-long%0A        family, type_, url, _, _, _, _, last_seen = line%0A%0A        context = %7B%7D%0A        context%5B'date_added'%5D = first_seen%0A        context%5B'last_seen'%5D = last_seen%0A        context%5B'source'%5D = self.name%0A%0A        tags = %5B%5D%0A        tags.append(family.lower())%0A        tags.append(type_.lower())%0A%0A        try:%0A            url = Url.get_or_create(value=url)%0A            url.add_context(context)%0A            url.add_source(self.name)%0A            url.tag(tags)%0A        except ObservableValidationError as e:%0A            logging.error(e)%0A

Create h3x_feeds.py (#469)