Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ After creating the webhook, you will be provided with a geo-dependent URL, respe
* Python SDK:

```python
python3 -c "import limacharlie; print(limacharlie.Manager().getOrgURLs()['hooks'])"
python3 -c "from limacharlie.client import Client; from limacharlie.sdk.organization import Organization; print(Organization(Client()).get_urls()['hooks'])"
```

## Using the webhook adapter
Expand Down
13 changes: 9 additions & 4 deletions docs/2-sensors-deployment/endpoint-agent/uninstallation.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ On Windows, the command defaults to uninstalling the sensor as if installed from
To run the uninstall command against *all* Sensors, a simple loop with the SDK in Python would work:

```python
import limacharlie
lc = limacharlie.Manager()
for sensor in lc.sensors():
sensor.task( 'uninstall' )
from limacharlie.client import Client
from limacharlie.sdk.organization import Organization
from limacharlie.sdk.sensor import Sensor

client = Client()
org = Organization(client)
for sensor_info in org.list_sensors():
sensor = Sensor(org, sensor_info["sid"])
sensor.task("uninstall")
```

### Using a D&R Rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ A common request is to alert an administrator if a Sensor that normally forwards
## Example Playbook Code

```python
import limacharlie
import time
from limacharlie.sdk.organization import Organization
from limacharlie.sdk.sensor import Sensor

# LimaCharlie D&R Rule to trigger this playbook
# every 30 minutes.
Expand All @@ -28,19 +29,19 @@ import time
SENSOR_SELECTOR = "plat == windows and `server` in tags"
DATA_WITHIN = 10 * 60 * 1000 # 10 minutes

def notify_missing_data(sdk: limacharlie.Limacharlie, sensor: limacharlie.Sensor):
def notify_missing_data(sdk: Organization, sensor: Sensor):
# TODO: Implement this, but it's optional if all you want is a detection
# since those will be generated automatically.
pass

def get_relevant_sensors(sdk: limacharlie.Limacharlie) -> list[limacharlie.Sensor]:
sensors = sdk.sensors(selector=SENSOR_SELECTOR)
def get_relevant_sensors(sdk: Organization) -> list[Sensor]:
sensors = sdk.list_sensors(selector=SENSOR_SELECTOR)
relevant_sensors = []
for sensor in sensors:
relevant_sensors.append(sensor)
for sensor_info in sensors:
relevant_sensors.append(Sensor(sdk, sensor_info["sid"]))
return relevant_sensors

def playbook(sdk: limacharlie.Limacharlie, data: dict) -> dict | None:
def playbook(sdk: Organization, data: dict) -> dict | None:
# Get the sensors we care about.
relevant_sensors = get_relevant_sensors(sdk)

Expand All @@ -49,7 +50,7 @@ def playbook(sdk: limacharlie.Limacharlie, data: dict) -> dict | None:
# For each sensor, check if we've received data within that time period.
for sensor in relevant_sensors:
# To do that we will get the data overview and see if a recent time stamp is present.
data_overview = sensor.getHistoricOverview(int(time.time() - DATA_WITHIN), int(time.time()))
data_overview = sensor.get_overview(int(time.time() - DATA_WITHIN), int(time.time()))
after = int(time.time() * 1000) - DATA_WITHIN
for timestamp in data_overview:
if timestamp > after:
Expand Down
20 changes: 13 additions & 7 deletions docs/3-detection-response/tutorials/writing-testing-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ The Organization ID (OID) identifies uniquely your organization while the API ke

### Login to the CLI

Back in your terminal, log in with your credentials: `limacharlie login`.
Back in your terminal, log in with your credentials: `limacharlie auth login`.

1. When asked for the Organization ID, paste your OID from the previous step.
2. When asked for a name for this access, you can leave it blank to set the default credentials.
Expand Down Expand Up @@ -264,7 +264,9 @@ respond:
name: T1196
```

Now validate: `limacharlie replay --validate --rule-content T1196.rule`
Now validate the rule structure. Save the detect and respond components to separate files (`T1196_detect.yaml` and `T1196_respond.yaml`), then run:

`limacharlie dr validate --detect T1196_detect.yaml --respond T1196_respond.yaml`

After a few seconds, you should see a response with `success: true` if the rule
validates properly.
Expand Down Expand Up @@ -312,7 +314,7 @@ should still NOT match because it's not a `.cpl`.

Now we can run our 3 samples against the rule using Replay,

`limacharlie replay --rule-content T1196.rule --events positive.json` should output a result
`limacharlie dr test --input-file T1196.rule --events positive.json` should output a result
indicating the event matched (by actioning the `report`) like:

```json
Expand All @@ -328,7 +330,7 @@ indicating the event matched (by actioning the `report`) like:
...
```

`limacharlie replay --rule-content T1196.rule --events negative-1.json` should output a result
`limacharlie dr test --input-file T1196.rule --events negative-1.json` should output a result
indicating the event did NOT match like:

```json
Expand All @@ -341,7 +343,7 @@ indicating the event did NOT match like:
}
```

`limacharlie replay --rule-content T1196.rule --events negative-2.json` be the same as `negative-1.json`.
`limacharlie dr test --input-file T1196.rule --events negative-2.json` be the same as `negative-1.json`.

### Testing Historical Data

Expand All @@ -353,7 +355,11 @@ costs associated.

Running our rule against the last week of data is simple:

`limacharlie replay --rule-content T1196.rule --entire-org --last-seconds 604800`
```bash
START=$(date -d '7 days ago' +%s)
END=$(date +%s)
limacharlie replay run --detect-file T1196_detect.yaml --respond-file T1196_respond.yaml --start $START --end $END
```

No matches should look like that:

Expand All @@ -375,5 +381,5 @@ Once your rule is done and you've evaluated various events for matches, you can

Now is the time to push the new rule to production, the easy part.

Simply run `limacharlie dr add --rule-name T1196 --rule-file T1196.rule`
Simply run `limacharlie dr set --key T1196 --input-file T1196.rule`
and confirm it is operational by running `limacharlie dr list`.
2 changes: 1 addition & 1 deletion docs/4-data-queries/query-cli.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Query with CLI

The command line interface found in the Python CLI/SDK can be invoked like `limacharlie query` once installed (`pip install limacharlie`).
The command line interface found in the Python CLI/SDK can be invoked like `limacharlie search` once installed (`pip install limacharlie`).

## Context

Expand Down
13 changes: 7 additions & 6 deletions docs/5-integrations/extensions/labs/ai-agent-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,14 @@ Here is an example D&R rule starting a new invocation of a playbook.
### Python example

```python
# Import LC SDK
import limacharlie
import json
# Instantiate the SDK with default creds.
lc = limacharlie.Manager()
# Instantiate the Extension manager object.
ext = limacharlie.Extension(lc)
from limacharlie.client import Client
from limacharlie.sdk.organization import Organization
from limacharlie.sdk.extensions import Extensions

client = Client()
org = Organization(client)
ext = Extensions(org)

# Issue a request to the "ext-ai-agent-engine" extension for the "my-agent-name" agent.
response = ext.request("ext-ai-agent-engine", "start_session", {
Expand Down
31 changes: 17 additions & 14 deletions docs/5-integrations/extensions/labs/playbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ Here is an example D&R rule starting a new invocation of a playbook.
### Python example

```python
# Import LC SDK
import limacharlie
# Instantiate the SDK with default creds.
lc = limacharlie.Manager()
# Instantiate the Extension manager object.
ext = limacharlie.Extension(lc)
from limacharlie.client import Client
from limacharlie.sdk.organization import Organization
from limacharlie.sdk.extensions import Extensions

client = Client()
org = Organization(client)
ext = Extensions(org)

