Perform behavioral analytics of syscall process and file activities at the host and container level to detect malicious activies
Create a new rule on Falco on /etc/falco/falco_rules.local.yaml
- macro: container
condition: container.id != host
- macro: spawned_process
condition: evt.type = execve and evt.dir=<
- rule: run_shell_in_container
desc: a shell was spawned by a non-shell program in a container. Container entrypoints are excluded.
condition: container and proc.name = bash
output: "Shell spawned (%user.name,container_id=%container.id)"
priority: WARNING
You should see the following logs:
21:46:10.887392293: Notice A shell was spawned in a container with an attached terminal (user=root user_loginuid=-1 <NA> (id=3d9b3f12ef50) shell=bash parent=runc cmdline=bash terminal=34816 container_id=3d9b3f12ef50 image=<NA>)
21:46:11.008102763: Warning Shell spawned (root,container_id=3d9b3f12ef50)
IDS/NIDS
Some vectors:
Install sysdig standalone and run on the host:
curl -s https://download.sysdig.com/DRAIOS-GPG-KEY.public | apt-key add -
curl -s -o /etc/apt/sources.list.d/draios.list http://download.sysdig.com/stable/deb/draios.list
apt-get update && apt-get install sysdig
In one terminal run:
$ while true; do cat /etc/passwd; sleep 1; done
Find the syscall made by cat
using sysdig
:
sysdig proc.name=cat and evt.type=openat -p "%evt.info | %proc.name"
...
fd=3(<f>/etc/passwd) dirfd=-100(AT_FDCWD) name=/etc/passwd flags=1(O_RDONLY) mode=0 dev=801 | cat
...
It's possible to use strace and summarize the options as well:
root@hackbox:/etc/falco# strace -p 839438 -wc
strace: Process 839438 attached
^Cstrace: Process 839438 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
99.93 3.366340 187018 18 select
0.03 0.001046 19 53 clock_gettime
0.02 0.000583 16 36 rt_sigprocmask
0.01 0.000487 54 9 write
0.01 0.000211 23 9 read
0.00 0.000065 16 4 getpid
0.00 0.000020 20 1 ioctl
------ ----------- ----------- --------- --------- ----------------
100.00 3.368753 130 total
References:
- syscall analysis - https://docs.sysdig.com/
- https://kubernetes.io/blog/2015/11/monitoring-kubernetes-with-sysdig/
- Volumes mount read-only or overwrite
securityContext:
readOnlyRootFilesystem: true
Kubernetes auditing provides a security-relevant, chronological set of records documenting the sequence of actions in a cluster. The cluster audits the activities generated by users, by applications that use the Kubernetes API, and by the control plane itself.
- RequestReceived - The stage for events generated as soon as the audit handler receives the request, and before it is delegated down the handler chain.
- ResponseStarted - Once the response headers are sent, but before the response body is sent. This stage is only generated for long-running requests (e.g. watch).
- ResponseComplete - The response body has been completed and no more bytes will be sent.
- Panic - Events generated when a panic occurred.
- None - don't log events that match this rule.
- Metadata - log request metadata (requesting user, timestamp, resource, verb, etc.) but not request or response body.
- Request - log event metadata and request body but not response body. This does not apply for non-resource requests.
- RequestResponse - log event metadata, request and response bodies. This does not apply for non-resource requests.
--audit-log-path
specifies the log file path that log backend uses to write audit events. Not specifying this flag disables log backend. - means standard out--audit-log-maxage
defined the maximum number of days to retain old audit log files--audit-log-maxbackup
defines the maximum number of audit log files to retain--audit-log-maxsize
defines the maximum size in megabytes of the audit log file before it gets rotated
Example of Audit with omitStages and filtering rules:
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
- "RequestReceived"
rules:
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
# Resource "pods" doesn't match requests to any subresource of pods,
# which is consistent with the RBAC policy.
resources: ["pods"]
# Log "pods/log", "pods/status" at Metadata level
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
Change the /etc/kubernetes/manifests/kube-apiserver.yaml
fields pointing to the audit configuration file:
--audit-policy-file=/etc/kubernetes/audit.yaml
--audit-log-path=/var/log/audit.log
NOTE: Don't forget to mount the host folder in the manifest.
Check the events filtered:
$ tail -n 1 /var/log/audit.log | jq .
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "17c3d2dc-99e6-4d59-a4ff-d88071329141",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/kube-system/pods/kube-controller-manager-kind-control-plane/status",
"verb": "patch",
"user": {
"username": "system:node:kind-control-plane",
"groups": [
"system:nodes",
"system:authenticated"
]
},
"sourceIPs": [
"172.18.0.2"
],
"userAgent": "kubelet/v1.19.1 (linux/amd64) kubernetes/206bcad",
"objectRef": {
"resource": "pods",
"namespace": "kube-system",
"name": "kube-controller-manager-kind-control-plane",
"apiVersion": "v1",
"subresource": "status"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2020-12-30T23:06:06.356455Z",
"stageTimestamp": "2020-12-30T23:06:06.360969Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": ""
}
}
References: