|
| 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_k8s_client_container" |
| 16 | + condition: "container.image.repository=\"k8s.gcr.io/fluentd-gcp-scaler\" or container.image.repository=\"\ |
| 17 | + fluxcd/flux\" or container.image.repository=\"sysdig/agent\" or container.image.repository=\"\ |
| 18 | + fluxcd/helm-operator\" or (container.image.repository=\"google/cloud-sdk\")" |
| 19 | + append: false |
| 20 | + |
| 21 | +- macro: "user_known_write_below_root_activities" |
| 22 | + condition: "(container.image.repository startswith \"bbcdocker/go-synapse\" and\ |
| 23 | + \ fd.name=\"/haproxy.conf\") or (container.image.repository=\"cassandra\" and\ |
| 24 | + \ fd.name startswith \"/root/.cassandra/\") or (container.id=host and fd.name\ |
| 25 | + \ startswith /root/.kube/) or (container.image.repository=\"mariadb\" and proc.name=\"\ |
| 26 | + mysqld\") or (container.image.repository=\"mariadb\" and proc.name=\"mysql\")" |
| 27 | + append: false |
| 28 | + |
| 29 | +- macro: "user_known_network_tool_client_container" |
| 30 | + condition: "container.image.repository=\"bbcdocker/go-synapse\" or container.image.repository=\"\ |
| 31 | + strimzi/kafka\" or container.image.repository=\"landoop/fast-data-dev\"" |
| 32 | + append: false |
| 33 | + |
| 34 | +- rule: "Launch Suspicious Network Tool in Container" |
| 35 | + condition: "and not user_known_network_tool_client_container" |
| 36 | + tags: [] |
| 37 | + append: true |
| 38 | + |
| 39 | +- rule: "Java app run shell untrusted" |
| 40 | + desc: "an attempt to spawn a shell below a Java application." |
| 41 | + condition: "spawned_process and shell_procs and proc.pname exists and proc.pname=java\n" |
| 42 | + output: "Shell spawned by Java application (user=%user.name shell=%proc.name parent=%proc.pname\ |
| 43 | + \ cmdline=%proc.cmdline pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3]\ |
| 44 | + \ aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7]\ |
| 45 | + \ container_id=%container.id image=%container.image.repository)\n" |
| 46 | + priority: "ALERT" |
| 47 | + tags: |
| 48 | + - "shell" |
| 49 | + - "mitre_execution" |
| 50 | + source: "syscall" |
| 51 | + append: false |
| 52 | + |
| 53 | +- macro: "user_known_write_below_etc_activities" |
| 54 | + condition: "(container.image.repository=\"quay.io/thanos/thanos\" and fd.name=\"\ |
| 55 | + /etc/prom/prometheus.yaml.tmp\" or (container.image.repository=\"eu.gcr.io/bbc-registry/comuto3\"\ |
| 56 | + \ and fd.name startswith \"/etc/nginx/\"))" |
| 57 | + append: false |
| 58 | + |
| 59 | +- rule: "The docker client is executed in a container" |
| 60 | + desc: "Detect a k8s client tool executed inside a container" |
| 61 | + condition: "spawned_process and container and not user_known_k8s_client_container\ |
| 62 | + \ and proc.name in (k8s_client_binaries)" |
| 63 | + output: "Docker or kubernetes client executed in container (user=%user.name %container.info\ |
| 64 | + \ parent=%proc.pname cmdline=%proc.cmdline image=%container.image.repository:%container.image.tag\ |
| 65 | + \ podname=%k8s.pod.name)" |
| 66 | + priority: "WARNING" |
| 67 | + tags: |
| 68 | + - "container" |
| 69 | + - "mitre_execution" |
| 70 | + append: false |
| 71 | + |
| 72 | +- macro: "user_read_sensitive_file_conditions" |
| 73 | + condition: "or container.image.repository=\"sysdig/agent\" or (container.id=host\ |
| 74 | + \ and fd.name=/etc/pam.d/sshd and proc.name=grep)" |
| 75 | + append: true |
| 76 | + |
| 77 | +- rule: "Root user interactive" |
| 78 | + desc: "an attempt to run interactive commands by root user" |
| 79 | + condition: "spawned_process and user.name=\"root\" and interactive" |
| 80 | + output: "Root user ran an interactive command (user=%user.name command=%proc.cmdline\ |
| 81 | + \ container_id=%container.id image=%container.image.repository)" |
| 82 | + priority: "INFO" |
| 83 | + tags: |
| 84 | + - "mitre_remote_access_tools" |
| 85 | + - "users" |
| 86 | + append: false |
| 87 | + |
| 88 | +- macro: "user_known_write_etc_conditions" |
| 89 | + condition: "proc.name=confd or (container.image.repository=\"confluentinc/cp-schema-registry\"\ |
| 90 | + \ and fd.name startswith \"/etc/schema-registry/\") or (container.image.repository=\"\ |
| 91 | + eu.gcr.io/bbc-registry/communication\" and fd.name startswith \"/etc/nginx/\"\ |
| 92 | + ) or (container.image.repository=\"eu.gcr.io/bbc-registry/redirector\" and fd.name\ |
| 93 | + \ startswith \"/etc/nginx/\") or (container.image.repository=\"eu.gcr.io/bbc-registry/webhooks\"\ |
| 94 | + \ and fd.name startswith \"/etc/nginx/\")or (container.image.repository=\"thanosio/thanos\"\ |
| 95 | + \ and fd.name startswith \"/etc/prom/\") or (container.image.repository=\"eu.gcr.io/bbc-registry/insurance-backoffice\"\ |
| 96 | + \ and fd.name startswith \"/etc/nginx/\") or (container.id=\"host\" and proc.name=\"\ |
| 97 | + exe\" and proc.pname=\"dockerd\")" |
| 98 | + append: false |
| 99 | + |
| 100 | +- macro: "user_known_package_manager_in_container" |
| 101 | + condition: "(container.image.repository=\"confluentinc/cp-schema-registry\" and\ |
| 102 | + \ proc.name=\"pip\") or (container.image.repository=sysdig/node-image-analyzer\ |
| 103 | + \ and proc.name=rpm)" |
| 104 | + append: false |
| 105 | + |
| 106 | +- macro: "user_privileged_containers" |
| 107 | + condition: "(container.image.repository endswith sysdig/agent) or (container.image.repository=weaveworks/scope)\ |
| 108 | + \ or (container.image.repository=docker.io/weaveworks/scope) or (container.image.repository=gcr.io/google-containers/startup-script)\ |
| 109 | + \ or (container.image.repository=gke.gcr.io/kube-proxy) or (container.image.repository=sysdig/node-image-analyzer)" |
| 110 | + append: false |
| 111 | + |
| 112 | +- macro: "user_sensitive_mount_containers" |
| 113 | + condition: "(container.image.repository = docker.io/sysdig/agent) or (container.image.repository=quay.io/prometheus/node-exporter)\ |
| 114 | + \ or (container.image.repository=weaveworks/scope) or (container.image.repository=datadog/agent)" |
| 115 | + append: false |
| 116 | + |
| 117 | +- macro: "user_known_change_thread_namespace_activities" |
| 118 | + condition: "container.image.repository=gcr.io/google-containers/startup-script" |
| 119 | + append: false |
| 120 | + |
| 121 | +- list: "user_known_hostnetwork_images" |
| 122 | + items: |
| 123 | + - "gke.gcr.io/kube-proxy" |
| 124 | + - "gke.gcr.io/kube-proxy-amd64" |
| 125 | + - "newrelic/infrastructure-k8s" |
| 126 | + - "k8s.gcr.io/prometheus-to-sd" |
| 127 | + - "docker.io/sysdig/agent" |
| 128 | + - "gcr.io/stackdriver-agents/stackdriver-logging-agent" |
| 129 | + - "newrelic/newrelic-fluentbit-output" |
| 130 | + - "gcr.io/gke-release/gke-metrics-agent" |
| 131 | + - "quay.io/prometheus/node-exporter" |
| 132 | + append: false |
| 133 | + |
| 134 | +- rule: "Create HostNetwork Pod" |
| 135 | + condition: "and not ka.req.pod.containers.image.repository intersects (user_known_hostnetwork_images)" |
| 136 | + output: "Pod started using host network (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace\ |
| 137 | + \ images=%ka.req.pod.containers.repository)" |
| 138 | + tags: [] |
| 139 | + append: true |
| 140 | + |
| 141 | +- list: "user_known_privileged_images" |
| 142 | + items: |
| 143 | + - "gcr.io/google-containers/startup-script" |
| 144 | + - "gke.gcr.io/kube-proxy-amd64" |
| 145 | + - "newrelic/infrastructure-k8s" |
| 146 | + - "docker.io/sysdig/node-image-analyzer" |
| 147 | + append: false |
| 148 | + |
| 149 | +- rule: "Create Privileged Pod" |
| 150 | + condition: "and not ka.req.pod.containers.image.repository in (user_known_privileged_images)" |
| 151 | + tags: [] |
| 152 | + append: true |
| 153 | + |
| 154 | +- list: "user_known_kube_namespace_images" |
| 155 | + items: |
| 156 | + - "gcr.io/google-containers/startup-script" |
| 157 | + - "gke.gcr.io/kube-proxy-amd64" |
| 158 | + - "k8s.gcr.io/gke-node-termination-handler" |
| 159 | + - "gcr.io/gke-release/gke-metrics-agent" |
| 160 | + - "k8s.gcr.io/k8s-dns-kube-dns-amd64" |
| 161 | + - "k8s.gcr.io/prometheus-to-sd" |
| 162 | + - "gke.gcr.io/k8s-dns-dnsmasq-nanny-amd64" |
| 163 | + - "gke.gcr.io/k8s-dns-sidecar-amd64" |
| 164 | + append: false |
| 165 | + |
| 166 | +- rule: "Pod Created in Kube Namespace" |
| 167 | + condition: "and not ka.req.container.image.repository in (user_known_kube_namespace_images)" |
| 168 | + tags: [] |
| 169 | + append: true |
| 170 | + |
| 171 | +- macro: "user_shell_container_exclusions" |
| 172 | + condition: "((container.image.repository=bitnami/rabbitmq and proc.pname=erl) or\ |
| 173 | + \ (container.image.repository=bitnami/rabbitmq and proc.pname=\"beam.smp\"))" |
| 174 | + append: false |
| 175 | + |
| 176 | +- macro: "user_known_write_root_conditions" |
| 177 | + condition: "(fd.name=/root/.bash_history) or (container.image.repository=\"cassandra\"\ |
| 178 | + \ and fd.name startswith \"/root/.cassandra/\") or (container.image.repository=\"\ |
| 179 | + bbcdocker/go-synapse\" and fd.name=\"/haproxy.conf\") or (container.id=\"host\"\ |
| 180 | + \ and proc.name=\"exe\" and proc.pname=\"dockerd\")" |
| 181 | + append: false |
| 182 | + |
| 183 | +- macro: "exe_running_docker_save" |
| 184 | + condition: "((proc.cmdline startswith \"exe /var/lib/docker\" or proc.cmdline startswith\ |
| 185 | + \ \"exe / /var/lib/docker\") and proc.pname in (dockerd, docker))" |
| 186 | + append: false |
| 187 | + |
| 188 | +- rule: "Update Package Repository" |
| 189 | + condition: "and not exe_running_docker_save" |
| 190 | + tags: [] |
| 191 | + append: true |
| 192 | + |
| 193 | +- rule: "Modify Shell Configuration File" |
| 194 | + condition: "and not exe_running_docker_save" |
| 195 | + tags: [] |
| 196 | + append: true |
| 197 | + |
| 198 | +- rule: "Change thread namespace" |
| 199 | + condition: "and not (container.image.repository=\"datadog/agent\" and proc.name=\"\ |
| 200 | + system-probe\")" |
| 201 | + tags: [] |
| 202 | + append: true |
| 203 | + |
| 204 | +- macro: "allowed_clear_log_files" |
| 205 | + condition: "(container.image.repository=\"landoop/fast-data-dev\" and fd.name=\"\ |
| 206 | + /var/log/broker.log\")" |
| 207 | + append: false |
| 208 | + |
| 209 | +- list: "user_known_gke_metadata_images" |
| 210 | + items: |
| 211 | + - "gke.gcr.io/kube-proxy-amd64" |
| 212 | + - "gcr.io/gke-release/gke-metrics-agent" |
| 213 | + - "gke.gcr.io/k8s-dns-kube-dns-amd64" |
| 214 | + - "k8s.gcr.io/prometheus-to-sd" |
| 215 | + - "newrelic/infrastructure-k8s" |
| 216 | + - "datadog/agent" |
| 217 | + - "gke.gcr.io/prometheus-to-sd" |
| 218 | + - "sysdig/agent" |
| 219 | + - "gcr.io/stackdriver-agents/stackdriver-logging-agent" |
| 220 | + - "gcr.io/stackdriver-agents/metadata-agent-go" |
| 221 | + - "istio/proxyv2" |
| 222 | + - "newrelic/k8s-events-forwarder" |
| 223 | + - "gke.gcr.io/calico/typha" |
| 224 | + append: false |
| 225 | + |
| 226 | +- macro: "mariadb_snapshots_validator" |
| 227 | + condition: "(container.image.repository=\"google/cloud-sdk\" and container.name\ |
| 228 | + \ contains\"snapshot-validator\")" |
| 229 | + append: false |
| 230 | + |
| 231 | +- macro: "bbc_java_app_proc" |
| 232 | + condition: "(container.image.repository startswith \"eu.gcr.io/bbc-registry/\" and\ |
| 233 | + \ proc.name=\"java\")" |
| 234 | + append: false |
| 235 | + |
| 236 | +- macro: "gke_metadata_containers" |
| 237 | + condition: "(container.image.repository in (user_known_gke_metadata_images)) or\ |
| 238 | + \ mariadb_snapshots_validator or proc.name=\"newrelic-daemon\" or (container.image.repository=\"\ |
| 239 | + docker.elastic.co/beats/filebeat\" and proc.name=\"filebeat\")" |
| 240 | + append: false |
| 241 | + |
| 242 | +- rule: "Contact GKE Instance Metadata Service From Container" |
| 243 | + desc: "Detect attempts to contact the GKE Instance Metadata Service from a container" |
| 244 | + condition: "outbound and fd.sip=\"169.254.169.254\" and container and not gke_metadata_containers" |
| 245 | + output: "Outbound connection to GKE instance metadata service (proc=%proc.name procp=%proc.pname\ |
| 246 | + \ procpp=%proc.aname[2] procppp=%proc.aname[3] procpppp=%proc.aname[4] command=%proc.cmdline\ |
| 247 | + \ connection=%fd.name container_infos=%container.info container=%container.name\ |
| 248 | + \ image=%container.image.repository:%container.image.tag)" |
| 249 | + priority: "NOTICE" |
| 250 | + tags: |
| 251 | + - "gke" |
| 252 | + - "container" |
| 253 | + - "mitre_discovery" |
| 254 | + - "network" |
| 255 | + append: false |
| 256 | + |
| 257 | +- macro: "mariadb_snapshots" |
| 258 | + condition: "(container.image.repository=\"mariadb\" and container.name contains\ |
| 259 | + \ \"snapshot-validated\") or (container.image.repository=\"mariadb\" and proc.name=\"\ |
| 260 | + sh\" and proc.pname=\"mysqld\")" |
| 261 | + append: false |
| 262 | + |
| 263 | +- rule: "DB program spawned process" |
| 264 | + condition: "and not mariadb_snapshots" |
| 265 | + tags: [] |
| 266 | + append: true |
| 267 | + |
| 268 | +- macro: "user_known_clear_log_activities" |
| 269 | + condition: "(container.image.repository=\"landoop/fast-data-dev\" and fd.name=\"\ |
| 270 | + /var/log/running-smart.log\")" |
| 271 | + append: false |
| 272 | + |
| 273 | +- rule: "Clear Log Activities" |
| 274 | + condition: "and not user_known_clear_log_activities" |
| 275 | + tags: [] |
| 276 | + append: true |
| 277 | + |
| 278 | +- list: "user_known_sensitive_mount_images" |
| 279 | + items: |
| 280 | + - "newrelic/infrastructure-k8s" |
| 281 | + - "quay.io/prometheus/node-exporter" |
| 282 | + append: false |
| 283 | + |
| 284 | +- rule: "Create Sensitive Mount Pod" |
| 285 | + condition: "and not ka.req.pod.containers.image.repository in (user_known_sensitive_mount_images)" |
| 286 | + tags: [] |
| 287 | + append: true |
| 288 | + |
| 289 | +- macro: "user_shell_container_exclusions" |
| 290 | + condition: "(container.image.repository=\"kong\" and proc.pname=\"nginx\")" |
| 291 | + append: false |
| 292 | + |
| 293 | +- list: "user_known_privilged_k8s_roles" |
| 294 | + items: |
| 295 | + - "mariadb-moderation-snapshot-validated" |
| 296 | + - "mariadb-payment-servix-snapshot-validated" |
| 297 | + - "mariadb-user-activity-snapshot-validated" |
| 298 | + - "mariadb-user-wallet-servix-snapshot-validated" |
| 299 | + - "mariadb-log-snapshot-validated" |
| 300 | + - "mariadb-monetize-servix-snapshot-validated" |
| 301 | + - "mariadb-sesterce-snapshot-validated" |
| 302 | + - "mariadb-reports-snapshot-validated" |
| 303 | + - "mariadb-dev-snapshot-validated" |
| 304 | + - "mariadb-main-snapshot-validated" |
| 305 | + - "mariadb-components-snapshot-validated" |
| 306 | + - "prometheus-operator-admission" |
| 307 | + - "mariadb-monetize-servix-daily-copy" |
| 308 | + - "mariadb-sesterce-daily-copy" |
| 309 | + - "mariadb-main-daily-copy" |
| 310 | + - "mariadb-components-daily-copy" |
| 311 | + - "mariadb-log-daily-copy" |
| 312 | + - "mariadb-reports-daily-copy" |
| 313 | + - "mariadb-moderation-daily-copy" |
| 314 | + - "mariadb-payment-servix-daily-copy" |
| 315 | + append: false |
| 316 | + |
| 317 | +- rule: "ClusterRole With Write Privileges Created" |
| 318 | + condition: "and not ka.target.name in (user_known_privilged_k8s_roles)" |
| 319 | + tags: [] |
| 320 | + append: true |
| 321 | + |
| 322 | +- macro: "user_known_network_tool_activities" |
| 323 | + condition: "(container.image.repository=\"mariadb\" and (proc.pname=\"wsrep_sst_maria\"\ |
| 324 | + \ or proc.pname=\"timeout\") and proc.name=\"socat\")" |
| 325 | + append: false |
| 326 | + |
| 327 | +- macro: "user_shell_container_exclusions" |
| 328 | + condition: "(container.image.repository=\"mariadb\" and proc.pname=\"mysqld\" and\ |
| 329 | + \ proc.name=\"sh\")" |
| 330 | + append: false |
| 331 | + |
| 332 | +- macro: "user_known_remote_file_copy_activities" |
| 333 | + condition: "(container.image.repository=\"eu.gcr.io/bbc-registry/command-export-russian-user\"\ |
| 334 | + \ and proc.name=\"sftp\")" |
| 335 | + append: false |
| 336 | + |
| 337 | +- rule: "Launch Remote File Copy Tools in Container" |
| 338 | + condition: "and not user_known_remote_file_copy_activities" |
| 339 | + tags: [] |
| 340 | + append: true |
| 341 | + |
| 342 | +- macro: "user_known_container_drift_open_create_activities" |
| 343 | + condition: "(container.image.repository=\"docker.elastic.co/elasticsearch/elasticsearch\"\ |
| 344 | + \ and evt.arg.filename startswith \"/usr/share/elasticsearch/data/nodes\")" |
| 345 | + append: false |
| 346 | + |
| 347 | +- rule: "Container Drift Detected (open+create)" |
| 348 | + condition: "and not user_known_container_drift_open_create_activities" |
| 349 | + tags: [] |
| 350 | + append: true |
| 351 | + |
| 352 | +- macro: "user_known_container_drift_activities" |
| 353 | + condition: "((container.image.repository=\"fluxcd/helm-operator\" and proc.name=\"\ |
| 354 | + git\" and evt.arg.filename endswith \"/.git/config\") or (container.image.repository=\"\ |
| 355 | + fluxcd/flux\" and proc.name=\"git\" and evt.arg.filename endswith \"/.git/config\"\ |
| 356 | + ) or (container.image.repository=\"k8s.gcr.io/fluentd-gcp-scaler\" and proc.name=\"\ |
| 357 | + kubectl\" and evt.arg.filename startswith \"/root/.kube/cache/discovery/\") or\ |
| 358 | + \ (container.image.repository=\"eu.gcr.io/bbc-registry/command-bnp-payout-report\"\ |
| 359 | + \ and proc.name=\"gpg-agent\" and evt.arg.filename startswith \"/root/.gnupg/\"\ |
| 360 | + ) or (container.image.repository=\"gcr.io/stackdriver-agents/stackdriver-logging-agent\"\ |
| 361 | + \ and evt.arg.filename startswith \"/var/run/google-fluentd/\") or (container.image.repository=\"\ |
| 362 | + weaveworks/prom-aggregation-gateway\" and proc.name=\"prom-aggregatio\" and evt.arg.filename\ |
| 363 | + \ startswith \"/var/lib/docker/\") or (container.image.repository=\"datadog/agent\"\ |
| 364 | + \ and proc.name=\"system-probe\" and evt.arg.filename startswith \"/var/run/sysprobe/\"\ |
| 365 | + ) or (container.image.repository=\"docker.elastic.co/elasticsearch/elasticsearch\"\ |
| 366 | + \ and proc.name=\"java\" and evt.arg.filename startswith \"/usr/share/elasticsearch/plugins/\"\ |
| 367 | + ) or (container.image.repository=\"docker.elastic.co/elasticsearch/elasticsearch\"\ |
| 368 | + \ and proc.name=\"cp\" and evt.arg.filename startswith \"/mnt/elastic-internal/elasticsearch-config-local/\"\ |
| 369 | + ) or (container.image.repository=\"istio/proxyv2\" and proc.name=\"pilot-agent\"\ |
| 370 | + \ and evt.arg.filename startswith \"/var/lib/docker/overlay2/\"))" |
| 371 | + append: false |
| 372 | + |
| 373 | +- macro: "test_foo_bar" |
| 374 | + condition: "never_true" |
| 375 | + append: false |
0 commit comments