Skip to content

Commit

Permalink
feat(cmd/flags)!: split filter flag
Browse files Browse the repository at this point in the history
This commit splits the '--filter' flag into two new flags: '--scope' and
'--events'.

The '--scope' flag is used to specify the scope of the events to be
captured like 'comm', 'binary', 'pid', 'uid', 'mntns', 'pidns', 'uts',
'tree', 'follow' and 'container', while the '--events' flag is used to
specify the events and their userland filters like 'args', 'retval' and
'context'.

It also removes the set option previously available for the '--filter'
flag, as it is no longer needed. The '--events' flag is now used to
specify the sets of events to be captured, e.g. '--events fs'.

Other chores:

- analyze '--event' flag now is '--events', to be consistent.
- polcy_file.go validateContext() is removed since we have similar
  validation in further stages.
- Relocates unit tests from flags_test.go to respective new correlated
  files, making it easier to maintain and extend and changes integration
  tests to use PolicyFile instead of Policy.

BREAKING CHANGE: '--filter' flag is now replaced by '--scope' and
'--events' flags and analyze '--event' flag is now '--events'.

Co-authored-by: Yaniv Agman <yanivagman@gmail.com>
  • Loading branch information
geyslan and yanivagman committed Jul 10, 2023
1 parent 068f5ee commit 3429c8e
Show file tree
Hide file tree
Showing 61 changed files with 4,115 additions and 2,743 deletions.
11 changes: 8 additions & 3 deletions cmd/tracee-ebpf/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ func main() {
Usage: "list traceable events",
},
&cli.StringSliceFlag{
Name: "filter",
Aliases: []string{"f"},
Name: "scope",
Aliases: []string{"s"},
Value: nil,
Usage: "select events to trace by defining filter expressions. run '--filter help' for more info.",
Usage: "select workloads to trace by defining filter expressions. run '--scope help' for more info.",
},
&cli.StringSliceFlag{
Name: "events",
Aliases: []string{"e"},
Usage: "select events to trace and filter events. run '--events help' for more info.",
},
&cli.StringSliceFlag{
Name: "capture",
Expand Down
43 changes: 24 additions & 19 deletions cmd/tracee/cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,45 @@ func init() {

// events
analyze.Flags().StringArrayP(
"event",
"events",
"e",
[]string{},
"Define which signature events to load",
)
err := viper.BindPFlag("event", analyze.Flags().Lookup("event"))
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}

// TODO: decide if we want to bind this flag to viper, since we already have a similar
// flag in rootCmd, conflicting with each other.
// The same goes for the other flags (signatures-dir, rego), also in rootCmd.
//
// err := viper.BindPFlag("events", analyze.Flags().Lookup("events"))
// if err != nil {
// fmt.Fprintf(os.Stderr, "Error: %s\n", err)
// os.Exit(1)
// }

// signatures-dir
analyze.Flags().StringArray(
"signatures-dir",
[]string{},
"Directory where to search for signatures in CEL (.yaml), OPA (.rego), and Go plugin (.so) formats",
)
err = viper.BindPFlag("signatures-dir", analyze.Flags().Lookup("signatures-dir"))
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
// err = viper.BindPFlag("signatures-dir", analyze.Flags().Lookup("signatures-dir"))
// if err != nil {
// fmt.Fprintf(os.Stderr, "Error: %s\n", err)
// os.Exit(1)
// }

// rego
analyze.Flags().StringArray(
"rego",
[]string{},
"Control event rego settings",
)
err = viper.BindPFlag("rego", analyze.Flags().Lookup("rego"))
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
// err = viper.BindPFlag("rego", analyze.Flags().Lookup("rego"))
// if err != nil {
// fmt.Fprintf(os.Stderr, "Error: %s\n", err)
// os.Exit(1)
// }
}

