Commits

György Kohut committed ec10fbb

add stats page for source ips

Comments (0)

Files changed (6)

hbwebui/queries.py

     
     def filter_source_ip(self, source_ips):
         self.where_append('filter_source_ip', 'source_ip IN %s', [tuple(source_ips)])
+        
+
+
+class Stats_Source_IPs(QueryBase):
+    db = 'hbstats'
+    tpl = \
+        """SELECT
+                source_ip, cc, asn,
+                sum(agg_main.n_count)::bigint as n_count,
+                count(DISTINCT ident_id) AS n_ident, count(DISTINCT binary_id) AS n_binary, count(DISTINCT target_port) AS n_target_port,
+                max(agg_main.ts_last) as ts_last, min(agg_main.ts_first) as ts_first
+            FROM
+                agg_main
+            JOIN
+                dim_ident ON agg_main.ident_id = dim_ident.id
+            LEFT JOIN
+                att_asn_shadowserver ON agg_main.source_ip = att_asn_shadowserver.ip
+            %(where_clause)s
+            GROUP BY source_ip, cc, asn
+            %(order_by_clause)s"""
+    
+    def __init__(self):
+        super(Stats_Source_IPs, self).__init__()
+        self.where_init()
+        self.order_by_init()
+    
+    def filter_ident(self, idents):
+        self.where_append('filter_ident', 'ident_id IN (SELECT id from dim_ident WHERE ident IN %s)', [tuple(idents)])
+        
+    def order_n_count(self, desc=False):
+        self.order_by_append('order_n_count', 'n_count', desc)
+
+
+class Stats_Source_IPs_Summary(QueryBase):
+    db = 'hbstats'
+    tpl = \
+        """SELECT
+                count(DISTINCT source_ip) as n_count,
+                count(DISTINCT cc) as n_cc, count(DISTINCT asn) as n_asn,
+                count(DISTINCT ident_id) AS n_ident, count(DISTINCT binary_id) AS n_binary, count(DISTINCT target_port) AS n_target_port,
+                max(agg_main.ts_last) as ts_last, min(agg_main.ts_first) as ts_first,
+                sum(n_count)::bigint as n_total
+            FROM
+                agg_main
+            LEFT JOIN
+                att_asn_shadowserver ON agg_main.source_ip = att_asn_shadowserver.ip
+            %(where_clause)s"""
+    
+    def __init__(self):
+        super(Stats_Source_IPs_Summary, self).__init__()
+        self.where_init()
+    
+    def filter_ident(self, idents):
+        self.where_append('filter_ident', 'ident_id IN (SELECT id from dim_ident WHERE ident IN %s)', [tuple(idents)])

hbwebui/static/js/hbwebui/mod_stats_source_ips.js

