Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syscall filtering via seccomp for security #5213

Closed
andrewkroh opened this issue Sep 20, 2017 · 9 comments · Fixed by #6832
Closed

Add syscall filtering via seccomp for security #5213

andrewkroh opened this issue Sep 20, 2017 · 9 comments · Fixed by #6832

Comments

@andrewkroh
Copy link
Member

andrewkroh commented Sep 20, 2017

The Beat process on Linux can drop privileges to perform specific syscalls (like execve, fork, clone) using a seccomp-bpf filter. This is one-way operation where the process drops privileges and cannot restore them. This limits the damage that can be done if there ever would be a vulnerability.

There is a kernel version requirement, but we can test if the feature is available use it when possible.

I wrote a POC that uses google/kafel, a C library that generates the BPF syscall filter from a policy string. We could statically link with the library (we already use cgo in our Beats since 6.0).

When there is a policy violation the kernel kills the thread rather than the whole process. When it does this an audit event is generated.

FYI you can use /proc/[pid]/status to see if the process has a seccomp filter applied. Look for the Seccomp: line and a value > 0.

We can audit the syscalls used by a Beat by using strace -c [beat cmd] then develop a policy based on that data.

@andrewkroh
Copy link
Member Author

On a related note, when a seccomp policy is violated an event is sent by Auditbeat. I put a sample into this gist.

@andrewkroh
Copy link
Member Author

I have opened a PR #6832 to add this feature.

adriansr pushed a commit to andrewkroh/beats that referenced this issue May 7, 2018
The adds a default seccomp (Secure Computing) filter on Linux that prohibits execve, execveat, fork, and vfork system calls for the Beat process. The seccomp filter policy is configurable as well. You can create your own whitelist or blacklist policy with specific actions. It uses github.com/elastic/go-seccomp-bpf.

Whitelist Example

```
seccomp:
  default_action: errno
  syscalls:
  - action: allow
    names:
    - open
    - close
    - read
    - exit
```

Blacklist Example

```
seccomp:
  default_action: allow
  syscalls:
  - action: log
    names:
    - execve
    - execveat
    - fork
    - vfork
  - action: kill_process     # Requires kernel 4.14+.
    names:
    - connect
    - accept
    - sendto
    - recvfrom
    - sendmsg
    - recvmsg
    - bind
    - listen
```

Closes elastic#5213

Decisions I Made

- The default policy is a blacklist because it was the most simple to start with. Whitelisting is recommended because it is more robust. `man seccomp` states "A blacklist will have to be updated whenever a potentially dangerous system call is added (or a dangerous flag or option if those are blacklisted), and it is often possible to alter the representation of a value without altering its meaning, leading to a blacklist bypass."

- I chose to not implement argument filtering. It would be useful to have for more granular policies, but I'd rather wait to see how the policies are used and see if argument filtering is required.

- The code only makes use of the `seccomp` syscall to install the filter. It does not fallback to the `prctl(2)` `PR_SET_SECCOMP` operation because it does not support flags. The `SECCOMP_FILTER_FLAG_TSYNC` flag is necessary in Go because we have little control over when threads are started, and there are no guarantees that the filter would be installed before other threads start.
adriansr pushed a commit that referenced this issue May 7, 2018
The adds a default seccomp (Secure Computing) filter on Linux that prohibits execve, execveat, fork, and vfork system calls for the Beat process. The seccomp filter policy is configurable as well. You can create your own whitelist or blacklist policy with specific actions. It uses github.com/elastic/go-seccomp-bpf.

Whitelist Example

```
seccomp:
  default_action: errno
  syscalls:
  - action: allow
    names:
    - open
    - close
    - read
    - exit
```

Blacklist Example

```
seccomp:
  default_action: allow
  syscalls:
  - action: log
    names:
    - execve
    - execveat
    - fork
    - vfork
  - action: kill_process     # Requires kernel 4.14+.
    names:
    - connect
    - accept
    - sendto
    - recvfrom
    - sendmsg
    - recvmsg
    - bind
    - listen
```

Closes #5213

Decisions I Made

- The default policy is a blacklist because it was the most simple to start with. Whitelisting is recommended because it is more robust. `man seccomp` states "A blacklist will have to be updated whenever a potentially dangerous system call is added (or a dangerous flag or option if those are blacklisted), and it is often possible to alter the representation of a value without altering its meaning, leading to a blacklist bypass."

- I chose to not implement argument filtering. It would be useful to have for more granular policies, but I'd rather wait to see how the policies are used and see if argument filtering is required.

- The code only makes use of the `seccomp` syscall to install the filter. It does not fallback to the `prctl(2)` `PR_SET_SECCOMP` operation because it does not support flags. The `SECCOMP_FILTER_FLAG_TSYNC` flag is necessary in Go because we have little control over when threads are started, and there are no guarantees that the filter would be installed before other threads start.
@andrewkroh
Copy link
Member Author

Metricbeat system/diskio uses execve on in Linux. I found seccomp violations in my audit logs and isolated it to the system/diskio test. Here's the cause:

https://github.com/shirou/gopsutil/blob/57f370e13068146efe1cb7129f79e5d51da8a242/disk/disk_linux.go#L373-L389

@ruflin
Copy link
Contributor

ruflin commented May 14, 2018

This is not nice. I wonder if we should make the disk serial number optional and a config option that can be enabled to have by default not execve? Other ideas?

@andrewkroh andrewkroh reopened this May 14, 2018
@andrewkroh
Copy link
Member Author

There might be another way to get the data with ioctl and HDIO_GET_IDENTITY.

