From 05205fa773802d07603c2db024e39f0851490348 Mon Sep 17 00:00:00 2001 From: thecybermafia Date: Fri, 28 Sep 2018 15:32:15 +0530 Subject: [PATCH] Create generate-report.py Create PDF reports of weekly attack statistics with MHN REST API that contains data visualisation and other detailed information. --- scripts/generate-report.py | 161 +++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 scripts/generate-report.py diff --git a/scripts/generate-report.py b/scripts/generate-report.py new file mode 100644 index 00000000..6b7049db --- /dev/null +++ b/scripts/generate-report.py @@ -0,0 +1,161 @@ +from __future__ import unicode_literals +import json +import requests +import logging +import time +import datetime +import dateutil.parser +import matplotlib.pyplot as plt +import numpy as np +from io import open +from string import Template +from jinja2 import Environment, FileSystemLoader +from weasyprint import HTML +from PIL import Image + +api_token = "your_api_token_goes_here" +server_url = "server_ip_or_name" +api_url_base = 'https://github.com/threatstream/mhn/wiki/MHN-REST-APIs' +headers = {'Content-Type': 'application/json', + 'Authorization': 'Bearer {0}'.format(api_token)} +html_string = " " + + +def http_response_check(responseCode,api_url): + + if responseCode >= 500: + logging.error ('{0} - [!] [{1}] Server Error: [{2}]'.format(datetime.datetime.now(),responseCode,api_url)) + elif responseCode == 404: + logging.error ('{0} - [!] [{1}] URL not found: [{2}]'.format(datetime.datetime.now(),responseCode,api_url)) + elif responseCode == 401: + logging.error ('{0} - [!] [{1}] Authentication Failed: [{2}]'.format(datetime.datetime.now(),responseCode,api_url)) + elif responseCode == 400: + logging.error ('{0} - [!] [{1}] Bad Request: [{2}]'.format(datetime.datetime.now(),responseCode,api_url)) + elif responseCode >= 300: + logging.error ('{0} - [!] [{1}] Unexpected Redirect: [{2}]'.format(datetime.datetime.now(),responseCode,api_url)) + elif responseCode == 200: + logging.debug('{0} - Data retrived successfully: [{1}]'.format(datetime.datetime.now(),api_url)) + return 200 + else: + logging.error ('{0} - [?] Unexpected Error: [HTTP {1}]: URL: {2}'.format(datetime.datetime.now(),responseCode,api_url)) + return None + +def get_top_attackers(): + + global html_string + api_url = 'http://{0}/api/top_attackers/?api_key={1}&hours_ago=168'.format(server_url,api_token) + response = requests.get(api_url, headers=headers) + http_code = http_response_check(response.status_code,api_url) + if http_code == 200: + top_attackers = json.loads(response.content.decode('utf-8')) + source = [] + honeypot_raw_data = [] + count = [] + html_string = '

Attacker metadata

' + html_string += "
    " + for key, details in enumerate(top_attackers['data']): + for k, v in details.items(): + if (k == "count"): + count.append(v) + elif (k == "honeypot"): + honeypot_raw_data.append(v.encode('utf-8')) + elif (k == "source_ip"): + source.append(v.encode('utf-8')) + html_string += "

    " + html_string += "
  1. {0}
  2. ".format(v.encode('utf-8')) + get_attacker_metdata(v.encode('utf-8')) + get_attacker_stats(v.encode('utf-8')) + html_string += "
" + figure1 = generate_plot(count,source,"Attacks","Attacker Statistics") + figure1.savefig('top-attackers-ip.png') + i = iter(honeypot_raw_data) + j = iter(count) + k = list(zip(i, j)) + d = {} + for (x,y) in k: + if x in d: + d[x] = d[x] + y + else: + d[x] = y + honeypot_data = d.keys() + honeypot_count = d.values() + figure2 = generate_plot(honeypot_count,honeypot_data,'Attacks','Sensor Statistics') + figure2.savefig('top-attackers-honeypot.png') + else: + return None + +def generate_plot(datameasure,datasource,xlabel,title): + + figure, ax = plt.subplots() + y_pos = np.arange(len(datameasure)) + ax.barh(y_pos, datameasure, align='center') + ax.set_yticks(y_pos) + ax.set_yticklabels(datasource,fontsize=7,rotation=30) + ax.set_xlabel(xlabel) + ax.set_title(title) + return figure + +def get_attacker_metdata(source_ip): + + global html_string + api_url = 'http://{0}/api/metadata/?api_key={1}&ip={2}'.format(server_url,api_token,source_ip) + response = requests.get(api_url, headers=headers) + http_code = http_response_check(response.status_code,api_url) + if response.status_code == 200: + metadata = json.loads(response.content.decode('utf-8')) + for key, details in enumerate(metadata['data']): + for key, value in details.items(): + if (key == "os"): + if (value != None): + html_string += "OS detected: {0}".format(value.encode('utf-8')) + html_string += "
" + else: + return None + +def get_attacker_stats(source_ip): + + global html_string + api_url = 'http://{0}/api/attacker_stats/{1}/?api_key={2}'.format(server_url,source_ip,api_token) + response = requests.get(api_url, headers=headers) + http_code = http_response_check(response.status_code,api_url) + if http_code == 200: + attacker_stats = json.loads(response.content.decode('utf-8')) + attacker_counter = attacker_stats['data']['count'] + html_string += "Total attacks made: {0}".format(attacker_counter) + first_seen = attacker_stats['data']['first_seen'] + first_seen_readable = dateutil.parser.parse(first_seen) + html_string += "
First Seen on: {:%d %B %Y %I:%M:%S %p}".format(first_seen_readable) + last_seen = attacker_stats['data']['last_seen'] + last_seen_readable = dateutil.parser.parse(last_seen) + html_string += "
Last Seen on: {:%d %B %Y %I:%M:%S %p}".format(last_seen_readable) + attacker_honeypots = attacker_stats['data']['honeypots'] + if attacker_honeypots: + html_string += "
Sensors Attacked:" + for k in attacker_honeypots: + html_string += " {0} ".format(k.encode('utf-8')) + attacker_ports = attacker_stats['data']['ports'] + if attacker_ports: + html_string += "
Ports Attacked:" + for k in attacker_ports: + html_string += " {0} ".format(k) + else: + return None + +if __name__ == "__main__": + try: + logging.basicConfig(filename='mhn-report.log', level=logging.DEBUG) + top_attackers = get_top_attackers() + env = Environment(loader=FileSystemLoader('.')) + template = env.get_template("report-template.html") + template_vars = {"generated_date" : datetime.datetime.now().strftime('%I:%M:%S %p %A, %B the %dth, %Y'), + "generated_source": server_url, + "top_attackers_ip_plot": "file:top-attackers-ip.png", + "top_attackers_honeypot_plot": "file:top-attackers-honeypot.png"} + html_out = template.render(template_vars) + html_out = html_out + html_string + #print html_out + filename = "report-mhn-{0}.pdf".format(datetime.datetime.now().strftime('%Y-%m-%d')) + HTML(string=html_out).write_pdf(filename) + send_mail() + except Exception, e: + logging.error("{0} - Error: Unknown error, program terminated".format(datetime.datetime.now()))