+mod_stats_source_ips = (function() {
+    
+    function summary(container, url) {
+        mod_stats_base.summary.call(this, container, url);
+                
+        this.tpl = this.tpl = '\
+            <h3><%= n_count %> <% print(pluralize(n_count, "Source IP")) %></h3>\
+            <ul>\
+                <li>from <%= n_cc %> <% print(pluralize(n_cc, "Country", "Countries")) %></li>\
+                <li>from <%= n_asn %> <% print(pluralize(n_asn, "ASN")) %></li>\
+                <li>collected by <%= n_ident %> <% print(pluralize(n_ident, "ident")) %></li>\
+                <li>on <%= n_target_port %> target <% print(pluralize(n_target_port, "port")) %></li>\
+                <li>uploaded <%= n_binary %> <% print(pluralize(n_binary, "Binary", "Binaries")) %></li>\
+                <li>between <%= ts_first %> - <%= ts_last %></li>\
+                <li>in <%= n_total %> <% print(pluralize(n_total, "attack")) %> in total</li>\
+            </ul>';
+    }
+    summary.prototype = utils.extend(
+        mod_stats_base.summary,
+        {
+            renderer: function(data) {
+                data.ts_first = mod_base.renderTimestamp(data.ts_first);
+                data.ts_last = mod_base.renderTimestamp(data.ts_last);
+                mod_stats_base.summary.prototype.renderer.call(this, data);
+            }
+        }
+    );
+    
+    
+    function table(container, url) {
+        mod_stats_base.table.call(this, container, url);
+        
+        this.dtConfig = $.extend(
+            this.dtConfig,
+            {
+                'aoColumnDefs': [
+                    { 'sTitle': 'Source IP', 'mDataProp': 'source_ip', 'sType': 'string', 'aTargets': [0], 'fnRender': function(o, val) { return '<a href="#">'+val+'</a>'; }},
+                    { 'sTitle': 'Country', 'mDataProp': 'cc', 'sType': 'string', 'aTargets': [1], },
+                    { 'sTitle': 'ASN', 'mDataProp': 'asn', 'sType': 'numeric', 'aTargets': [2] },
+                    { 'sTitle': '# Attacks', 'mDataProp': 'n_count', 'sType': 'numeric', 'aTargets': [3] },
+                    { 'sTitle': '# Idents', 'mDataProp': 'n_ident', 'sType': 'numeric', 'aTargets': [4] },
+                    { 'sTitle': '# Binaries', 'mDataProp': 'n_binary', 'sType': 'numeric', 'aTargets': [5] },
+                    { 'sTitle': '# Target Ports', 'mDataProp': 'n_target_port', 'sType': 'numeric', 'aTargets': [6] },
+                    { 'sTitle': 'Last', 'mDataProp': 'ts_last', 'sType': null, 'aTargets': [7], 'fnRender': function(o, val) { return mod_base.renderTimestamp(val); }},
+                    { 'sTitle': 'First', 'mDataProp': 'ts_first', 'sType': null, 'aTargets': [8], 'fnRender': function(o, val) { return mod_base.renderTimestamp(val); }}
+                ],
+                'aaSorting': [
+                    [3, 'desc'],
+                ]
+            }
+        );
+    }
+    table.prototype = utils.extend(mod_stats_base.table);
+    
+    
+    return {
+        summary: summary,
+        table: table
+    };
+})();

hbwebui/templates/navbar.html

             <ul class="nav">
                 <li {% if page == "dashboard" %}class="active"{% endif %}><a href="{% if page == "dashboard" %}#{% else %}{% url dashboard %}{% endif %}">Dashboard</a></li>
                 
-                {% if page == "stats_binaries" %}
+                {% if page == "stats_binaries" or page == "stats_source_ips" %}
                 <li class="dropdown active">
                     {% if page == "stats_binaries" %}
-                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">Stats / Binaries<span class="caret"></span></a>
+                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">Stats / Binaries <span class="caret"></span></a>
+                    {% endif %}
+                    {% if page == "stats_source_ips" %}
+                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">Stats / Source IPs <span class="caret"></span></a>
                     {% endif %}
-                    <ul class="dropdown-menu">
-                        {% if page == "stats_binaries" %}
-                        <li><a href="#"><strong>Binaries</strong></a></li>
-                        {% endif %}
-                        <li><a href="#">Source IPs</a></li>
-                    </ul>
-                </li>
                 {% else %}
                 <li class="dropdown">
                     <a class="dropdown-toggle" data-toggle="dropdown" href="#">Stats <span class="caret"></span></a>
+                {% endif %}
                     <ul class="dropdown-menu">
+                        {% if page == "stats_binaries" %}
+                        <li><a href="#"><strong>Binaries</strong></a></li>
+                        {% else %}
                         <li><a href="{% url stats_binaries %}">Binaries</a>
-                        <li><a href="#">Source IPs</a></li>
+                        {% endif %}
+                        {% if page == "stats_source_ips" %}
+                        <li><a href="#"><strong>Source IPs</strong></a></li>
+                        {% else %}
+                        <li><a href="{% url stats_source_ips %}">Source IPs</a>
+                        {% endif %}
                     </ul>
                 </li>
-                {% endif %}
             </ul>
             <div class="nav pull-right dropdown">
                 <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"><span class="icon-user"></span> {{ user.username }} <span class="caret"></span></a>

hbwebui/templates/stats_source_ips.html