# Issue a request to the "ext-playbook" extension.
response = ext.request("ext-playbook", "run_playbook", {
Expand All @@ -78,7 +79,7 @@ print(response)

A playbook is a normal python script. The only required component is a top level function called `playbook` which takes 2 arguments:

* `sdk`: an instance of the LC Python SDK ( `limacharlie.Manager()` ) pre-authenticated to the relevant Organization based on the credentials provided, if any, `None` otherwise.
* `sdk`: an instance of the LC Python SDK (`Organization` from `limacharlie.sdk.organization`) pre-authenticated to the relevant Organization based on the credentials provided, if any, `None` otherwise.
* `data`: the optional JSON dictionary provided as context to your playbook.

The function must return a dictionary with the following optional keys:
Expand All @@ -95,13 +96,13 @@ This allows your playbook to return information about its execution, return data
The following is a sample playbook that sends a webhook to an external product with a secret stored in LimaCharlie, and it returns the data as the response from the playbook.

```python
import limacharlie
import json
import urllib.request
from limacharlie.sdk.hive import Hive

def playbook(sdk, data):
# Get the secret we need from LimaCharlie.
mySecret = limacharlie.Hive(sdk, "secret").get("my-secret-name").data["secret"]
mySecret = Hive(sdk, "secret").get("my-secret-name").data["secret"]

# Send the Webhook.
request = urllib.request.Request("https://example.com/webhook", data=json.dumps(data).encode('utf-8'), headers={
Expand Down Expand Up @@ -133,7 +134,7 @@ When a playbook generates a detection, you can customize the detection category
The following example checks if a server sensor has missed a check-in and creates a detection with a custom category name:

```python
import limacharlie
from limacharlie.sdk.sensor import Sensor

def playbook(sdk, data):
if not sdk:
Expand All @@ -145,8 +146,9 @@ def playbook(sdk, data):
threshold = 3600 # 1 hour in seconds

missing_sensors = []
for sensor in sdk.sensors():
info = sensor.getInfo()
for sensor_info in sdk.list_sensors():
sensor = Sensor(sdk, sensor_info["sid"])
info = sensor.get_info()
last_seen = info.get('last_seen', 0)
if (current_time - last_seen) > threshold:
missing_sensors.append({
Expand All @@ -169,7 +171,7 @@ def playbook(sdk, data):
return {
"data": {"status": "all sensors checked in"}
}
```python
```

**Important:** The `cat` field must be placed at the **top level** of the return dictionary, alongside `detection`, not inside it. When this playbook creates a detection, it will appear in the Detections UI with the category name "Server-Sensor-Missing-Check-In" instead of the default "playbook-detection".

Expand Down Expand Up @@ -222,12 +224,13 @@ hives:
my-playbook:
data:
python: |-
from limacharlie.sdk.sensor import Sensor
def playbook(sdk, data):
if not sdk:
return {"error": "LC API key required to list sensors"}
return {
"data": {
"sensors": [s.getInfo() for s in sdk.sensors()]
"sensors": [Sensor(sdk, s["sid"]).get_info() for s in sdk.list_sensors()]
}
}
usr_mtd:
Expand Down
4 changes: 2 additions & 2 deletions docs/5-integrations/extensions/using-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ Configurations are a great way of storing rarely-written settings for an Extensi

The structure of the configuration for a given Extension is published by the Extension via its "schema".

Schemas are available through the [Schema API](https://api.limacharlie.io/static/swagger/#/Extension-Schema/getExtensionSchema) or the LimaCharlie CLI: `limacharlie extension get_schema --help`.
Schemas are available through the [Schema API](https://api.limacharlie.io/static/swagger/#/Extension-Schema/getExtensionSchema) or the LimaCharlie CLI: `limacharlie extension schema --help`.

### Requests

Requests are, as the name implies, direct individual requests to an Extension. A request contains an "action" and a "payload" (JSON object) to be sent to the Extension. Some requests can be flagged to have the Extension impersonate the requester (identity and permissions) during execution.

The "action" and "payload" entirely depends on the Extension it is destined to. The list of actions and individual payload structures available for an Extension is documented by each Extension using the "schema" they publish.

Schemas are available through the [Schema API](https://api.limacharlie.io/static/swagger/#/Extension-Schema/getExtensionSchema) or the LimaCharlie CLI: `limacharlie extension get_schema --help`.
Schemas are available through the [Schema API](https://api.limacharlie.io/static/swagger/#/Extension-Schema/getExtensionSchema) or the LimaCharlie CLI: `limacharlie extension schema --help`.

## Interacting

Expand Down
30 changes: 16 additions & 14 deletions docs/5-integrations/services/replay.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The returned data from the API contains the following:

### Query Language

To use Replay in LCQL Mode (LimaCharlie Query Language), you can specify your query in the `query` parameter of the Replay Request (defined below) when using the REST interface, or you can use the LimaCharlie Python SDK/CLI's [query interface](https://github.com/refractionPOINT/python-limacharlie/blob/master/limacharlie/Query.py): `limacharlie query --help`.
To use Replay in LCQL Mode (LimaCharlie Query Language), you can specify your query in the `query` parameter of the Replay Request (defined below) when using the REST interface, or you can use the LimaCharlie Python SDK/CLI's [query interface](https://github.com/refractionPOINT/python-limacharlie/blob/master/limacharlie/Query.py): `limacharlie search --help`.

### Python CLI

Expand All @@ -52,30 +52,32 @@ The [Python CLI](https://github.com/refractionPOINT/python-limacharlie) gives yo
Sample command line to query one sensor:

```
limacharlie-replay --sid 9cbed57a-6d6a-4af0-b881-803a99b177d9 --start 1556568500 --end 1556568600 --rule-content ./test_rule.txt
limacharlie replay run --detect-file ./test_detect.yaml --respond-file ./test_respond.yaml --start 1556568500 --end 1556568600
```

Sample command line to query an entire organization:

```
limacharlie-replay --entire-org --start 1555359000 --end 1556568600 --rule-name my-rule-name
limacharlie replay run --name my-rule-name --start 1555359000 --end 1556568600
```

If specifying a rule as content with the `--rule-content`, the format should be
in `JSON` or `YAML` like:
When specifying a rule via `--detect-file` and `--respond-file`, each file should be in `JSON` or `YAML` format. For example, a detect file:

```yaml
detect:
event: DNS_REQUEST
op: is
path: event/DOMAIN_NAME
value: www.dilbert.com
respond:
- action: report
name: dilbert-is-here
event: DNS_REQUEST
op: is
path: event/DOMAIN_NAME
value: www.dilbert.com
```

Instead of specifying the `--entire-org` or `--sid` flags, you may use events from a local file via the `--events` flag.
And a respond file:

```yaml
- action: report
name: dilbert-is-here
```

Instead of replaying against an entire organization, you may use events from a local file via the `limacharlie dr test` command with the `--events` flag.

We invite you to look at the command line usage itself, as the tool evolves.

Expand Down
Loading
Loading