-
Notifications
You must be signed in to change notification settings - Fork 361
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial poc layout and mongo query setup * added dissector and sorter portions of the beaconing process to the fqdn beacons package * beaconing by fqdn table creation functionality finished * Add ResolvedIPs to data sent to sorter * Working MVP for FQDN Beaconing Detection * moved datatypes/functions only used in fqdn beacons out of the data package * Added show-beacons-fqdn command and updated supporting files * initial all sources modification * stashin changes * Changed module fields to beaconsFQDN * removed mongodb_test.go * Addid static config for BeaconFQDN * Fixed name in static config, added flag in fsimporter * Filter out strobes for now * Fixed reporting output for dst/src IPs * updated strobes flagging and storage for fqdn beacons * Added BeaconFQDN to rita.yaml * Updated a comment * Removed todo comment for config file update * Move countAndRemoveConsecutiveDuplicates to the analyzer where it is used in beacons and beaconsFQDN, update comments in beacon and beaconfqdn sorter, add typing info to FqdnInput.DstBSONList * added initial additional worker functionality for beacons fqdn * fixed closing bug in new worker * Fix bug where dissector query was matching on src_network_name, clean up unique ip data structures. Co-authored-by: lisaSW <[email protected]> Co-authored-by: Logan Lembke <[email protected]> Co-authored-by: lisaSW <[email protected]> Co-authored-by: Logan L <[email protected]>
- Loading branch information
1 parent
b842e05
commit 7c72d56
Showing
22 changed files
with
1,770 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package commands | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/activecm/rita/pkg/beaconfqdn" | ||
"github.com/activecm/rita/resources" | ||
"github.com/olekukonko/tablewriter" | ||
"github.com/urfave/cli" | ||
) | ||
|
||
func init() { | ||
command := cli.Command{ | ||
Name: "show-beacons-fqdn", | ||
Usage: "Print hosts which show signs of C2 software (FQDN Analysis)", | ||
ArgsUsage: "<database>", | ||
Flags: []cli.Flag{ | ||
humanFlag, | ||
configFlag, | ||
delimFlag, | ||
netNamesFlag, | ||
}, | ||
Action: showBeaconsFQDN, | ||
} | ||
|
||
bootstrapCommands(command) | ||
} | ||
|
||
func showBeaconsFQDN(c *cli.Context) error { | ||
db := c.Args().Get(0) | ||
if db == "" { | ||
return cli.NewExitError("Specify a database", -1) | ||
} | ||
res := resources.InitResources(c.String("config")) | ||
res.DB.SelectDB(db) | ||
|
||
data, err := beaconfqdn.Results(res, 0) | ||
|
||
if err != nil { | ||
res.Log.Error(err) | ||
return cli.NewExitError(err, -1) | ||
} | ||
|
||
if !(len(data) > 0) { | ||
return cli.NewExitError("No results were found for "+db, -1) | ||
} | ||
|
||
showNetNames := c.Bool("network-names") | ||
|
||
if c.Bool("human-readable") { | ||
err := showBeaconsFQDNHuman(data, showNetNames) | ||
if err != nil { | ||
return cli.NewExitError(err.Error(), -1) | ||
} | ||
return nil | ||
} | ||
|
||
err = showBeaconsFQDNDelim(data, c.String("delimiter"), showNetNames) | ||
if err != nil { | ||
return cli.NewExitError(err.Error(), -1) | ||
} | ||
return nil | ||
} | ||
|
||
func showBeaconsFQDNHuman(data []beaconfqdn.Result, showNetNames bool) error { | ||
table := tablewriter.NewWriter(os.Stdout) | ||
var headerFields []string | ||
if showNetNames { | ||
headerFields = []string{ | ||
"Score", "Source Network", "Source IP", "FQDN", "Resolved IPs", | ||
"Connections", "Avg. Bytes", "Intvl Range", "Size Range", "Top Intvl", | ||
"Top Size", "Top Intvl Count", "Top Size Count", "Intvl Skew", | ||
"Size Skew", "Intvl Dispersion", "Size Dispersion", | ||
} | ||
} else { | ||
headerFields = []string{ | ||
"Score", "Source IP", "FQDN", "Resolved IPs", | ||
"Connections", "Avg. Bytes", "Intvl Range", "Size Range", "Top Intvl", | ||
"Top Size", "Top Intvl Count", "Top Size Count", "Intvl Skew", | ||
"Size Skew", "Intvl Dispersion", "Size Dispersion", | ||
} | ||
} | ||
|
||
table.SetHeader(headerFields) | ||
|
||
for _, d := range data { | ||
var row []string | ||
|
||
if showNetNames { | ||
row = []string{ | ||
f(d.Score), d.SrcNetworkName, | ||
d.SrcIP, d.FQDN, i(d.Connections), f(d.AvgBytes), | ||
i(d.Ts.Range), i(d.Ds.Range), i(d.Ts.Mode), i(d.Ds.Mode), | ||
i(d.Ts.ModeCount), i(d.Ds.ModeCount), f(d.Ts.Skew), f(d.Ds.Skew), | ||
i(d.Ts.Dispersion), i(d.Ds.Dispersion), | ||
} | ||
} else { | ||
row = []string{ | ||
f(d.Score), d.SrcIP, d.FQDN, i(d.Connections), f(d.AvgBytes), | ||
i(d.Ts.Range), i(d.Ds.Range), i(d.Ts.Mode), i(d.Ds.Mode), | ||
i(d.Ts.ModeCount), i(d.Ds.ModeCount), f(d.Ts.Skew), f(d.Ds.Skew), | ||
i(d.Ts.Dispersion), i(d.Ds.Dispersion), | ||
} | ||
} | ||
table.Append(row) | ||
} | ||
table.Render() | ||
return nil | ||
} | ||
|
||
func showBeaconsFQDNDelim(data []beaconfqdn.Result, delim string, showNetNames bool) error { | ||
var headerFields []string | ||
if showNetNames { | ||
headerFields = []string{ | ||
"Score", "Source Network", "Source IP", "FQDN", | ||
"Connections", "Avg. Bytes", "Intvl Range", "Size Range", "Top Intvl", | ||
"Top Size", "Top Intvl Count", "Top Size Count", "Intvl Skew", | ||
"Size Skew", "Intvl Dispersion", "Size Dispersion", | ||
} | ||
} else { | ||
headerFields = []string{ | ||
"Score", "Source IP", "FQDN", | ||
"Connections", "Avg. Bytes", "Intvl Range", "Size Range", "Top Intvl", | ||
"Top Size", "Top Intvl Count", "Top Size Count", "Intvl Skew", | ||
"Size Skew", "Intvl Dispersion", "Size Dispersion", | ||
} | ||
} | ||
|
||
// Print the headers and analytic values, separated by a delimiter | ||
fmt.Println(strings.Join(headerFields, delim)) | ||
for _, d := range data { | ||
|
||
var row []string | ||
if showNetNames { | ||
row = []string{ | ||
f(d.Score), d.SrcNetworkName, | ||
d.SrcIP, d.FQDN, i(d.Connections), f(d.AvgBytes), | ||
i(d.Ts.Range), i(d.Ds.Range), i(d.Ts.Mode), i(d.Ds.Mode), | ||
i(d.Ts.ModeCount), i(d.Ds.ModeCount), f(d.Ts.Skew), f(d.Ds.Skew), | ||
i(d.Ts.Dispersion), i(d.Ds.Dispersion), | ||
} | ||
} else { | ||
row = []string{ | ||
f(d.Score), d.SrcIP, d.FQDN, i(d.Connections), f(d.AvgBytes), | ||
i(d.Ts.Range), i(d.Ds.Range), i(d.Ts.Mode), i(d.Ds.Mode), | ||
i(d.Ts.ModeCount), i(d.Ds.ModeCount), f(d.Ts.Skew), f(d.Ds.Skew), | ||
i(d.Ts.Dispersion), i(d.Ds.Dispersion), | ||
} | ||
} | ||
|
||
fmt.Println(strings.Join(row, delim)) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.