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

Fix: Use events.ErrSkipped with a proper Reason when skipping an actions #202

Merged
merged 2 commits into from
Apr 11, 2024
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
15 changes: 15 additions & 0 deletions events/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ var _ = events.Register(
)
```

### Handling Unsupported Contexts/Prerequisites

When developing actions for the event-generator, it's essential to consider whether the action is applicable to the current execution context. For example, certain actions might be intended to run exclusively within containers or specific environments. Actions that require a specific context or prerequisite to execute successfully should skip the action by return events.ErrSkipped when the necessary conditions are not met For example:

```golang
func UserMgmtBinaries(h events.Helper) error {
if h.InContainer() {
return &events.ErrSkipped{
Reason: "'User mgmt binaries' is excluded in containers",
}
}
return h.SpawnAsWithSymlink("vipw", "helper.ExecLs")
}
```

### Behavior
Running an *action* should be an idempotent operation in the sense that it should not have additional effects if it is called more than once.
For this reason, *actions* should revert any operation that changed the state of the system (eg. if a file is created, then it has to be removed). For example:
Expand Down
26 changes: 14 additions & 12 deletions events/syscall/change_namespace_privileges_via_unshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,27 @@ limitations under the License.
package syscall

import (
"os/exec"
"os/exec"

"github.com/falcosecurity/event-generator/events"
"github.com/falcosecurity/event-generator/events"
)

var _ = events.Register(
ChangeNamespacePrivilegesViaUnshare,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)

func ChangeNamespacePrivilegesViaUnshare(h events.Helper) error {
if h.InContainer() {
cmd := exec.Command("unshare")

h.Log().Infof("Change namespace privileges via unshare")

if err := cmd.Run(); err != nil {
return err
}
if h.InContainer() {
cmd := exec.Command("unshare")

h.Log().Infof("Change namespace privileges via unshare")

if err := cmd.Run(); err != nil {
return err
}
}
return &events.ErrSkipped{
Reason: "'Change Namespace Privileges Via Unshare' is applicable only to containers.",
}
return nil
}
41 changes: 22 additions & 19 deletions events/syscall/contact_cloud_metadata_service_from_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,32 @@ limitations under the License.
package syscall

import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
"os/exec"

"github.com/falcosecurity/event-generator/events"
)

var _ = events.Register(
ContactCloudMetadataServiceFromContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
ContactCloudMetadataServiceFromContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)

func ContactCloudMetadataServiceFromContainer(h events.Helper) error {
if h.InContainer() {
// The IP address 169.254.169.254 is reserved for the Cloud Instance Metadata Service,
// a common endpoint used by cloud instances (GCP, AWS and Azure) to access
// metadata about the instance itself. Detecting attempts to communicate with this
// IP address from a container can indicate potential unauthorized access to
// sensitive cloud infrastructure metadata.
cmd := exec.Command("timeout", "1s", "nc", "169.254.169.254", "80")

if err := cmd.Run(); err != nil {
return err
}

h.Log().Infof("Outbound connection to cloud instance metadata service")
}
return nil
if h.InContainer() {
// The IP address 169.254.169.254 is reserved for the Cloud Instance Metadata Service,
// a common endpoint used by cloud instances (GCP, AWS and Azure) to access
// metadata about the instance itself. Detecting attempts to communicate with this
// IP address from a container can indicate potential unauthorized access to
// sensitive cloud infrastructure metadata.
cmd := exec.Command("timeout", "1s", "nc", "169.254.169.254", "80")

if err := cmd.Run(); err != nil {
return err
}

h.Log().Infof("Outbound connection to cloud instance metadata service")
}
return &events.ErrSkipped{
Reason: "'Contact Cloud Metadata Service From Container' is applicable only to containers.",
}
}
4 changes: 3 additions & 1 deletion events/syscall/container_drift_detected_chmod.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,7 @@ func ContainerDriftDetcted(h events.Helper) error {
return err
}
}
return nil
return &events.ErrSkipped{
Reason: "'Container Drift Detected (chmod)' is applicable only to containers.",
}
}
4 changes: 3 additions & 1 deletion events/syscall/container_drift_detected_open_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ func ContainerDriftDetectedOpenCreate(h events.Helper) error {
h.Log().Infof("writing to %s", file.Name())
return os.WriteFile(file.Name(), nil, os.FileMode(0755)) // Also set execute permission
}
return nil
return &events.ErrSkipped{
Reason: "'Container Drift Detected (open+create)' is applicable only to containers.",
}
}
35 changes: 18 additions & 17 deletions events/syscall/debugfs_launched_in_privilleged_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,29 @@ limitations under the License.
package syscall

import (
"os/exec"
"syscall"
"os/exec"
"syscall"

"github.com/falcosecurity/event-generator/events"
"github.com/falcosecurity/event-generator/events"
)

var _ = events.Register(DebugfsLaunchedInPrivilegedContainer)

func DebugfsLaunchedInPrivilegedContainer(h events.Helper) error {
if h.InContainer() {
cmd := exec.Command("debugfs")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
}
if h.InContainer() {
cmd := exec.Command("debugfs")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
}

h.Log().Info("Debugfs launched started in a privileged container")
err := cmd.Run()
if err != nil {
h.Log().WithError(err).Error("Failed to launch debugfs")
return err
}
}

return nil
h.Log().Info("Debugfs launched started in a privileged container")
err := cmd.Run()
if err != nil {
h.Log().WithError(err).Error("Failed to launch debugfs")
return err
}
}
return &events.ErrSkipped{
Reason: "'Debugfs Launched in Privileged Container' is applicable only to containers.",
}
}
30 changes: 16 additions & 14 deletions events/syscall/decoding_payload_in_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@ limitations under the License.
package syscall

import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
"os/exec"

"github.com/falcosecurity/event-generator/events"
)

var _ = events.Register(
DecodingPayloadInContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
DecodingPayloadInContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)

func DecodingPayloadInContainer(h events.Helper) error {
if h.InContainer() {
encodedPayload := "ZGVjb2RlZF9ieV9ldmVudC1nZW5lcmF0b3I="
cmd := exec.Command("echo", encodedPayload, "|", "base64", "-d")

err := cmd.Run()
if err != nil {
return err
}
}
if h.InContainer() {
encodedPayload := "ZGVjb2RlZF9ieV9ldmVudC1nZW5lcmF0b3I="
cmd := exec.Command("echo", encodedPayload, "|", "base64", "-d")

return nil
err := cmd.Run()
if err != nil {
return err
}
}
return &events.ErrSkipped{
Reason: "'Decoding Payload In Container' is applicable only to containers.",
}
}
9 changes: 6 additions & 3 deletions events/syscall/drop_and_execute_new_binary_in_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ func DropAndExecuteNewBinaryInContainer(h events.Helper) error {
// Find the path of the ls binary
lsPath, err := exec.LookPath("ls")
if err != nil {
h.Log().WithError(err).Error("ls binary not found")
return err
return &events.ErrSkipped{
Reason: "ls utility not found in path",
}
}

// Read the ls binary content
Expand All @@ -52,5 +53,7 @@ func DropAndExecuteNewBinaryInContainer(h events.Helper) error {
h.Log().Info("Executed a binary not part of base image")
executeCmd.Run() // Rule triggers even the command is not successful
}
return nil
return &events.ErrSkipped{
Reason: "'Drop And Execute New Binary In Container' is applicable only to containers.",
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ func kubernetesClientToolLaunchedInContainer(h events.Helper) error {
if h.InContainer() {
kubectl, err := exec.LookPath("kubectl")
if err != nil {
h.Log().Warnf("kubectl is needed to launch this action")
return err
return &events.ErrSkipped{
Reason: "kubectl is needed to launch this action",
}
}

cmd := exec.Command(kubectl)
h.Log().Infof("Kubernetes Client Tool Launched In Container")
return cmd.Run()
}
return nil
return &events.ErrSkipped{
Reason: "'Kubernetes Client Tool Launched In Container' is applicable only to containers.",
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@ func LaunchPackageManagementProcessInContainer(h events.Helper) error {
cmd := exec.Command("apt-get")
return cmd.Run()
}
return nil
return &events.ErrSkipped{
Reason: "'Launch Package Management Process In Container' is applicable only to containers.",
}
}
33 changes: 17 additions & 16 deletions events/syscall/launch_remote_file_copy_tools_in_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,29 @@ limitations under the License.
package syscall

import (
"os/exec"
"os/exec"

"github.com/falcosecurity/event-generator/events"
"github.com/falcosecurity/event-generator/events"
)

var _ = events.Register(
LaunchRemoteFileCopyToolsInContainer,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
LaunchRemoteFileCopyToolsInContainer,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)

func LaunchRemoteFileCopyToolsInContainer(h events.Helper) error {
if h.InContainer() {
// Launch a remote file copy tool (e.g., scp) within the container
cmd := exec.Command("scp")
if h.InContainer() {
// Launch a remote file copy tool (e.g., scp) within the container
cmd := exec.Command("scp")

h.Log().Info("Remote file copy tool launched in container")
err := cmd.Run()
if err != nil {
h.Log().WithError(err).Error("Failed to launch remote file copy tool")
return err
}
}

return nil
h.Log().Info("Remote file copy tool launched in container")
err := cmd.Run()
if err != nil {
h.Log().WithError(err).Error("Failed to launch remote file copy tool")
return err
}
}
return &events.ErrSkipped{
Reason: "'Launch Remote File Copy Tools In Container' is applicable only to containers.",
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ func LaunchIngressRemoteFileCopyToolsInsideContainer(h events.Helper) error {
cmd := exec.Command("wget")
return cmd.Run()
}
return nil
return &events.ErrSkipped{
Reason: "'Launch Ingress Remote File Copy Tools Inside Container' is applicable only to containers.",
}
}
31 changes: 16 additions & 15 deletions events/syscall/launch_suspicious_network_tool_in_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,27 @@ limitations under the License.
package syscall

import (
"os/exec"
"os/exec"

"github.com/falcosecurity/event-generator/events"
"github.com/falcosecurity/event-generator/events"
)

var _ = events.Register(
LaunchSuspiciousNetworkToolInContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
LaunchSuspiciousNetworkToolInContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)

func LaunchSuspiciousNetworkToolInContainer(h events.Helper) error {
if h.InContainer() {
cmd := exec.Command("nmap", "-sn", "192.168.1.0/24")

h.Log().Infof("Network tool launched in container")

if err := cmd.Run(); err != nil {
return err
}
}

return nil
if h.InContainer() {
cmd := exec.Command("nmap", "-sn", "192.168.1.0/24")

h.Log().Infof("Network tool launched in container")

if err := cmd.Run(); err != nil {
return err
}
}
return &events.ErrSkipped{
Reason: "'Launch Suspicious Network Tool In Container' is applicable only to containers.",
}
}
Loading
Loading