# Technical Documentation: google/grr

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/google/grr)

### Overview (`README.md`)

<p align="center">
<img src="https://raw.githubusercontent.com/google/grr/gh-pages/img/grr_logo_real_sm.png" />

<p align="center">
GRR Rapid Response is an incident response framework focused on remote live forensics.

[](https://github.com/google/grr/actions/workflows/build.yml)

GRR is a python client (agent) that is installed on target systems, and
python server infrastructure that can manage and talk to clients.<br>


Documentation
-------------

Please visit our [documentation website](https://grr-doc.readthedocs.io/) if you want to know more about GRR.


Contact Us
----------

* GitHub issues: [github.com/google/grr/issues](https://github.com/google/grr/issues)
* GRR Users mailing list: [grr-users](https://groups.google.com/forum/#!forum/grr-users)
* Follow us [on twitter](https://twitter.com/grrresponse) for announcements of GRR user meetups. We use [a gitter chat room](https://gitter.im/google/grr) during meetups.


Screenshots
-----------
[<img src="https://github.com/google/grr/blob/gh-pages/screenshots/endpoint-overview.png" width="330">](https://github.com/google/grr/blob/gh-pages/screenshots/endpoint-overview.png)
[<img src="https://github.com/google/grr/blob/gh-pages/screenshots/filesystem-overview.png" width="330">](https://github.com/google/grr/blob/gh-pages/screenshots/filesystem-overview.png)
[<img src="https://github.com/google/grr/blob/gh-pages/screenshots/workflow-results.png" width="330">](https://github.com/google/grr/blob/gh-pages/screenshots/workflow-results.png)

---

### Overview (`api_client/python/README.md`)

# GRR API client library

GRR API client library provides an easy way to talk to GRR AdminUI server to
fetch data or trigger actions. It can be used for GRR scripting and automation.

## Installation

To install the latest release version from PIP:

```bash
pip install grr-api-client
```

To install the latest dev version from source:

```bash
sudo apt-get install -y \
  protobuf-compiler \
  python-dev \
  python-pip

sudo pip install --upgrade pip
sudo pip install virtualenv

git clone https://github.com/google/grr.git
virtualenv GRR_NEW
source GRR_NEW/bin/activate

cd grr/api_client/python
pip install --editable .
```

## Initializing the GRR API object

```python
from grr_api_client import api
grrapi = api.InitHttp(api_endpoint="http://localhost:1234",
                      auth=("user", "pwd"))
```

This creates a root GRR API object that will connect to the
"http://localhost:1234" HTTP API endpoint. This URL should be the same with
GRR's AdminUI URL.

GRR API library uses [requests](http://docs.python-requests.org/en/master/)
library under the hood. The *auth* argument is passed verbatim to the *requests*
library. In the example above the `("user", "pwd")` value will force the
requests library to do HTTP Basic authentication with user name "user" and
password "pwd".

In case your GRR AdminUI server is configured to use any other authentication
scheme, any authentication method [supported by requests
library](http://docs.python-requests.org/en/master/user/authentication/) can be
used (or [custom one can be
implemented](http://docs.python-requests.org/en/master/user/advanced/#custom-authentication)).

## Example: Collect client IDs for a given hostname

```python
from grr_api_client import api
grrapi = api.InitHttp(api_endpoint="http://localhost:1234",
                      auth=("user", "pwd"))

search_result = grrapi.SearchClients("host:suspicious.corp.com")
result = {}
for client in search_result:
  client_id = client.client_id
  client_last_seen_at = client.data.last_seen_at
  result[client_id] = client_last_seen_at
print(result)
```

## Example: add *"suspicious"* label to all clients with a given hostname

```python
from grr_api_client import api
grrapi = api.InitHttp(api_endpoint="http://localhost:1234",
                      auth=("user", "pwd"))

search_result = grrapi.SearchClients("host:suspicious.corp.com")
for client in search_result:
  client.AddLabels(["suspicious"])
```

## Example: start a FileFinder hunt

*flow_args* and *hunt_runner_args* below are protobufs (see Protobuf library
[docs](https://developers.google.com/protocol-buffers/docs/pythontutorial)). See
definitions of
[FileFinderArgs](https://github.com/google/grr/blob/7cdf490f9be2ccc0a8160c9b8ae23b73922049d5/grr/proto/flows.proto#L1626),
[HuntRunnerArgs](https://github.com/google/grr/blob/7cdf490f9be2ccc0a8160c9b8ae23b73922049d5/grr/proto/flows.proto#L286),
[ForemanClientRuleSet](https://github.com/google/grr/blob/a103753a065f14f77b0df841e224777797f870d8/grr/proto/jobs.proto#L1471).

```python
from grr_api_client import api
grrapi = api.InitHttp(api_endpoint="http://localhost:1234",
                      auth=("user", "pwd"))

# Initialize args protobuf for a FileFinder flow: FileFinderArgs.
flow_args = grrapi.types.CreateFlowArgs("FileFinder")
# FileFinderArgs.paths gets initialized with an example value,
# we should get rid of it.
flow_args.ClearField("paths")
flow_args.paths.append("/var/log/*")
flow_args.action.action_type = flow_args.action.DOWNLOAD

# Initialize hunt runner args.
hunt_runner_args = grrapi.types.CreateHuntRunnerArgs()
rule = hunt_runner_args.client_rule_set.rules.add()
rule.rule_type = rule.LABEL
rule.label.label_names.append("suspicious")

# Create a hunt and start it.
hunt = grrapi.CreateHunt(flow_name="FileFinder", flow_args=flow_args,
                         hunt_runner_args=hunt_runner_args)
hunt = hunt.Start()
```

## Using command line API shell

*grr_api_shell* command provides an IPython shell with a preinitialized *grrapi*
object (it's installed as part of grr-api-client PIP package).

```
/* Detailed source-code truncated for AI context efficiency. */
```

## API shell command line one-liners

*grr_api_shell* tool can be used for command line one-liners.

Print client IDs of all the clients known to GRR:

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'print("\n".join(c.client_id for c in grrapi.SearchClients("")))' \
  http://localhost:1234
```

Write all the files downloaded by a specific flow into the "flow_results.zip"
file:

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'grrapi.Client("C.1234567890ABCDEF").Flow("F:BB628B23").GetFilesArchive().WriteToFile("./flow_results.zip")' \
  http://localhost:1234
```

Download an archive of files collected from a GRR client that are stored in
*/fs/os/var/log/* VFS folder:

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'grrapi.Client("C.1234567890ABCDEF").File("/fs/os/var/log").GetFilesArchive().WriteToFile("./all_client_files.zip")' \
  http://localhost:1234
```

Download a single file collected from a GRR client (helpful for large files
\> 4GB that can't be added to an archive):

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'grrapi.Client("C.1234567890ABCDEF").File("/fs/os/var/log/syslog").GetBlob().WriteToFile("./syslog")' \
  http://localhost:1234
```

Decode a Crowdstrike encoded file that was fetched via GetBlob:

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'grrapi.Client("C.1234567890ABCDEF").File("/fs/os/var/encrypted/file").GetBlob().DecodeCrowdStrikeQuarantineEncoding().WriteToFile("./decoded.file")' \
  http://localhost:1234
```


Download an archive of all files collected with OS-handler (not TSK/NTFS) from a
GRR client:

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'grrapi.Client("C.1234567890ABCDEF").File("/fs/os").
  GetFilesArchive().WriteToFile("./all_client_files.zip")' \
  http://localhost:1234
```

Print all results of a particular flow in a text-protobuf format:

```bash
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'for r in grrapi.Client("C.1234567890ABCDEF").Flow("F:BB628B23").ListResults(): print(str(r.payload))' \
  http://localhost:1234
```

Decrypt a file from a Collect Large File flow:

```bash
cat encrypted_file | \
grr_api_shell --basic_auth_username "user" --basic_auth_password "pwd" \
  --exec_code 'grrapi.Client("C.1234567890ABCDEF").Flow("F:BB628B23").Get().DecryptLargeFile()' \
  http://localhost:1234 > decrypted_file
```

---

### Overview (`grr/artifacts/README.md`)

# This directory is reserved for external artifacts

The Makefile removes ``*.yaml`` from this directory when syncing the external
repo located [here] (https://github.com/ForensicArtifacts/artifacts).

## Where artifacts go

- Private artifacts should go in ``artifacts/local``
- Public artifacts that are non GRR specific should be submitted to the external
repo.
- Public artifacts that call GRR functions with ``LIST_FILES``,
  ``GRR_CLIENT_ACTION``, ``GREP`` etc. should live in
  ``artifacts/flow_templates``

---

### Overview (`monitoring/grafana/README.md`)

The module `grr-grafanalib-dashboards` contains sample [Grafana dashboards](https://grafana.com/docs/grafana/latest/features/dashboard/dashboards/)
written using [grafanalib](https://github.com/weaveworks/grafanalib),
that will help you get started quickly introducing monitoring capabilities to your GRR server.

Quick Start
-----------
Before generating the dashboards on your own, note that you can find the sample
dashboard in importable JSON format inside the folder
`grr/monitoring/grafana/grr_grafanalib_dashboards/dashboards_for_use`. From
there you can import the sample dashboards without re-generating them to your
Grafana instance. Follow the instructions below if you want to rebuild or
customize the dashboards.

**Please note the following edge case**: the panel "API Calls Count Rate by other statuses (not
  SUCCESS)" inside the AdminUI dashboard will *not* show a spike in the graph
  when there is only one data point present (only a single API call of a given
  method was made), where the status of the call is not SUCCESS.
  This is due to the way Prometheus' function [rate()](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) works.

First, make sure to activate the virtual environment of your GRR installation (if you use one), and have Grafana and [Prometheus](https://prometheus.io/docs/prometheus/latest/getting_started/#starting-prometheus)
running on your GRR deployment. To run Prometheus and Grafana with GRR, check out the [monitoring section](https://grr-doc.readthedocs.io/en/latest/maintaining-and-tuning/monitoring.html)
of the documentation.
Then, go to the grafana directory using `cd grr/moniroing/grafana`.
Now use `pip install .` to install the grr-grafanalib-module package. This will install `grafanalib` to your environment as well.

You can now visit the given sample dashboards by browsing to `cd grr_grafanalib_dashboards/dashboards_to_generate`.
This folder will contain all the individual dashboards for each GRR server component. In order to generate these dashboards
to a format that is importable by a Grafana instance, run `generate-dashboards <grr_component_name>.dashboard.py`,
for example: `generate-dashboards frontends.dashboard.py`.
After running this command, new files will be created in the folder with the names `<grr_component_name>.json`. This
JSON file can be imported to your Grafana instance by browsing to the [Import](http://localhost:3000/dashboard/import) page,
clicking the button "Upload .json file" and proceeding with the instructions.

Please note that these dashboards are not exhausitve (by design) as your use case might be unique to you and your GRR
deployment's needs. Use these as general guidelines on how to implement your own dashboards from scratch,
or rather extend these dashboards by introducing new metrics, graphs, alerts etc and fitting them to your individual scenario.

---

### Overview (`grr/artifacts/flow_templates/README.md`)

# Flow Templates: GRR specific 'artifacts'

These 'artifacts' are separate from the main repository because they don't
describe digital forensic artifacts, instead they provide a way to call
pre-defined GRR flows from YAML, the working name for which is 'flow templates'.

---

### Overview (`terraform/demo/google/README.md`)

# Using Terraform to deploy demo GRR setup on Google Cloud

## Installing Terraform

Please follow [these
instructions](https://www.terraform.io/intro/getting-started/install.html) to
install Terraform binary on your machine.

## Setting up a Google Cloud Project

1.  Create a new project in GCP console
    ([link](https://console.cloud.google.com/project)). Let's assume it's called
    "grr-terraform-demo".
1.  Enable billing for the project
    ([link](https://support.google.com/cloud/answer/6293499#enable-billing)).
1.  Enable Compute Engine and Cloud SQL APIs
    ([link](https://console.cloud.google.com/flows/enableapi?apiid=compute_component,sqladmin)).

## Instrumenting Terraform with credentials

1.  In Cloud Platform Console, navigate to the [Create service account
    key](https://console.cloud.google.com/apis/credentials/serviceaccountkey)
    page.
1.  From the Service account dropdown, select Compute Engine default service
    account, and leave JSON selected as the key type.
1.  Click Create, which downloads your credentials as a file named
    `[PROJECT_ID]-[UNIQUE_ID].json`.
1.  In the same shell where you're going to run Terraform (see below), run the
    following:

```bash
export GCLOUD_KEYFILE_JSON=/absolute/path/to/downloaded-file.json
```

## Running Terraform

`cd` to the folder with Terraform configuration files (and where this README
file is).

If it's the first time you run Terraform with this set of configuration files,
run:

```bash
terraform init
```

Then run (`grr-terraform-demo` is the name of a project that you've previously
set up):

```bash
terraform apply -var 'gce_project=grr-terraform-demo'
```

Run the following to get the URL of a newly deployed GRR AdminUI:

```bash
terraform output
```

Tip: you can use Terraform variables to specify the number of generated
Windows and Linux clients:

```bash
terraform apply -var 'gce_project=grr-terraform-demo' -var 'windows_client_count=4' -var 'linux_client_count=3'
```

---

### Overview (`grr/core/grr_response_core/artifacts/README.md`)

# This directory is reserved for external artifacts

The Makefile removes `*.yaml` from this directory when syncing the external repo
located [here](https://github.com/ForensicArtifacts/artifacts).

## Where artifacts go

-   Private artifacts should go in `artifacts/local`.
-   Public artifacts that are non GRR specific should be submitted to the
    external repo.

---

### Overview (`grr/server/grr_response_server/gui/ui/README.md`)

# Frontend

## Development server

First make sure `grr_admin_ui` is up and running.

Run `ng serve` (or `ng s`) for a dev server. Navigate to
`http://localhost:4200/`. The app will automatically reload if you change any of
the source files.

## Running unit tests

Run `ng test` (or `ng t`) to execute the unit tests. The test will automatically
reload if you change any of the source files.

## Further help

To get more help on the Angular CLI use `ng help` or go check out the
[Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

---

### Overview (`grr/server/grr_response_server/gui/ui/components/shared/flow_args_form/osquery_query_helper/osquery_raw_table_specs.README.md`)

The `osquery_raw_table_specs.*` file holds osquery's table specification as a
single object.

It was generated using a
[script](https://github.com/osquery/osquery/blob/4.5.1/tools/codegen/genwebsitejson.py)
and [osquery table specifications](https://github.com/osquery/osquery/tree/4.5.1/specs),
both taken from the
[open-source osquery repository](https://github.com/osquery/osquery).

High-level instructions for regenerating the file (and updating the
specifications to next osquery versions):
1. Clone the osquery repository
2. Run the script for generating table specifications, pointing it to the
directory with the table specifications. You might need to find a way around
import errors. Save its output to a file.
3. The script produces JSON, but the code requires this data to be in a
typescript `.ts` file. It should suffice to just prefix the output of the script
with something like: `export const tableSpecs451 = ...old json data...`.
4. Update the import statements which use the table specifications inside the
grr codebase. At the moment of writing this, it is only the file
`grr/server/grr_response_server/gui/ui/components/flow_args_form/osquery_query_helper/osquery_table_specs.ts`.
Make sure that the tests run, there are no import errors, and the model of the
data is the same as before (or it is adapted appropriately).

---

--- METRICS ---
- Files Extracted: 9
- Estimated Token Budget: ~4213 tokens
- Canonical Reference: https://codewiki.google/github.com/google/grr