var analyze = &cobra.Command{
Expand All @@ -96,8 +101,8 @@ var analyze = &cobra.Command{
Tracee can be used to collect events and store it in a file. This file can be used as input to analyze.
eg:
tracee --filter event=ptrace --output=json:events.json
tracee analyze --event=anti_debugging events.json`,
tracee --events ptrace --output=json:events.json
tracee analyze --events anti_debugging events.json`,
Run: func(cmd *cobra.Command, args []string) {
inputFile, err := os.Open(args[0])
if err != nil {
Expand All @@ -113,7 +118,7 @@ tracee analyze --event=anti_debugging events.json`,

// Signature directory command line flags

signatureEvents := viper.GetStringSlice("event")
signatureEvents := viper.GetStringSlice("events")
// if no event was passed, load all events
if len(signatureEvents) == 0 {
signatureEvents = nil
Expand Down
18 changes: 13 additions & 5 deletions cmd/tracee/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,22 @@ func initCmd() error {
hfFallback(cmd, args)
})

// Filter/Policy flags
// Scope/Event/Policy flags

// filter is not bound to viper
// scope is not bound to viper
rootCmd.Flags().StringArrayP(
"filter",
"f",
"scope",
"s",
[]string{},
"Select events to trace by defining filter expressions",
"Select workloads to trace by defining filter expressions",
)

// events is not bound to viper
rootCmd.Flags().StringArrayP(
"events",
"e",
[]string{},
"Select events to trace and event filters",
)

// policy is not bound to viper
Expand Down
12 changes: 6 additions & 6 deletions docs/contributing/building/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
make tracee
sudo ./dist/tracee \
-o option:parse-arguments \
--filter comm=bash \
--filter follow
--scope comm=bash \
--scope follow
```

Now, in your host's bash shell, execute a command. You will see all events
Expand All @@ -55,8 +55,8 @@
sudo ./dist/tracee \
-o format:json \
-o option:parse-arguments \
--filter comm=bash \
--filter follow
--scope comm=bash \
--scope follow
```

Now, in your host's bash shell, execute: `sudo strace /bin/ls` and observe
Expand Down Expand Up @@ -134,8 +134,8 @@ And, after the compilation, run the commands directly in your host:
```console
sudo ./dist/tracee \
-o option:parse-arguments \
--filter comm=bash \
--filter follow
--scope comm=bash \
--scope follow
```

> **Note**: the generated binary must be compatible to your host (depending on
Expand Down
7 changes: 1 addition & 6 deletions docs/docs/config/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,7 @@ log:
## Reserved Flags
There are a few flags that are reserved for the CLI and cannot be set through the configuration file. These include:
- `--config`: This flag is used to specify the configuration file, so it cannot be set through the configuration file itself.
- `--capture`: This flag is used to specify which events should be captured by Tracee, so it cannot be set through the configuration file.
- `--policy`: This flag is used to specify a policy file for Tracee, so it cannot be set through the configuration file.
- `--filter `: This flag is used to specify an event filter for Tracee via CLI and via policy file loading mechanism (the --policy flag), so it cannot be set through the configuration file.
The CLI flags that cannot be configured via the configuration file are `--config`, `--capture`, `--policy`, `--scope`, and `--event`.

## Example Configuration Files

Expand Down
5 changes: 4 additions & 1 deletion docs/docs/events/builtin/extra/bpf_attach.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ kprobe
get information about which helper functions are used by the BPF program

## Example Use Case
./tracee -f e=bpf_attach

```console
./tracee -e bpf_attach
```

## Issues

Expand Down
5 changes: 4 additions & 1 deletion docs/docs/events/builtin/extra/file_modification.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ kprobe + kretprobe
Catch the file ctime change and submit the event if marked to be submitted

## Example Use Case
./tracee -f e=file_modification

```console
./tracee -e file_modification
```

## Note
Only the first event of file modification is submitted between the open and the close of a file by a process.
Expand Down
5 changes: 4 additions & 1 deletion docs/docs/events/builtin/extra/hidden_kernel_module.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ It periodically checks for a hidden module.
Self-triggered hook by uprobing itself.

## Example Use Case
./tracee -f e=hidden_kernel_module

```console
./tracee -e hidden_kernel_module
```

## Issues

Expand Down
4 changes: 3 additions & 1 deletion docs/docs/events/builtin/extra/hooked_syscalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ Detection of syscall hooking.
The `hooked_syscalls` event could be used as part of a broader system integrity monitoring solution. For example, a security engineer could use it to raise alerts or run further investigations if unexpected syscall hooking activities are detected. This could aid in the early detection and mitigation of malware or rootkit infections.
Example:

`tracee -f e=hooked_syscalls -f hooked_syscalls.args.check_syscalls=<syscall>,<syscall>,...`
```console
tracee -e hooked_syscalls.args.check_syscalls=<syscall>,<syscall>,...`
```

## Issues
The `check_syscalls` argument is used as a parameter to specify the syscalls to be checked. This will change in the future to be an event parameter.
Expand Down
5 changes: 4 additions & 1 deletion docs/docs/events/builtin/extra/kallsyms_lookup_name.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ kprobe + kretprobe
tracing the kallsyms_lookup_name event

## Example Use Case
`./dist/tracee -f e=kallsyms_lookup_name`

```console
./dist/tracee -e kallsyms_lookup_name
```
5 changes: 4 additions & 1 deletion docs/docs/events/builtin/extra/process_execute_failed.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ kretprobe
Fetch the return value of exec_binprm

## Example Use Case
./tracee -f e=process_execution_failed

```console
./tracee -e process_execution_failed
```

## Issues
Currently, only covers failed executions that are happening within exec_binprm. Other failures may occur at an earlier stage.
Expand Down
5 changes: 4 additions & 1 deletion docs/docs/events/builtin/extra/security_bpf_prog.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ kprobe
get information about which helper functions are used by the BPF program

## Example Use Case
./tracee -f e=security_bpf_prog

```console
./tracee -e security_bpf_prog
```

## Issues

Expand Down
6 changes: 3 additions & 3 deletions docs/docs/events/builtin/extra/symbols_collision.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Also, used to maintain the cache used by the event for performance improvement.
Could be used for example to catch collision between a shared object and `libc.so`, overwriting libc symbols:

```console
./dist/tracee -f e=symbols_collision -f symbols_collision.args.loaded_path=/usr/lib/libc.so.6
./dist/tracee -e symbols_collision.args.loaded_path=/usr/lib/libc.so.6
```

Running this line will give a lot of spam symbols collision, for example collisions of `libc` with `libm`:
Expand All @@ -48,13 +48,13 @@ To reduce the spam collisions, we can configure the event to not print the colli
1. Whitelist the collided symbols:

```console
./dist/tracee -f e=symbols_collision -f symbols_collision.args.loaded_path=/usr/lib/libc.so.6 -f symbols_collision.args.symbols!=finitel,__signbitf,finite,frexpl,frexp,scalbn,__finite,copysignl,scalbnf,__signbitl,scalbnl,copysign,copysignf,ldexpf,modff,modf,ldexp,ldexpl,finitef,frexpf,__finitel,modfl,__finitef,__signbit
./dist/tracee -e symbols_collision.args.loaded_path=/usr/lib/libc.so.6 -e symbols_collision.args.symbols!=finitel,__signbitf,finite,frexpl,frexp,scalbn,__finite,copysignl,scalbnf,__signbitl,scalbnl,copysign,copysignf,ldexpf,modff,modf,ldexp,ldexpl,finitef,frexpf,__finitel,modfl,__finitef,__signbit
```

2. Whitelist the library `libm`:

```console
./dist/tracee -f e=symbols_collision -f symbols_collision.args.loaded_path=/usr/lib/libc.so.6 -f symbols_collision.args.collision_path!=/usr/lib/libm.so.6
./dist/tracee -e symbols_collision.args.loaded_path=/usr/lib/libc.so.6 -e symbols_collision.args.collision_path!=/usr/lib/libm.so.6
```

The first approach is recommended when dealing with common symbols like 'setup_', 'finish_' etc. because it will reduce
Expand Down
4 changes: 3 additions & 1 deletion docs/docs/events/builtin/extra/symbols_loaded.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ Used by tracee to maintain mount NS cache, used in this event to get to processe
To catch SO which tries to override the `fopen` function of `libc`, we can use the event in
the following way:

`./dist/tracee -f e=symbols_loaded -f symbols_loaded.args.symbols=fopen symbols_loaded.args.library_path!=libc`
```console
./dist/tracee -e symbols_loaded.args.symbols=fopen -e symbols_loaded.args.library_path!=libc
```

## Issues
Because the event is implemented in user-mode, it needs to open and read files.
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/events/builtin/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Tracee offers a set of network events that makes it easy to trace network activi
Trace all TCP packets sent to port 80 anywhere, from any process:

```console
tracee --output json --filter event=net_packet_tcp --filter net_packet_tcp.args.dst_port=80
tracee --output json --events net_packet_tcp.args.dst_port=80
```

```json
Expand All @@ -187,7 +187,7 @@ tracee --output json --filter event=net_packet_tcp --filter net_packet_tcp.args.
Trace all DNS packets received ONLY from Google DNS server '8.8.8.8':

```console
tracee --output json --filter event=net_packet_dns --filter net_packet_dns.args.src=8.8.8.8
tracee --output json --events net_packet_dns.args.src=8.8.8.8
```

(only **systemd-resolved**, since all the other processes are resolving using local systemd-resolved server `127.0.1.1:53`):
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/events/custom/analyze.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ The tracee subcommand `analyze` allows you to execute behavior signatures on pas
For example, you can collect the ptrace event into one node using the following command:

```
tracee --filter event=ptrace --output=json:events.json
tracee events=ptrace --output=json:events.json
```

Then, on another node, you can check if the behavior signature for anti-debugging was triggered using the following command:

```
tracee analyze --event=anti_debugging events.json
tracee analyze --events=anti_debugging events.json
```

The `analyze` command can also be used to test new signatures from the collected past data. You can run tracee on a node, collect several events, and based on the collected events, create your behavior signature. Afterward, you can test if the signature would be triggered using the `analyze` command.
2 changes: 1 addition & 1 deletion docs/docs/events/custom/golang.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ There are 2 ways you can get your own golang signatures working with tracee.
```console
sudo ./dist/tracee \
--output json \
--filter event=mine
--events mine
```

```json
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/events/custom/rego.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ what you want:
sudo ./dist/tracee \
--output json
--signatures-dir signatures/rego \
--filter event=mine
--events mine
```

```json
Expand Down
12 changes: 6 additions & 6 deletions docs/docs/events/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ eg:

Tracing `execve` events with [filters]:

```
tracee --filter event=execve
```console
tracee --events execve
```

Tracing `execve` events with [policies]:
Expand Down Expand Up @@ -116,13 +116,13 @@ net_packet_http_response | [default network_events] |
Events can be part of a set, for example on the table above we can see a few sets like `default`, `network_events`, `syscalls`.
We can ask tracee to trace a full set, or sets, instead of passing event by event, for example:

```
tracee --filter set=syscalls
```console
tracee --events syscalls
```
or

```
tracee --filter set=syscalls,network_events
```console
tracee --events syscalls,network_events
```


Expand Down
Loading

0 comments on commit 3429c8e

Please sign in to comment.