+{% extends "bootstrap.html" %}
+{% block bootstrap-head %}
+
+{% load staticfiles %}
+
+<script src="{% static "js/lodash.min.js" %}"></script>
+<script src="{% static "js/hbwebui/utils.js" %}"></script>
+<script src="{% static "js/hbwebui/mod_base.js" %}"></script>
+<script src="{% static "js/hbwebui/mod_stats_base.js" %}"></script>
+<script src="{% static "js/hbwebui/mod_stats_source_ips.js" %}"></script>
+
+
+<title>Source IPs Stats</title>
+
+
+<script>
+    urls = {
+        'mod_summary': '{% url r_stats_source_ips_summary %}',
+        'mod_table': '{% url r_stats_source_ips %}',
+    };
+    
+    var idents = {{ idents|safe }};
+    
+    
+    $(
+        function() {
+            mod_summary = new mod_stats_source_ips.summary($('#mod-summary'), urls.mod_summary);
+            mod_summary.render();
+            
+            mod_table = new mod_stats_source_ips.table($('#mod-table'), urls.mod_table);
+            mod_table.render();
+        }
+    );
+</script>
+
+{% endblock %}
+
+{% block bootstrap-body %}
+{% include "navbar.html" %}
+
+<div class="container-fluid">
+    <div class="row-fluid">
+        <div id="mod-summary"></div>
+        <hr/>
+    </div>
+    <div class="row-fluid">
+        <div id="mod-table"></div>
+    </div>
+</div>
+
+{% endblock %}
 urlpatterns = patterns('hbwebui.views',
     url(r'^$', 'dashboard', name='dashboard'),
     url(r'^stats/binaries$', 'stats_binaries', name='stats_binaries'),
+    url(r'^stats/source_ips$', 'stats_source_ips', name='stats_source_ips'),
+    
+    url(r'^r/stats/source_ips$', 'r_stats_source_ips', name='r_stats_source_ips'),
+    url(r'^r/stats/source_ips/summary$', 'r_stats_source_ips_summary', name='r_stats_source_ips_summary'),
     
     url(r'^r/stats/binaries$', 'r_stats_binaries', name='r_stats_binaries'),
     url(r'^r/stats/binaries/summary$', 'r_stats_binaries_summary', name='r_stats_binaries_summary'),
     
     return response
 
+@login_required(login_url=login_url)
+@ident_required
+def stats_source_ips(request):
+    idents = request.session['idents']
+        
+    t = loader.get_template('stats_source_ips.html')
+    c = RequestContext(request, {
+            'page': 'stats_source_ips',
+            'idents': json.dumps(idents),
+    })
+    return HttpResponse(t.render(c))
+
+@login_required_simple
+@ident_required_simple
+def r_stats_source_ips(request):
+    idents = request.session['idents']
+    
+    q = queries.Stats_Source_IPs()
+    q.filter_ident(idents)
+    q.order_n_count(desc=True)
+    print q.build()
+    cursor = q.execute()
+    qr = util.dictfetchall(cursor)
+    
+    r = []
+    for d in qr:
+        o = {}
+        o['source_ip'] = d['source_ip']
+        o['cc'] = d['cc']
+        o['asn'] = d['asn']
+        o['n_count'] = d['n_count']
+        o['n_ident'] = d['n_ident']
+        o['n_binary'] = d['n_binary']
+        o['n_target_port'] = d['n_target_port']
+        o['ts_last'] = calendar.timegm(d['ts_last'].utctimetuple())
+        o['ts_first'] = calendar.timegm(d['ts_first'].utctimetuple())
+        r.append(o)
+    
+    response = HttpResponse(mimetype='application/json')
+    json.dump(r, response)
+    
+    return response
+
+@login_required_simple
+@ident_required_simple
+def r_stats_source_ips_summary(request):
+    idents = request.session['idents']
+    
+    q = queries.Stats_Source_IPs_Summary()
+    q.filter_ident(idents)
+    cursor = q.execute()
+    qr = util.dictfetchall(cursor)
+    
+    r = {}
+    r['n_count'] = qr[0]['n_count']
+    r['n_cc'] = qr[0]['n_cc']
+    r['n_asn'] = qr[0]['n_asn']
+    r['n_ident'] = qr[0]['n_ident']
+    r['n_binary'] = qr[0]['n_binary']
+    r['n_target_port'] = qr[0]['n_target_port']
+    r['ts_last'] = calendar.timegm(qr[0]['ts_last'].utctimetuple())
+    r['ts_first'] = calendar.timegm(qr[0]['ts_first'].utctimetuple())
+    r['n_total'] = qr[0]['n_total']
+    
+    response = HttpResponse(mimetype='application/json')
+    json.dump(r, response)
+    
+    return response
+
 # example
 @login_required_simple
 @ident_required_simple