SkillAgentSearch skills...

Beagle

Beagle is an incident response and digital forensics tool which transforms security logs and data into graphs.

Install / Use

/learn @yampelo/Beagle
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Beagle

Build Status codecov Read The Docs Docker PyPI Slack

<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=4 orderedList=true} --> <!-- code_chunk_output -->
  1. About Beagle
  2. Installation
    1. Docker
    2. Python Package
    3. Configuration
  3. Web Interface
    1. Uploading Data
    2. Browsing Existing Graphs
    3. Graph Interface
      1. Inspecting Nodes and Edges
      2. Expanding Neighbours
      3. Hiding Nodes
      4. Running Mutators
      5. Toggling Node and Edge Types
      6. Undo/Redo Action and Reset
      7. Graph Perspectives
  4. Python Library
    1. Controlling Edge Generation
    2. Loading Saved JSON
  5. Documentation
<!-- /code_chunk_output -->

About Beagle

Beagle is an incident response and digital forensics tool which transforms data sources and logs into graphs. Supported data sources include FireEye HX Triages, Windows EVTX files, SysMon logs and Raw Windows memory images. The resulting Graphs can be sent to graph databases such as Neo4J or DGraph, or they can be kept locally as Python NetworkX objects.

Beagle can be used directly as a python library, or through a provided web interface.

<center> <img src ="docs/imgs/upload_to_graph.gif"> </center>

The library can be used either as a sequence of functional calls from a single datasource.

>>> from beagle.datasources import SysmonEVTX

>>> graph = SysmonEVTX("malicious.evtx").to_graph()
>>> graph
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>

As a graph generated from a set of multiple artifacts

>>> from beagle.datasources import SysmonEVTX, HXTriage, PCAP
>>> from beagle.backends import NetworkX

>>> nx = NetworkX.from_datasources(
    datasources=[
        SysmonEVTX("malicious.evtx"),
        HXTriage("alert.mans"),
        PCAP("traffic.pcap"),
    ]
)
>>> G = nx.graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>

Or by strictly calling each intermediate step of the data source to graph process.

>>> from beagle.backends import NetworkX
>>> from beagle.datasources import SysmonEVTX
>>> from beagle.transformers import SysmonTransformer

>>> datasource = SysmonEVTX("malicious.evtx")

# Transformers take a datasource, and transform each event
# into a tuple of one or more nodes.
>>> transformer = SysmonTransformer(datasource=datasource)
>>> nodes = transformer.run()

# Transformers output an array of nodes.
[
    (<SysMonProc> process_guid="{0ad3e319-0c16-59c8-0000-0010d47d0000}"),
    (<File> host="DESKTOP-2C3IQHO" full_path="C:\Windows\System32\services.exe"),
    ...
]

# Backends take the nodes, and transform them into graphs
>>> backend = NetworkX(nodes=nodes)
>>> G = backend.graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x126b887f0>

Graphs are centered around the activity of individual processes, and are meant primarily to help analysts investigate activity on hosts, not between them.

Installation

Docker

Beagle is available as a docker file:

docker pull yampelo/beagle
mkdir -p data/beagle
docker run -v "$PWD/data/beagle":"/data/beagle" -p 8000:8000 yampelo/beagle

Python Package

It is also available as library. Full API Documentation is available on https://beagle-graphs.readthedocs.io

pip install pybeagle

Note: Only Python 3.6+ is currently supported.

Rekall is not automatically installed. To install Rekall execute the following command instead:

pip install pybeagle[rekall]

Configuration

Any entry in the configuration file can be modified using environment variables that follow the following format: BEAGLE__{SECTION}__{KEY}. For example, in order to change the VirusTotal API Key used when using the docker image, you would use -e parameter and set the BEAGLE__VIRUSTOTAL__API_KEY variable:

docker run -v "data/beagle":"/data/beagle" -p 8000:8000 -e "BEAGLE__VIRUSTOTAL__API_KEY=$API_KEY" beagle

