Hari 41: Falco Attack Sim — 6 Alerts, Defense in Depth
5 min read

Hari 41: Falco Attack Sim — 6 Alerts, Defense in Depth

Attack simulation: shell, sensitive file, network tool, K8s API. Distroless blocks shell exec. 3/4 custom Falco rules fired (6 alerts). NetworkPolicy blocks egress. All 5 defense layers proven working.

devsecops
kubernetes
falco
attack simulation
defense in depth
Share

Day 40 buat 4 custom Falco rules. Hari ini test dengan attack simulation: eksekusi shell, baca file sensitif, jalankan network tool, contact K8s API. Hasilnya: 6 alerts fired, distroless blocks shell, NetworkPolicy blocks egress. Semua 5 defense layers proven working.

Test 1: Distroless Security Proof

Attempt shell exec pada SecureBank production pod (distroless):

$ kubectl exec -it <securebank-pod> -n securebank -- /bin/sh
error: "/bin/sh": stat /bin/sh: no such file or directory

$ kubectl exec -it <securebank-pod> -n securebank -- /bin/bash
error: "/bin/bash": stat /bin/bash: no such file or directory

$ kubectl exec -it <securebank-pod> -n securebank -- sh
error: "sh": executable file not found in $PATH

$ kubectl exec -it <securebank-pod> -n securebank -- ls
error: "ls": executable file not found in $PATH

Distroless = no shell, no ls, no utilities. Hanya binary /securebank yang ada. Attacker yang dapat RCE tidak bisa exec shell untuk pivot. Ini prevention, bukan detection.

Test 2: Attack Simulation — Alpine Attacker Pod

Deploy securebank:attacker (alpine tagged sebagai securebank image) dengan 4 attack scenarios:

# Attack script:
whoami                              # [1] Shell spawned
cat /etc/passwd                     # [2] Sensitive file read
wget http://securebank-api...:80    # [3] Network tool
wget https://kubernetes.default.svc # [4] K8s API access

Attacker output:

[1] whoami → root
[2] cat /etc/passwd → full passwd file (17 entries)
[3] wget securebank-api → Connection refused (NetworkPolicy blocks!)
[4] wget kubernetes.default.svc → Connection refused (NetworkPolicy blocks!)

NetworkPolicy (Day 37) bekerja — default-deny-all blocks egress. Both wget gagal karena hanya DNS egress yang di-allow.

MAJOR DISCOVERY: 6 Falco Alerts Fired!

[Critical] Sensitive file read in SecureBank
  file=/etc/passwd user=root pod=attacker-sim

[Warning] Shell spawned in SecureBank container
  command=sh -c echo "=== ATTACK SIMULATION START ==="...

[Critical] Sensitive file read in SecureBank  (2nd read)
[Critical] Sensitive file read in SecureBank  (3rd read)

[Notice] Network tool in SecureBank container
  tool=wget command=wget -qO- http://securebank-api.securebank.svc:80/health

[Notice] Network tool in SecureBank container
  tool=wget command=wget -qO- https://kubernetes.default.svc:443/

3 dari 4 custom rules fired! 6 alerts total: 1 WARNING + 3 CRITICAL + 2 NOTICE. Falcosidekick forwarded 5/6 alerts to WebUI (1 error pada first alert — Redis cold start).

k3d Tracepoint: PARTIAL Limitation (Correction from Day 39-40)

Day 39-40 document "k3d tracepoint limitation = rules can't trigger". Hari ini discovery: limitation is PARTIAL.

Syscall Tracepoint Status Rules Using It
execve sys_enter_execve ✅ Working Shell spawned, Network tool
openat sys_enter_openat ✅ Working Sensitive file read
connect sys_enter_connect ❌ Missing K8s API access

3/4 rules work. Hanya Rule 4 (K8s API access, butuh connect tracepoint) yang tidak fire.

Kenapa Day 40 test tidak fire? Timing issue — Falco pods baru restart dari helm upgrade (~3 menit), eBPF probe butuh warm-up time. Day 41 (25+ menit setelah upgrade), probe fully operational.

Defense in Depth: All 5 Layers Proven

Layer Tool Day Result
Prevention (admission) Gatekeeper 34-36 Pod tanpa resources = denied
Prevention (image) Distroless 18 No shell = attacker can't exec
Prevention (network) NetworkPolicy 37 Egress blocked = wget failed
Detection (runtime) Falco 39-41 6 alerts fired
Alert forwarding Falcosidekick 39 5/6 alerts to WebUI

Attack scenario: attacker compromises securebank container → no shell (distroless) → even if shell obtained (supply chain attack) → Falco detects shell + file access + network tool → NetworkPolicy blocks egress → alert forwarded to WebUI.

Before vs After

Aspek Before (Day 40) After (Day 41)
Custom rules tested Schema validation only 3/4 rules fired in real attack
k3d limitation "Total failure" "Partial — execve/openat work"
Distroless proof Documented only Verified: 4 exec attempts fail
NetworkPolicy proof Cross-ns blocked Egress blocked (wget refused)
Defense in depth Theoretical All 5 layers proven

Pelajaran Hari Ini

Distroless = prevention, Falco = detection. Distroless prevents shell exec. Falco detects if attacker somehow gets shell. Defense in depth: keduanya bekerja bersama.

k3d tracepoint limitation is PARTIAL. execve dan openat work, hanya connect missing. 3/4 custom rules fired. Correction dari Day 39-40 yang bilang "total failure".

eBPF probe warm-up time. Day 40 test tidak fire karena Falco pods baru restart. Day 41 (25+ min) = full operational. eBPF probe butuh waktu untuk attach semua tracepoints.

NetworkPolicy blocks egress in attack. Attacker's wget ke securebank-api dan K8s API both "Connection refused". Day 37 default-deny-all = attacker tidak bisa lateral movement atau data exfil.

Repo

Semua code dan dokumentasi ada di: https://github.com/stayrelevantid/chalange-devsecops

Kesimpulan

Attack simulation selesai dengan hasil melampaui ekspektasi. 6 Falco alerts fired (3/4 custom rules work). Distroless blocks shell exec. NetworkPolicy blocks egress. All 5 defense layers proven working together. k3d limitation corrected: PARTIAL, bukan total. Besok Day 42 — n8n webhook untuk alert forwarding ke Slack.

Enjoyed this article? Share it!

Share

Diskusi & Komentar

Artikel Terkait