Skip to content

feat: add Falco rules and tests for Linux persistence techniques (refs #37)#41

Draft
JJcyborg wants to merge 2 commits into
mainfrom
feat/issue-37-persistence-monitoring
Draft

feat: add Falco rules and tests for Linux persistence techniques (refs #37)#41
JJcyborg wants to merge 2 commits into
mainfrom
feat/issue-37-persistence-monitoring

Conversation

@JJcyborg

@JJcyborg JJcyborg commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Adds 18 Falco detection rules covering 6 required + 4 bonus persistence categories from the InternalAllTheThings reference:

  • Cron/At jobs (T1053.003, T1053.005)
  • SSH authorized_keys (T1098.004, T1078)
  • Systemd services (T1543.002, T1053.006)
  • Bash profile/RC (T1546.004, T1546.005, T1037.001)
  • LD_PRELOAD/LD_LIBRARY_PATH (T1574.006)
  • Setuid/Setgid (T1548.001)
  • PAM module config (T1546.003)
  • User account creation (T1136.001)
  • Password file direct edit
  • XDG Autostart (T1547.001)

Includes 114 test cases. Closes #37

@JJcyborg JJcyborg left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: PR #41 — Falco Persistence Detection Rules

Overall this is a solid and well-structured contribution. The rules cover the 6 required persistence categories plus 4 bonus ones, tests pass (114/114), YAML syntax is valid, and the structure is consistent. However, there is one factual inaccuracy and a few quality issues that should be addressed before merging.

Must-fix

1. Incorrect MITRE tag T1546.005 on "Shell Profile or RC File Modification"

  • T1546.005 is "Event Triggered Execution: Trap" (Unix signal trapping), NOT shell profile/rc file modification. This is a factual tagging error.
  • The header comment also mislabels T1546.005 as ".bashrc and .bash_profile".
  • Fix: Remove T1546.005 from the tags on this rule. The rule already has T1546.004 which correctly covers shell profile modification. If you want system-wide shell profile coverage here too, add T1546.003 (Unix Shell Configuration Modification) or adjust accordingly.

Should-fix

2. Four unused list definitions (dead code)

  • cron_directories, ssh_authorized_keys_paths, shell_profile_files, systemd_service_directories are defined as Falco lists but never referenced in any rule condition. The rules use inline fd.name startswith/endswith conditions instead.
  • Fix: Either refactor conditions to use these lists via macros, or remove the unused lists to avoid confusion.

3. Rule name "etc ld.so.preload File Write" looks like a truncated path

  • Missing the leading / makes it look like a file path with the root stripped.
  • Fix: Rename to ld.so.preload File Write or /etc/ld.so.preload File Write.

4. Duplicate persistence_rules fixture in conftest.py and test file

  • Both tests/conftest.py and tests/test_persistence_detection.py define a persistence_rules fixture. The local one shadows the conftest one, making the conftest fixture dead code.
  • Fix: Remove the fixture from conftest.py (the test-local version is better since it loads directly from the file path), or remove it from the test file and use the conftest version.

Nit / Informational

5. False positive risk in LD_PRELOAD rule

  • proc.env contains "LD_PRELOAD=." matches any LD_PRELOAD value containing a dot character, including legitimate paths like /usr/lib/libfoo.so. Consider tightening to specific suspicious path prefixes.

6. Bonus rules (PAM, useradd, password file, XDG autostart, ld.so.conf) are not in REQUIRED_RULES

  • These 5 additional rules are excluded from tag validation tests. Consider adding them to REQUIRED_RULES or a separate BONUS_RULES dict to ensure their MITRE tags are also verified.

What looks good

  • 18 Falco rules covering 10 persistence techniques — comprehensive coverage
  • Valid Falco YAML syntax throughout (verified with Python yaml.safe_load)
  • All rules have required fields: desc, condition, output, priority, tags
  • MITRE tags for 6 core categories are correct (T1053.003, T1053.005, T1098.004, T1543.002, T1546.004, T1574.006, T1548.001)
  • Priority levels are appropriate (CRITICAL for ld.so.preload writes, WARNING for most, NOTICE for lower-risk events)
  • Good allow-list hygiene (excluding package managers, config management tools, shell binaries)
  • 114 test cases all passing
  • Clean test structure with parametrized validation

…ete unused Falco lists, deduplicate fixture, fix rule name, tighten LD_PRELOAD condition
@JJcyborg

JJcyborg commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed all review feedback:

  • Removed incorrect T1546.005 tag from Shell Profile rules (T1546.004 covers this; T1546.005 = Trap, not shell profile)
  • Deleted 4 unused Falco lists: cron_directories, ssh_authorized_keys_paths, shell_profile_files, systemd_service_directories
  • Deduplicated fixture — now only defined in conftest.py, removed from test file
  • Fixed rule name: "etc ld.so.preload File Write" → "/etc/ld.so.preload File Write"
  • Tightened LD_PRELOAD condition: replaced over-broad LD_PRELOAD=. with LD_PRELOAD=./ and LD_PRELOAD=../
  • Added test: test_no_t1546_005_in_shell_profile_rules verifies T1546.005 is not present
  • Added test: test_all_lists_referenced_in_conditions ensures no dead list definitions

All 113 tests passing. Ready for re-review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorporate monitoring for persistence techniques

1 participant