/
report-bl-hostnames.go
114 lines (97 loc) · 2.88 KB
/
report-bl-hostnames.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package reporting
import (
"bytes"
"html/template"
"os"
"sort"
"github.com/globalsign/mgo/bson"
"github.com/activecm/rita/pkg/hostname"
"github.com/activecm/rita/reporting/templates"
"github.com/activecm/rita/resources"
)
func printBLHostnames(db string, res *resources.Resources) error {
f, err := os.Create("bl-hostnames.html")
if err != nil {
return err
}
defer f.Close()
data, err := getBlacklistedHostnameResultsView(res, "conn_count", 1000)
if err != nil {
return err
}
out, err := template.New("bl-hostnames.html").Parse(templates.BLHostnameTempl)
if err != nil {
return err
}
w, err := getBLHostnameWriter(data)
if err != nil {
return err
}
return out.Execute(f, &templates.ReportingInfo{DB: db, Writer: template.HTML(w)})
}
func getBLHostnameWriter(results []hostname.AnalysisView) (string, error) {
tmpl := "<tr><td>{{.Host}}</td><td>{{.Connections}}</td><td>{{.UniqueConnections}}</td>" +
"<td>{{.TotalBytes}}</td>" +
"<td>{{range $idx, $host := .ConnectedHosts}}{{if $idx}}, {{end}}{{ $host }}{{end}}</td>" +
"</tr>\n"
out, err := template.New("blhostname").Parse(tmpl)
if err != nil {
return "", err
}
w := new(bytes.Buffer)
for _, result := range results {
sort.Strings(result.ConnectedHosts)
err := out.Execute(w, result)
if err != nil {
return "", err
}
}
return w.String(), nil
}
//getBlacklistedHostnameResultsView ....
func getBlacklistedHostnameResultsView(res *resources.Resources, sort string, limit int) ([]hostname.AnalysisView, error) {
ssn := res.DB.Session.Copy()
defer ssn.Close()
blHostsQuery := []bson.M{
bson.M{"$match": bson.M{"blacklisted": true}},
bson.M{"$unwind": "$dat"},
bson.M{"$project": bson.M{"host": 1, "ips": "$dat.ips"}},
bson.M{"$unwind": "$ips"},
bson.M{"$group": bson.M{
"_id": "$host",
"ips": bson.M{"$addToSet": "$ips"},
}},
bson.M{"$unwind": "$ips"},
bson.M{"$lookup": bson.M{
"from": "uconn",
"localField": "ips",
"foreignField": "dst",
"as": "uconn",
}},
bson.M{"$unwind": "$uconn"},
bson.M{"$unwind": "$uconn.dat"},
bson.M{"$project": bson.M{"host": 1, "conns": "$uconn.dat.count", "bytes": "$uconn.dat.tbytes", "ip": "$uconn.src"}},
bson.M{"$group": bson.M{
"_id": "$_id",
"ips": bson.M{"$addToSet": "$ip"},
"conn_count": bson.M{"$sum": "$conns"},
"total_bytes": bson.M{"$sum": "$bytes"},
}},
bson.M{"$sort": bson.M{sort: -1}},
bson.M{"$limit": limit},
bson.M{"$project": bson.M{
"_id": 0,
"host": "$_id",
"uconn_count": bson.M{"$size": bson.M{"$ifNull": []interface{}{"$ips", []interface{}{}}}},
"ips": 1,
"conn_count": 1,
"total_bytes": 1,
}},
}
var blHosts []hostname.AnalysisView
err := ssn.DB(res.DB.GetSelectedDB()).C(res.Config.T.DNS.HostnamesTable).Pipe(blHostsQuery).AllowDiskUse().All(&blHosts)
if err != nil {
return nil, err
}
return blHosts, nil
}