We would need to modify gopsutil to not do the udevadm query.

andrewkroh added a commit to andrewkroh/beats that referenced this issue May 15, 2018
This PR adds to the seccomp enhancement in elastic#6832 by adding a whitelist policy.

The policies are derived from a combination of static analysis of the object code and runtime profiling (to see what the cgo linked libraries are doing). The policies also account for the system calls used while running the system tests with coverage and race detection.

Closes elastic#5213
adriansr pushed a commit that referenced this issue May 16, 2018
This PR adds to the seccomp enhancement in #6832 by adding a whitelist policy.

The policies are derived from a combination of static analysis of the object code and runtime profiling (to see what the cgo linked libraries are doing). The policies also account for the system calls used while running the system tests with coverage and race detection.

Closes #5213
@andrewkroh
Copy link
Member Author

stevea78 pushed a commit to stevea78/beats that referenced this issue May 20, 2018
The adds a default seccomp (Secure Computing) filter on Linux that prohibits execve, execveat, fork, and vfork system calls for the Beat process. The seccomp filter policy is configurable as well. You can create your own whitelist or blacklist policy with specific actions. It uses github.com/elastic/go-seccomp-bpf.

Whitelist Example

```
seccomp:
  default_action: errno
  syscalls:
  - action: allow
    names:
    - open
    - close
    - read
    - exit
```

Blacklist Example

```
seccomp:
  default_action: allow
  syscalls:
  - action: log
    names:
    - execve
    - execveat
    - fork
    - vfork
  - action: kill_process     # Requires kernel 4.14+.
    names:
    - connect
    - accept
    - sendto
    - recvfrom
    - sendmsg
    - recvmsg
    - bind
    - listen
```

Closes elastic#5213

Decisions I Made

- The default policy is a blacklist because it was the most simple to start with. Whitelisting is recommended because it is more robust. `man seccomp` states "A blacklist will have to be updated whenever a potentially dangerous system call is added (or a dangerous flag or option if those are blacklisted), and it is often possible to alter the representation of a value without altering its meaning, leading to a blacklist bypass."

- I chose to not implement argument filtering. It would be useful to have for more granular policies, but I'd rather wait to see how the policies are used and see if argument filtering is required.

- The code only makes use of the `seccomp` syscall to install the filter. It does not fallback to the `prctl(2)` `PR_SET_SECCOMP` operation because it does not support flags. The `SECCOMP_FILTER_FLAG_TSYNC` flag is necessary in Go because we have little control over when threads are started, and there are no guarantees that the filter would be installed before other threads start.
stevea78 pushed a commit to stevea78/beats that referenced this issue May 20, 2018
This PR adds to the seccomp enhancement in elastic#6832 by adding a whitelist policy.

The policies are derived from a combination of static analysis of the object code and runtime profiling (to see what the cgo linked libraries are doing). The policies also account for the system calls used while running the system tests with coverage and race detection.

Closes elastic#5213
stevea78 pushed a commit to stevea78/beats that referenced this issue May 20, 2018
The adds a default seccomp (Secure Computing) filter on Linux that prohibits execve, execveat, fork, and vfork system calls for the Beat process. The seccomp filter policy is configurable as well. You can create your own whitelist or blacklist policy with specific actions. It uses github.com/elastic/go-seccomp-bpf.

Whitelist Example

```
seccomp:
  default_action: errno
  syscalls:
  - action: allow
    names:
    - open
    - close
    - read
    - exit
```

Blacklist Example

```
seccomp:
  default_action: allow
  syscalls:
  - action: log
    names:
    - execve
    - execveat
    - fork
    - vfork
  - action: kill_process     # Requires kernel 4.14+.
    names:
    - connect
    - accept
    - sendto
    - recvfrom
    - sendmsg
    - recvmsg
    - bind
    - listen
```

Closes elastic#5213

Decisions I Made

- The default policy is a blacklist because it was the most simple to start with. Whitelisting is recommended because it is more robust. `man seccomp` states "A blacklist will have to be updated whenever a potentially dangerous system call is added (or a dangerous flag or option if those are blacklisted), and it is often possible to alter the representation of a value without altering its meaning, leading to a blacklist bypass."

- I chose to not implement argument filtering. It would be useful to have for more granular policies, but I'd rather wait to see how the policies are used and see if argument filtering is required.

- The code only makes use of the `seccomp` syscall to install the filter. It does not fallback to the `prctl(2)` `PR_SET_SECCOMP` operation because it does not support flags. The `SECCOMP_FILTER_FLAG_TSYNC` flag is necessary in Go because we have little control over when threads are started, and there are no guarantees that the filter would be installed before other threads start.
stevea78 pushed a commit to stevea78/beats that referenced this issue May 20, 2018
This PR adds to the seccomp enhancement in elastic#6832 by adding a whitelist policy.

The policies are derived from a combination of static analysis of the object code and runtime profiling (to see what the cgo linked libraries are doing). The policies also account for the system calls used while running the system tests with coverage and race detection.

Closes elastic#5213
@jsoriano
Copy link
Member

jsoriano commented Jun 1, 2018

I have opened a PR to get disk serial from udev data or sysfs without using udevadm or any other command shirou/gopsutil#532

@ruflin
Copy link
Contributor

ruflin commented Jun 1, 2018

Great. If it doesn't get merge soonish we can also switch to our own fork for now until it is merged.

@jsoriano
Copy link
Member

jsoriano commented Jul 1, 2018

gopsutil 2.18.06 released, PR created to update it #7483

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants