|
| 1 | +#################### |
| 2 | +# Your custom rules! |
| 3 | +#################### |
| 4 | + |
| 5 | +# Add new rules, like this one |
| 6 | +# - rule: A shell is run in a container |
| 7 | +# desc: An event will trigger every time you run a shell in a container |
| 8 | +# condition: evt.type = execve and evt.dir=< and container.id != host and proc.name = bash |
| 9 | +# output: "Suspect shell run in container (user=%user.name %container.info shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)" |
| 10 | +# priority: ERROR |
| 11 | +# tags: [shell] |
| 12 | + |
| 13 | +# Or override any rule, macro, or list from the Default Rules |
| 14 | +--- |
| 15 | +- macro: "user_known_network_tool_client_container" |
| 16 | + condition: "container.image.repository=\"bbcdocker/go-synapse\" or container.image.repository=\"\ |
| 17 | + strimzi/kafka\" or container.image.repository=\"landoop/fast-data-dev\"" |
| 18 | + append: false |
| 19 | + |
| 20 | +- rule: "Launch Suspicious Network Tool in Container" |
| 21 | + condition: "and not user_known_network_tool_client_container" |
| 22 | + tags: [] |
| 23 | + append: true |
| 24 | + |
| 25 | +- rule: "Java app run shell untrusted" |
| 26 | + desc: "an attempt to spawn a shell below a Java application." |
| 27 | + condition: "spawned_process and shell_procs and proc.pname exists and proc.pname=java\n" |
| 28 | + output: "Shell spawned by Java application (user=%user.name shell=%proc.name parent=%proc.pname\ |
| 29 | + \ cmdline=%proc.cmdline pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3]\ |
| 30 | + \ aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7]\ |
| 31 | + \ container_id=%container.id image=%container.image.repository)\n" |
| 32 | + priority: "ALERT" |
| 33 | + tags: |
| 34 | + - "shell" |
| 35 | + - "mitre_execution" |
| 36 | + source: "syscall" |
| 37 | + append: false |
| 38 | + |
| 39 | +- rule: "The docker client is executed in a container" |
| 40 | + desc: "Detect a k8s client tool executed inside a container" |
| 41 | + condition: "spawned_process and container and not user_known_k8s_client_container\ |
| 42 | + \ and proc.name in (k8s_client_binaries)" |
| 43 | + output: "Docker or kubernetes client executed in container (user=%user.name %container.info\ |
| 44 | + \ parent=%proc.pname cmdline=%proc.cmdline image=%container.image.repository:%container.image.tag\ |
| 45 | + \ podname=%k8s.pod.name)" |
| 46 | + priority: "WARNING" |
| 47 | + tags: |
| 48 | + - "container" |
| 49 | + - "mitre_execution" |
| 50 | + append: false |
| 51 | + |
| 52 | +- macro: "user_read_sensitive_file_conditions" |
| 53 | + condition: "or container.image.repository=\"sysdig/agent\" or (container.id=host\ |
| 54 | + \ and fd.name=/etc/pam.d/sshd and proc.name=grep)" |
| 55 | + append: true |
| 56 | + |
| 57 | +- rule: "Root user interactive" |
| 58 | + desc: "an attempt to run interactive commands by root user" |
| 59 | + condition: "spawned_process and user.name=\"root\" and interactive" |
| 60 | + output: "Root user ran an interactive command (user=%user.name command=%proc.cmdline\ |
| 61 | + \ container_id=%container.id image=%container.image.repository)" |
| 62 | + priority: "INFO" |
| 63 | + tags: |
| 64 | + - "mitre_remote_access_tools" |
| 65 | + - "users" |
| 66 | + append: false |
| 67 | + |
| 68 | +- list: "user_known_hostnetwork_images" |
| 69 | + items: |
| 70 | + - "gke.gcr.io/kube-proxy" |
| 71 | + - "gke.gcr.io/kube-proxy-amd64" |
| 72 | + - "newrelic/infrastructure-k8s" |
| 73 | + - "k8s.gcr.io/prometheus-to-sd" |
| 74 | + - "docker.io/sysdig/agent" |
| 75 | + - "gcr.io/stackdriver-agents/stackdriver-logging-agent" |
| 76 | + - "newrelic/newrelic-fluentbit-output" |
| 77 | + - "gcr.io/gke-release/gke-metrics-agent" |
| 78 | + - "quay.io/prometheus/node-exporter" |
| 79 | + append: false |
| 80 | + |
| 81 | +- rule: "Create HostNetwork Pod" |
| 82 | + condition: "and not ka.req.pod.containers.image.repository intersects (user_known_hostnetwork_images)" |
| 83 | + output: "Pod started using host network (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace\ |
| 84 | + \ images=%ka.req.pod.containers.repository)" |
| 85 | + tags: [] |
| 86 | + append: true |
| 87 | + |
| 88 | +- list: "user_known_privileged_images" |
| 89 | + items: |
| 90 | + - "gcr.io/google-containers/startup-script" |
| 91 | + - "gke.gcr.io/kube-proxy-amd64" |
| 92 | + - "newrelic/infrastructure-k8s" |
| 93 | + - "docker.io/sysdig/node-image-analyzer" |
| 94 | + append: false |
| 95 | + |
| 96 | +- rule: "Create Privileged Pod" |
| 97 | + condition: "and not ka.req.pod.containers.image.repository in (user_known_privileged_images)" |
| 98 | + tags: [] |
| 99 | + append: true |
| 100 | + |
| 101 | +- list: "user_known_kube_namespace_images" |
| 102 | + items: |
| 103 | + - "gcr.io/google-containers/startup-script" |
| 104 | + - "gke.gcr.io/kube-proxy-amd64" |
| 105 | + - "k8s.gcr.io/gke-node-termination-handler" |
| 106 | + - "gcr.io/gke-release/gke-metrics-agent" |
| 107 | + - "k8s.gcr.io/k8s-dns-kube-dns-amd64" |
| 108 | + - "k8s.gcr.io/prometheus-to-sd" |
| 109 | + - "gke.gcr.io/k8s-dns-dnsmasq-nanny-amd64" |
| 110 | + - "gke.gcr.io/k8s-dns-sidecar-amd64" |
| 111 | + append: false |
| 112 | + |
| 113 | +- rule: "Pod Created in Kube Namespace" |
| 114 | + condition: "and not ka.req.container.image.repository in (user_known_kube_namespace_images)" |
| 115 | + tags: [] |
| 116 | + append: true |
| 117 | + |
| 118 | +- rule: "Update Package Repository" |
| 119 | + condition: "and not exe_running_docker_save" |
| 120 | + tags: [] |
| 121 | + append: true |
| 122 | + |
| 123 | +- rule: "Modify Shell Configuration File" |
| 124 | + condition: "and not exe_running_docker_save" |
| 125 | + tags: [] |
| 126 | + append: true |
| 127 | + |
| 128 | +- rule: "Change thread namespace" |
| 129 | + condition: "and not (container.image.repository=\"datadog/agent\" and proc.name=\"\ |
| 130 | + system-probe\")" |
| 131 | + tags: [] |
| 132 | + append: true |
| 133 | + |
| 134 | +- list: "user_known_gke_metadata_images" |
| 135 | + items: |
| 136 | + - "gke.gcr.io/kube-proxy-amd64" |
| 137 | + - "gcr.io/gke-release/gke-metrics-agent" |
| 138 | + - "gke.gcr.io/k8s-dns-kube-dns-amd64" |
| 139 | + - "k8s.gcr.io/prometheus-to-sd" |
| 140 | + - "newrelic/infrastructure-k8s" |
| 141 | + - "datadog/agent" |
| 142 | + - "gke.gcr.io/prometheus-to-sd" |
| 143 | + - "sysdig/agent" |
| 144 | + - "gcr.io/stackdriver-agents/stackdriver-logging-agent" |
| 145 | + - "gcr.io/stackdriver-agents/metadata-agent-go" |
| 146 | + - "istio/proxyv2" |
| 147 | + - "newrelic/k8s-events-forwarder" |
| 148 | + - "gke.gcr.io/calico/typha" |
| 149 | + append: false |
| 150 | + |
| 151 | +- macro: "mariadb_snapshots_validator" |
| 152 | + condition: "(container.image.repository=\"google/cloud-sdk\" and container.name\ |
| 153 | + \ contains \"snapshot-validator\")" |
| 154 | + append: false |
| 155 | + |
| 156 | +- macro: "bbc_java_app_proc" |
| 157 | + condition: "(container.image.repository startswith \"eu.gcr.io/bbc-registry/\" and\ |
| 158 | + \ proc.name=\"java\")" |
| 159 | + append: false |
| 160 | + |
| 161 | +- macro: "gke_metadata_containers" |
| 162 | + condition: "(container.image.repository in (user_known_gke_metadata_images)) or\ |
| 163 | + \ mariadb_snapshots_validator or proc.name=\"newrelic-daemon\" or (container.image.repository=\"\ |
| 164 | + docker.elastic.co/beats/filebeat\" and proc.name=\"filebeat\")" |
| 165 | + append: false |
| 166 | + |
| 167 | +- rule: "Contact GKE Instance Metadata Service From Container" |
| 168 | + desc: "Detect attempts to contact the GKE Instance Metadata Service from a container" |
| 169 | + condition: "outbound and fd.sip=\"169.254.169.254\" and container and not gke_metadata_containers" |
| 170 | + output: "Outbound connection to GKE instance metadata service (proc=%proc.name procp=%proc.pname\ |
| 171 | + \ procpp=%proc.aname[2] procppp=%proc.aname[3] procpppp=%proc.aname[4] command=%proc.cmdline\ |
| 172 | + \ connection=%fd.name container_infos=%container.info container=%container.name\ |
| 173 | + \ image=%container.image.repository:%container.image.tag)" |
| 174 | + priority: "NOTICE" |
| 175 | + tags: |
| 176 | + - "gke" |
| 177 | + - "container" |
| 178 | + - "mitre_discovery" |
| 179 | + - "network" |
| 180 | + append: false |
| 181 | + |
| 182 | +- macro: "mariadb_snapshots" |
| 183 | + condition: "(container.image.repository=\"mariadb\" and container.name contains\ |
| 184 | + \ \"snapshot-validated\") or (container.image.repository=\"mariadb\" and proc.name=\"\ |
| 185 | + sh\" and proc.pname=\"mysqld\")" |
| 186 | + append: false |
| 187 | + |
| 188 | +- rule: "DB program spawned process" |
| 189 | + condition: "and not mariadb_snapshots" |
| 190 | + tags: [] |
| 191 | + append: true |
| 192 | + |
| 193 | +- macro: "user_known_clear_log_activities" |
| 194 | + condition: "(container.image.repository=\"landoop/fast-data-dev\" and fd.name=\"\ |
| 195 | + /var/log/running-smart.log\")" |
| 196 | + append: false |
| 197 | + |
| 198 | +- rule: "Clear Log Activities" |
| 199 | + condition: "and not user_known_clear_log_activities" |
| 200 | + tags: [] |
| 201 | + append: true |
| 202 | + |
| 203 | +- list: "user_known_sensitive_mount_images" |
| 204 | + items: |
| 205 | + - "newrelic/infrastructure-k8s" |
| 206 | + - "quay.io/prometheus/node-exporter" |
| 207 | + append: false |
| 208 | + |
| 209 | +- rule: "Create Sensitive Mount Pod" |
| 210 | + condition: "and not ka.req.pod.containers.image.repository in (user_known_sensitive_mount_images)" |
| 211 | + tags: [] |
| 212 | + append: true |
| 213 | + |
| 214 | +- list: "user_known_privilged_k8s_roles" |
| 215 | + items: |
| 216 | + - "mariadb-moderation-snapshot-validated" |
| 217 | + - "mariadb-payment-servix-snapshot-validated" |
| 218 | + - "mariadb-user-activity-snapshot-validated" |
| 219 | + - "mariadb-user-wallet-servix-snapshot-validated" |
| 220 | + - "mariadb-log-snapshot-validated" |
| 221 | + - "mariadb-monetize-servix-snapshot-validated" |
| 222 | + - "mariadb-sesterce-snapshot-validated" |
| 223 | + - "mariadb-reports-snapshot-validated" |
| 224 | + - "mariadb-dev-snapshot-validated" |
| 225 | + - "mariadb-main-snapshot-validated" |
| 226 | + - "mariadb-components-snapshot-validated" |
| 227 | + - "prometheus-operator-admission" |
| 228 | + - "mariadb-monetize-servix-daily-copy" |
| 229 | + - "mariadb-sesterce-daily-copy" |
| 230 | + - "mariadb-main-daily-copy" |
| 231 | + - "mariadb-components-daily-copy" |
| 232 | + - "mariadb-log-daily-copy" |
| 233 | + - "mariadb-reports-daily-copy" |
| 234 | + - "mariadb-moderation-daily-copy" |
| 235 | + - "mariadb-payment-servix-daily-copy" |
| 236 | + append: false |
| 237 | + |
| 238 | +- rule: "ClusterRole With Write Privileges Created" |
| 239 | + condition: "and not ka.target.name in (user_known_privilged_k8s_roles)" |
| 240 | + tags: [] |
| 241 | + append: true |
| 242 | + |
| 243 | +- rule: "Launch Remote File Copy Tools in Container" |
| 244 | + condition: "and not user_known_remote_file_copy_activities" |
| 245 | + tags: [] |
| 246 | + append: true |
| 247 | + |
| 248 | +- macro: "user_known_container_drift_open_create_activities" |
| 249 | + condition: "(container.image.repository=\"docker.elastic.co/elasticsearch/elasticsearch\"\ |
| 250 | + \ and evt.arg.filename startswith \"/usr/share/elasticsearch/data/nodes\")" |
| 251 | + append: false |
| 252 | + |
| 253 | +- rule: "Container Drift Detected (open+create)" |
| 254 | + condition: "and not user_known_container_drift_open_create_activities" |
| 255 | + tags: [] |
| 256 | + append: true |
| 257 | + |
| 258 | +- macro: "test_foo_bar" |
| 259 | + condition: "never_true" |
| 260 | + append: false |
0 commit comments