You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
7.8 KiB

3 years ago
[![Project Status: Active – The project has reached a stable, usable
state and is being actively
developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
[![Signed
by](https://img.shields.io/badge/Keybase-Verified-brightgreen.svg)](https://keybase.io/hrbrmstr)
![Signed commit
%](https://img.shields.io/badge/Signed_Commits-100%25-lightgrey.svg)
[![Linux build
Status](https://travis-ci.org/hrbrmstr/brimr.svg?branch=master)](https://travis-ci.org/hrbrmstr/brimr)
![Minimal R
Version](https://img.shields.io/badge/R%3E%3D-3.6.0-blue.svg)
![License](https://img.shields.io/badge/License-MIT-blue.svg)
# brimr
Tools to Work with Brim and zqd
## Description
Brim (<https://github.com/brimsec/brim>) enables efficient query
3 years ago
operations on large packet captures and log sources, such as Zeek. Tools
are provided to with with Brim components, including the Brim zqd query
back-end.
3 years ago
## What’s Inside The Tin
The following functions are implemented:
- `brim_ast`: Turn a Brim ZQL query into an abstract syntax tree
- `brim_host`: Retrieve the Brim host URL
- `brim_search_raw`: Post a ZQL query to the given Brim instance and
retrieve results in raq ZJSON format
- `brim_search`: Post a ZQL query to the given Brim instance and
retrieve processed results
- `brim_spaces`: Retrieve active Brim spaces from the specified Brim
instance
3 years ago
- `tidy_brim`: Turn Brim/zqd search results into a data frame
- `zq_cmd`: Execute a zq command line
3 years ago
## Installation
``` r
remotes::install_git("https://git.rud.is/hrbrmstr/brimr.git")
# or
remotes::install_gitlab("hrbrmstr/brimr")
# or
remotes::install_bitbucket("hrbrmstr/brimr")
3 years ago
# or
remotes::install_github("hrbrmstr/brimr")
3 years ago
```
NOTE: To use the ‘remotes’ install options you will need to have the
[{remotes} package](https://github.com/r-lib/remotes) installed.
## Usage
``` r
library(brimr)
library(tibble)
# current version
packageVersion("brimr")
## [1] '0.1.0'
```
3 years ago
### Available Brim “spaces”
3 years ago
``` r
brim_spaces()
3 years ago
## id name
## 1 sp_1p6pwLgtsESYBTHU9PL9fcl2iBn 2021-02-17-Trickbot-gtag-rob13-infection-in-AD-environment.pcap
## data_path storage_kind
## 1 file:///Users/hrbrmstr/Library/Application%20Support/Brim/data/spaces/sp_1p6pwLgtsESYBTHU9PL9fcl2iBn filestore
```
3 years ago
3 years ago
### Sample ZQL query
3 years ago
3 years ago
``` r
# Z query to fetch Zeek connection data to create our network connection graph
zql1 <- '_path=conn | count() by id.orig_h, id.resp_h, id.resp_p | sort id.orig_h, id.resp_h, id.resp_p'
cat(
substr(jsonlite::toJSON(jsonlite::fromJSON(brim_ast(zql1)), pretty = TRUE), 1, 100), "..."
)
3 years ago
## {
## "op": ["SequentialProc"],
## "procs": [
## {
## "op": "FilterProc",
## "filter": {
3 years ago
## ...
```
### Let’s execute the query
3 years ago
3 years ago
``` r
3 years ago
space <- "2021-02-17-Trickbot-gtag-rob13-infection-in-AD-environment.pcap"
3 years ago
r1 <- brim_search(space, zql1)
r1
## ZQL query took 0.0000 seconds; 384 records matched; 1,082 records read; 238,052 bytes read
(r1 <- as_tibble(tidy_brim(r1)))
## # A tibble: 74 x 4
## orig_h resp_h resp_p count
## <chr> <chr> <chr> <int>
## 1 10.2.17.2 10.2.17.101 49787 1
## 2 10.2.17.101 3.222.126.94 80 1
## 3 10.2.17.101 10.2.17.1 445 1
## 4 10.2.17.101 10.2.17.2 53 97
## 5 10.2.17.101 10.2.17.2 88 27
## 6 10.2.17.101 10.2.17.2 123 5
## 7 10.2.17.101 10.2.17.2 135 8
## 8 10.2.17.101 10.2.17.2 137 2
## 9 10.2.17.101 10.2.17.2 138 2
## 10 10.2.17.101 10.2.17.2 389 37
## # … with 64 more rows
```
### Let’s try one that processes the Suricata alerts
``` r
# Z query to fetch Suricata alerts including the count of alerts per source:destination
zql2 <- "event_type=alert | count() by src_ip, dest_ip, dest_port, alert.severity, alert.signature | sort src_ip, dest_ip, dest_port, alert.severity, alert.signature"
r2 <- brim_search(space, zql2)
r2
## ZQL query took 0.0000 seconds; 47 records matched; 870 records read; 238,660 bytes read
(r2 <- (as_tibble(tidy_brim(r2))))
## # A tibble: 35 x 6
## src_ip dest_ip dest_port severity signature count
## <chr> <chr> <int> <int> <chr> <int>
## 1 10.2.17.2 10.2.17.1… 49674 3 SURICATA Applayer Detect protocol only one direction 1
## 2 10.2.17.2 10.2.17.1… 49680 3 SURICATA Applayer Detect protocol only one direction 1
## 3 10.2.17.2 10.2.17.1… 49687 3 SURICATA Applayer Detect protocol only one direction 1
## 4 10.2.17.2 10.2.17.1… 49704 3 SURICATA Applayer Detect protocol only one direction 1
## 5 10.2.17.2 10.2.17.1… 49709 3 SURICATA Applayer Detect protocol only one direction 1
## 6 10.2.17.2 10.2.17.1… 49721 3 SURICATA Applayer Detect protocol only one direction 1
## 7 10.2.17.2 10.2.17.1… 50126 3 SURICATA Applayer Detect protocol only one direction 1
## 8 10.2.17.1… 3.222.126… 80 2 ET POLICY curl User-Agent Outbound 1
## 9 10.2.17.1… 36.95.27.… 443 1 ET HUNTING Suspicious POST with Common Windows Process Names - Possib… 1
## 10 10.2.17.1… 36.95.27.… 443 1 ET MALWARE Win32/Trickbot Data Exfiltration 1
## # … with 25 more rows
3 years ago
```
3 years ago
``` r
library(igraph)
library(ggraph)
library(tidyverse)
gdf <- count(r1, orig_h, resp_h, wt=count)
count(gdf, node = resp_h, wt=n, name = "in_degree") %>%
full_join(
count(gdf, node = orig_h, name = "out_degree")
) %>%
mutate_at(
vars(in_degree, out_degree),
replace_na, 1
) %>%
arrange(in_degree) -> vdf
g <- graph_from_data_frame(gdf, vertices = vdf)
ggraph(g, layout = "linear") +
geom_node_point(
aes(size = in_degree), shape = 21
) +
geom_edge_arc(
width = 0.125,
arrow = arrow(
length = unit(5, "pt"),
type = "closed"
)
)
```
<img src="man/figures/README-graph-1.png" width="864" />
### Use `zq` directly
``` r
zq_cmd(
c(
'"* | cut ts,id.orig_h,id.orig_p"', # note the quotes
system.file("logs", "conn.log.gz", package = "brimr")
)
)
## id.orig_h id.orig_p ts
## 1: 10.164.94.120 39681 2018-03-24T17:15:21.255387Z
## 2: 10.47.25.80 50817 2018-03-24T17:15:21.411148Z
## 3: 10.47.25.80 50817 2018-03-24T17:15:21.926018Z
## 4: 10.47.25.80 50813 2018-03-24T17:15:22.690601Z
## 5: 10.47.25.80 50813 2018-03-24T17:15:23.205187Z
## ---
## 988: 10.174.251.215 33003 2018-03-24T17:15:21.429238Z
## 989: 10.174.251.215 33003 2018-03-24T17:15:21.429315Z
## 990: 10.174.251.215 33003 2018-03-24T17:15:21.429479Z
## 991: 10.164.94.120 38265 2018-03-24T17:15:21.427375Z
## 992: 10.174.251.215 33003 2018-03-24T17:15:21.433306Z
```
3 years ago
## brimr Metrics
| Lang | \# Files | (%) | LoC | (%) | Blank lines | (%) | \# Lines | (%) |
|:-----|---------:|-----:|----:|-----:|------------:|-----:|---------:|-----:|
| R | 5 | 0.42 | 180 | 0.39 | 71 | 0.33 | 86 | 0.32 |
| Rmd | 1 | 0.08 | 53 | 0.11 | 37 | 0.17 | 47 | 0.18 |
| SUM | 6 | 0.50 | 233 | 0.50 | 108 | 0.50 | 133 | 0.50 |
3 years ago
clock Package Metrics for brimr
## Code of Conduct
Please note that this project is released with a Contributor Code of
Conduct. By participating in this project you agree to abide by its
terms.