Environment variables and directories can be easily defined using docker compose

version: "3"

services:
    beagle:
        image: yampelo/beagle
        volumes:
            - /data/beagle:/data/beagle
        ports:
            - "8000:8000"
        environment:
            - BEAGLE__VIRUSTOTAL__API_KEY=$key$

Web Interface

Beagle's docker image comes with a web interface that wraps around the process of both transforming data into graphs, as well as using them to investigate data.

Uploading Data

<center> <img src ="docs/imgs/web_upload_dropdown.gif"> </center>

The upload form wraps around the graph creation process, and automatically uses NetworkX as the backend. Depending on the parameters required by the data source, the form will either prompt for a file upload, or text input. For example:

  • VT API Sandbox Report asks for the hash to graph.
  • FireEye HX requires the HX triage.

Any graph created is stored locally in the folder defined under the dir key from the storage section in the configuration. This can be modified by setting the BEAGLE__STORAGE__DIR environment variable.

Optionally, a comment can be added to any graph to better help describe it.

Each data source will automatically extract metadata from the provided parameter. The metadata and comment are visible later on when viewing the existing graphs of the datasource.

Browsing Existing Graphs

Clicking on a datasource on the sidebar renders a table of all parsed graphs for that datasource.

<center> <img src="docs/imgs/existing_graphs_page.png"> </center>

Graph Interface

Viewing a graph in Beagle provides a web interface that allows analysts to quickly pivot around an incident.

The interface is split into two main parts, the left part which contains various perspectives of the graph (Graph, Tree, Table, etc), and the right part which allows you to filter nodes and edges by type, search for nodes, and expand a node's properties. It also allows you to undo and redo operations you perform on the graph.

Any element in the graph that has a divider above it is collapsible:

<center> <img src="docs/imgs/collapsable.gif"> </center>

Inspecting Nodes and Edges

Nodes in the graph display the first 15 characters of a specific field. For example, for a process node, this will be the process name.

Edges simply show the edge type.

A single click on a node or edge will focus that node and display its information in the "Node Info" panel on the right sidebar.

Focusing on a Node
<center> <img src="docs/imgs/node_select.gif"> </center>
Focusing on an Edge
<center> <img src="docs/imgs/edge_select.gif"> </center>

Expanding Neighbours

A double click on a node will pull in any neighbouring nodes. A neighbouring node is any node connected to the clicked-on node by an edge. If there are no neighbors to be pulled in, no change will be seen in the graph.

  • This is regardless of direction. That means that a parent process or a child process could be pulled in when double clicking on a node.
  • Beagle will only pull in 25 nodes at a time.
<center> <img src="docs/imgs/double_click_neighbours.gif"> </center>

Hiding Nodes

A long single click on a node will hide it from the graph, as well as any edges that depend on it.

<center> <img src="docs/imgs/hiding_node.gif"> </center>

Running Mutators

Right clicking on a node exposes a context menu that allows you to run graph mutators. Mutators are functions which take the graph state, and return a new state.

Two extremely useful mutators are:

  1. Backtracking a node: Find the sequence of nodes and edges that led to the creation of this node.
    • Backtracking a process node will show its process tree.
  2. Expanding all descendants: From the current node, show every node that has this node as an ancestor.
    • Expanding a process node will show every child process node it spawned, any file it may have touched, and pretty much every activity that happened as a result of this node.
Backtracking a node

Backtracking a node is extremely useful and is similar to doing a root cause infection in log files.

<center> <img src="docs/imgs/backtrack_node.gif"> </center>
Expanding Node Descendants

Expanding a node's descendants allows you to immediately view everything that happened because of this node. This action reveals the subgraph rooted at the selected node.

<center> <img src="docs/imgs/expand_descendants_node.gif"> </center>

Toggling Node and Edge Types

Sometimes, a Node or Edge

View on GitHub
GitHub Stars1.3k
CategoryDevelopment
Updated13d ago
Forks148

Languages

Python

Security Score

100/100

Audited on Mar 7, 2026

No findings