redgap 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. redgap-0.1.0/.gitignore +33 -0
  2. redgap-0.1.0/LICENSE +21 -0
  3. redgap-0.1.0/NOTICE +46 -0
  4. redgap-0.1.0/PKG-INFO +153 -0
  5. redgap-0.1.0/README.md +103 -0
  6. redgap-0.1.0/docs/DEPLOY.md +56 -0
  7. redgap-0.1.0/docs/architecture.md +41 -0
  8. redgap-0.1.0/docs/architecture.svg +78 -0
  9. redgap-0.1.0/docs/index.html +483 -0
  10. redgap-0.1.0/docs/samples/baseline/coverage.json +158 -0
  11. redgap-0.1.0/docs/samples/baseline/coverage.md +31 -0
  12. redgap-0.1.0/docs/samples/baseline/navigator-layer.json +127 -0
  13. redgap-0.1.0/docs/samples/demo.txt +20 -0
  14. redgap-0.1.0/docs/samples/fixed/coverage.json +171 -0
  15. redgap-0.1.0/docs/samples/fixed/coverage.md +31 -0
  16. redgap-0.1.0/docs/samples/fixed/navigator-layer.json +127 -0
  17. redgap-0.1.0/fixtures/replay/T1057/events.jsonl +3 -0
  18. redgap-0.1.0/fixtures/replay/T1057/provenance.json +16 -0
  19. redgap-0.1.0/fixtures/replay/T1057/raw/exec.log +3 -0
  20. redgap-0.1.0/fixtures/replay/T1070.006/events.jsonl +5 -0
  21. redgap-0.1.0/fixtures/replay/T1070.006/provenance.json +18 -0
  22. redgap-0.1.0/fixtures/replay/T1070.006/raw/exec.log +5 -0
  23. redgap-0.1.0/fixtures/replay/T1087.001/events.jsonl +3 -0
  24. redgap-0.1.0/fixtures/replay/T1087.001/provenance.json +16 -0
  25. redgap-0.1.0/fixtures/replay/T1087.001/raw/exec.log +3 -0
  26. redgap-0.1.0/fixtures/replay/T1136.001/events.jsonl +5 -0
  27. redgap-0.1.0/fixtures/replay/T1136.001/provenance.json +18 -0
  28. redgap-0.1.0/fixtures/replay/T1136.001/raw/exec.log +5 -0
  29. redgap-0.1.0/fixtures/replay/T1548.001/events.jsonl +9 -0
  30. redgap-0.1.0/fixtures/replay/T1548.001/provenance.json +19 -0
  31. redgap-0.1.0/fixtures/replay/T1548.001/raw/exec.log +9 -0
  32. redgap-0.1.0/lab/Dockerfile +30 -0
  33. redgap-0.1.0/lab/collector/redgap_exec.c +82 -0
  34. redgap-0.1.0/lab/compose.yaml +24 -0
  35. redgap-0.1.0/pyproject.toml +68 -0
  36. redgap-0.1.0/rules/proc_creation_lnx_setgid_setuid.yml +32 -0
  37. redgap-0.1.0/rules/redgap/account_discovery_etc_passwd.yml +36 -0
  38. redgap-0.1.0/rules/redgap/create_account_useradd.yml +32 -0
  39. redgap-0.1.0/rules/roundtrip/timestomp_touch.yml +32 -0
  40. redgap-0.1.0/scripts/gen_samples.py +41 -0
  41. redgap-0.1.0/src/redgap/__init__.py +9 -0
  42. redgap-0.1.0/src/redgap/_resources.py +44 -0
  43. redgap-0.1.0/src/redgap/allowlist.py +147 -0
  44. redgap-0.1.0/src/redgap/catalog.py +63 -0
  45. redgap-0.1.0/src/redgap/cli.py +134 -0
  46. redgap-0.1.0/src/redgap/detection/__init__.py +5 -0
  47. redgap-0.1.0/src/redgap/detection/coverage.py +133 -0
  48. redgap-0.1.0/src/redgap/detection/engine.py +276 -0
  49. redgap-0.1.0/src/redgap/detection/sigma_ast.py +238 -0
  50. redgap-0.1.0/src/redgap/engine_facade.py +75 -0
  51. redgap-0.1.0/src/redgap/lab.py +118 -0
  52. redgap-0.1.0/src/redgap/models.py +149 -0
  53. redgap-0.1.0/src/redgap/pipeline.py +68 -0
  54. redgap-0.1.0/src/redgap/planner.py +179 -0
  55. redgap-0.1.0/src/redgap/report/__init__.py +10 -0
  56. redgap-0.1.0/src/redgap/report/build.py +87 -0
  57. redgap-0.1.0/src/redgap/report/markdown.py +84 -0
  58. redgap-0.1.0/src/redgap/report/navigator.py +92 -0
  59. redgap-0.1.0/src/redgap/target.py +119 -0
  60. redgap-0.1.0/src/redgap/techniques/__init__.py +11 -0
  61. redgap-0.1.0/src/redgap/techniques/base.py +21 -0
  62. redgap-0.1.0/src/redgap/techniques/registry.py +277 -0
  63. redgap-0.1.0/src/redgap/telemetry/__init__.py +1 -0
  64. redgap-0.1.0/src/redgap/telemetry/schema.py +104 -0
  65. redgap-0.1.0/src/redgap/telemetry/snoopy.py +73 -0
  66. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/LICENSE +6 -0
  67. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/README.md +32 -0
  68. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_apt_shell_execution.yml +28 -0
  69. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_at_command.yml +28 -0
  70. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_auditctl_clear_rules.yml +26 -0
  71. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_av_kaspersky_av_disabled.yml +31 -0
  72. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_awk_shell_spawn.yml +38 -0
  73. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_base64_decode.yml +23 -0
  74. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_base64_execution.yml +34 -0
  75. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_base64_shebang_cli.yml +27 -0
  76. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_bash_interactive_shell.yml +23 -0
  77. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_bpf_kprob_tracing_enabled.yml +28 -0
  78. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_bpftrace_unsafe_option_usage.yml +23 -0
  79. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_cap_setgid.yml +29 -0
  80. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_cap_setuid.yml +29 -0
  81. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_capa_discovery.yml +25 -0
  82. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_capsh_shell_invocation.yml +24 -0
  83. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_chattr_immutable_removal.yml +25 -0
  84. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_chmod_targeting_sensitive_directories.yml +46 -0
  85. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_chroot_execution.yml +28 -0
  86. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_clear_logs.yml +37 -0
  87. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_clear_syslog.yml +87 -0
  88. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_clipboard_collection.yml +28 -0
  89. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_cp_passwd_or_shadow_tmp.yml +28 -0
  90. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_crontab_enumeration.yml +25 -0
  91. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_crontab_removal.yml +23 -0
  92. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_crypto_mining.yml +42 -0
  93. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_curl_usage.yml +22 -0
  94. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_curl_wget_exec_tmp.yml +36 -0
  95. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_dd_file_overwrite.yml +30 -0
  96. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_dd_process_injection.yml +27 -0
  97. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_disable_ufw.yml +38 -0
  98. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_doas_execution.yml +22 -0
  99. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_env_shell_invocation.yml +30 -0
  100. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_network_discovery.yml +31 -0
  101. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_permission_change_admin.yml +29 -0
  102. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_storage_discovery.yml +32 -0
  103. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_syslog_config_change.yml +30 -0
  104. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_system_discovery.yml +30 -0
  105. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_user_account_creation.yml +27 -0
  106. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_vm_discovery.yml +29 -0
  107. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_vm_kill.yml +29 -0
  108. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_esxcli_vsan_discovery.yml +32 -0
  109. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_file_and_directory_discovery.yml +35 -0
  110. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_file_deletion.yml +25 -0
  111. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_find_shell_execution.yml +33 -0
  112. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_flock_shell_execution.yml +31 -0
  113. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_gcc_shell_execution.yml +36 -0
  114. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_git_shell_execution.yml +29 -0
  115. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_grep_os_arch_discovery.yml +33 -0
  116. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_groupdel.yml +24 -0
  117. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_install_root_certificate.yml +24 -0
  118. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_install_suspicious_packages.yml +49 -0
  119. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_iptables_flush_ufw.yml +41 -0
  120. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_local_account.yml +52 -0
  121. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_local_groups.yml +34 -0
  122. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_malware_gobrat_grep_payload_discovery.yml +28 -0
  123. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_mkfifo_named_pipe_creation.yml +21 -0
  124. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_mkfifo_named_pipe_creation_susp_location.yml +26 -0
  125. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_mount_hidepid.yml +27 -0
  126. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_netcat_reverse_shell.yml +59 -0
  127. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_nice_shell_execution.yml +29 -0
  128. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_nohup.yml +23 -0
  129. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_nohup_susp_execution.yml +27 -0
  130. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_omigod_scx_runasprovider_executescript.yml +35 -0
  131. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_omigod_scx_runasprovider_executeshellcommand.yml +33 -0
  132. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_perl_reverse_shell.yml +31 -0
  133. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_php_reverse_shell.yml +36 -0
  134. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_pnscan_binary_cli_pattern.yml +26 -0
  135. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_proxy_connection.yml +22 -0
  136. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_pua_trufflehog.yml +43 -0
  137. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_python_base64_encoded_execution.yml +43 -0
  138. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_python_http_server_execution.yml +36 -0
  139. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_python_pty_spawn.yml +38 -0
  140. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_python_reverse_shell.yml +32 -0
  141. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_python_shell_os_system.yml +38 -0
  142. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_remote_access_tools_teamviewer_incoming_connection.yml +31 -0
  143. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_remote_system_discovery.yml +46 -0
  144. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_remove_package.yml +42 -0
  145. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_rsync_shell_execution.yml +44 -0
  146. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_rsync_shell_spawn.yml +37 -0
  147. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_ruby_reverse_shell.yml +34 -0
  148. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_schedule_task_job_cron.yml +25 -0
  149. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_security_software_discovery.yml +34 -0
  150. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_security_tools_disabling.yml +83 -0
  151. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_services_stop_and_disable.yml +50 -0
  152. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_setgid_setuid.yml +27 -0
  153. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_ssh_shell_execution.yml +36 -0
  154. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_ssm_agent_abuse.yml +29 -0
  155. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_container_residence_discovery.yml +38 -0
  156. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_curl_fileupload.yml +42 -0
  157. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_curl_useragent.yml +28 -0
  158. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_dockerenv_recon.yml +32 -0
  159. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_exec_from_dev_shm.yml +29 -0
  160. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_execution_tmp_folder.yml +27 -0
  161. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_find_execution.yml +33 -0
  162. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_git_clone.yml +41 -0
  163. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_history_delete.yml +34 -0
  164. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_history_recon.yml +35 -0
  165. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_hktl_execution.yml +97 -0
  166. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_inod_listing.yml +31 -0
  167. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_interactive_bash.yml +35 -0
  168. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_java_children.yml +32 -0
  169. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_network_utilities_execution.yml +43 -0
  170. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_pipe_shell.yml +35 -0
  171. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_process_reading_sudoers.yml +34 -0
  172. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_recon_indicators.yml +25 -0
  173. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_script_interpretor_spawn_credential_scanner.yml +43 -0
  174. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_sensitive_file_access.yml +60 -0
  175. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_shell_child_process_from_parent_tmp_folder.yml +31 -0
  176. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_susp_shell_script_exec_from_susp_location.yml +35 -0
  177. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_system_info_discovery.yml +29 -0
  178. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_system_network_connections_discovery.yml +30 -0
  179. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_system_network_discovery.yml +33 -0
  180. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_systemctl_mask_power_settings.yml +32 -0
  181. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_touch_susp.yml +24 -0
  182. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_triple_cross_rootkit_execve_hijack.yml +22 -0
  183. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_triple_cross_rootkit_install.yml +27 -0
  184. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_userdel.yml +24 -0
  185. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_usermod_susp_group.yml +25 -0
  186. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_vim_shell_execution.yml +52 -0
  187. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_webshell_detection.yml +50 -0
  188. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_wget_download_suspicious_directory.yml +29 -0
  189. redgap-0.1.0/tests/corpus/sigmahq_linux_process_creation/proc_creation_lnx_xterm_reverse_shell.yml +24 -0
  190. redgap-0.1.0/tests/test_allowlist.py +152 -0
  191. redgap-0.1.0/tests/test_coverage.py +84 -0
  192. redgap-0.1.0/tests/test_determinism.py +47 -0
  193. redgap-0.1.0/tests/test_engine_golden.py +128 -0
  194. redgap-0.1.0/tests/test_engine_semantics.py +264 -0
  195. redgap-0.1.0/tests/test_engine_semantics2.py +161 -0
  196. redgap-0.1.0/tests/test_fixture_integrity.py +69 -0
  197. redgap-0.1.0/tests/test_import_hygiene.py +38 -0
  198. redgap-0.1.0/tests/test_pipeline.py +45 -0
  199. redgap-0.1.0/tests/test_planner.py +121 -0
  200. redgap-0.1.0/tests/test_report.py +91 -0
  201. redgap-0.1.0/tests/test_rule_loading.py +53 -0
  202. redgap-0.1.0/tests/test_setuid_inert.py +100 -0
  203. redgap-0.1.0/tests/test_sigma_ast_smoke.py +89 -0
  204. redgap-0.1.0/tests/test_sigmahq_corpus.py +70 -0
  205. redgap-0.1.0/tests/test_snoopy.py +69 -0
  206. redgap-0.1.0/tests/test_techniques.py +38 -0
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+ env/
11
+
12
+ # Tooling
13
+ .pytest_cache/
14
+ .ruff_cache/
15
+ .mypy_cache/
16
+ .coverage
17
+ htmlcov/
18
+
19
+ # Secrets / local config — never commit an API key
20
+ .env
21
+ *.key
22
+ secrets.*
23
+
24
+ # OS / editor
25
+ .DS_Store
26
+ Thumbs.db
27
+ .idea/
28
+ .vscode/
29
+
30
+ # Runtime output (reports are regenerated; only committed samples live under docs/ or fixtures/)
31
+ out/
32
+ out-*/
33
+ *.tmp
redgap-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 befnoz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
redgap-0.1.0/NOTICE ADDED
@@ -0,0 +1,46 @@
1
+ RedGap — third-party components and attributions
2
+ =================================================
3
+
4
+ RedGap itself is licensed under the MIT License (see LICENSE).
5
+
6
+ This project depends on, references, or derives benign test procedures from the
7
+ following third-party works. Each remains under its own license; RedGap claims
8
+ no ownership of them and thanks their authors.
9
+
10
+ Runtime dependencies
11
+ --------------------
12
+ - pySigma (SigmaHQ) — LGPL-2.1 — Sigma rule parsing.
13
+ https://github.com/SigmaHQ/pySigma
14
+ - Typer — MIT — command-line interface.
15
+ - Rich — MIT — terminal rendering.
16
+ - PyYAML — MIT — YAML loading.
17
+
18
+ Optional dependency
19
+ --------------------
20
+ - anthropic (Anthropic SDK) — MIT — optional LLM orchestration only.
21
+
22
+ Detection content
23
+ -----------------
24
+ - Sigma community rules (SigmaHQ) are distributed under the Detection Rule
25
+ License (DRL-1.1). Any SigmaHQ rule vendored under rules/ retains its original
26
+ header, author, and license reference. See:
27
+ https://github.com/SigmaHQ/sigma/blob/master/LICENSE.Detection.Rules.md
28
+ - The full SigmaHQ linux/process_creation ruleset (122 rules) is vendored verbatim
29
+ under tests/corpus/sigmahq_linux_process_creation/ as TEST INPUT only (engine
30
+ validation), under DRL-1.1. Source commit and refresh steps are in that directory's
31
+ README. These rules are not loaded at runtime.
32
+
33
+ Technique provenance
34
+ -------------------
35
+ - The benign techniques executed by RedGap are derived from Atomic Red Team
36
+ (Red Canary), MIT License. RedGap runs only well-known, published, benign
37
+ detection tests against its own disposable local lab — never novel offense.
38
+ https://github.com/redcanaryco/atomic-red-team
39
+
40
+ Telemetry / tooling referenced (not redistributed)
41
+ --------------------------------------------------
42
+ - snoopy (a2o/snoopy) — GPL-2.0 — execve command logger used as
43
+ an independent telemetry collector in the lab image.
44
+ - Sysmon for Linux (Microsoft) — MIT — optional high-fidelity collector.
45
+ - MITRE ATT&CK / ATT&CK Navigator layer format — MITRE terms of use. ATT&CK(R) is
46
+ a registered trademark of The MITRE Corporation.
redgap-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.5
2
+ Name: redgap
3
+ Version: 0.1.0
4
+ Summary: Automated, MITRE ATT&CK-mapped offense<->detection coverage harness. Finds the red gaps in your detection coverage.
5
+ Author: befnoz
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 befnoz
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ License-File: LICENSE
28
+ License-File: NOTICE
29
+ Keywords: coverage,detection-engineering,mitre-attack,purple-team,security,sigma
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Intended Audience :: Information Technology
32
+ Classifier: Programming Language :: Python :: 3.11
33
+ Classifier: Programming Language :: Python :: 3.12
34
+ Classifier: Programming Language :: Python :: 3.13
35
+ Classifier: Topic :: Security
36
+ Requires-Python: >=3.11
37
+ Requires-Dist: pysigma==1.5.0
38
+ Requires-Dist: pyyaml>=6.0
39
+ Requires-Dist: rich>=13.7
40
+ Requires-Dist: typer>=0.12
41
+ Provides-Extra: dev
42
+ Requires-Dist: mypy>=1.11; extra == 'dev'
43
+ Requires-Dist: pre-commit>=3.8; extra == 'dev'
44
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
45
+ Requires-Dist: pytest>=8; extra == 'dev'
46
+ Requires-Dist: ruff>=0.6; extra == 'dev'
47
+ Provides-Extra: llm
48
+ Requires-Dist: anthropic>=0.40; extra == 'llm'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # RedGap
52
+
53
+ **Find the red gaps in your detection coverage.**
54
+
55
+ RedGap is an automated, MITRE ATT&CK-mapped **offense↔detection coverage harness**. It runs a small set of *benign* ATT&CK techniques against its own disposable local lab, collects real telemetry with an **independent collector**, and then **deterministically** — from logs and Sigma rules, with no AI in the loop — decides whether each technique was *detected* or is a *gap*. The output is a coverage report (`technique → detected? → gap type`) plus an ATT&CK Navigator layer.
56
+
57
+ The name is the output: in the coverage grid, detected techniques are green and gaps are **red**. RedGap finds the red.
58
+
59
+ [![CI](https://github.com/befnoz/redgap/actions/workflows/ci.yml/badge.svg)](https://github.com/befnoz/redgap/actions/workflows/ci.yml)
60
+ <!-- Uncomment once Pages is enabled / the package is on PyPI: -->
61
+ <!-- [![Live demo](https://img.shields.io/badge/demo-live-2e7d32)](https://befnoz.github.io/redgap/) -->
62
+ <!-- [![PyPI](https://img.shields.io/pypi/v/redgap)](https://pypi.org/project/redgap/) -->
63
+
64
+ > **v0.1 — what this is and is not.** RedGap v0.1 is a deterministic harness over a *fixed* set of techniques. It is **not** an autonomous agent that continuously attacks and adapts. Adaptive, gap-driven technique chaining (the agent choosing its next attack from the last result) is the honest **next step**, tracked on the roadmap. Precise scope on purpose.
65
+
66
+ **Status.** RedGap's own parser + evaluator ingests **all 122 real SigmaHQ `linux/process_creation` rules** with zero parser errors and zero evaluator crashes — that ruleset is vendored under [`tests/corpus/`](tests/corpus/sigmahq_linux_process_creation/) and checked by [`test_sigmahq_corpus.py`](tests/test_sigmahq_corpus.py), so the claim is reproducible, not asserted. **290 tests** run fully offline in CI. Coverage is computed from **5 committed real-telemetry captures** — one per technique, each with a raw log + parsed events + sha256 provenance — not authored logs. See [docs/architecture.md](docs/architecture.md) · committed output in [docs/samples/](docs/samples/).
67
+
68
+ ---
69
+
70
+ ## The one idea: the verdict is not the AI's to make
71
+
72
+ Every `detected` verdict is a **pure function of `(logs, rules)`**, computed and written to disk **before** any language model is ever called. An optional LLM planner may (a) choose the order of techniques and decide when to stop, and (b) narrate the report. It **cannot** decide whether something was detected — both the deterministic and the LLM planner return the engine's coverage, never model text. A test asserts the coverage report is byte-identical with and without the LLM.
73
+
74
+ This is deliberate. LLMs hallucinate confident verdicts; a coverage tool whose ground truth an LLM can fabricate is worthless. RedGap draws the trust boundary in code.
75
+
76
+ ![RedGap architecture — the deterministic pipeline, with the optional LLM planner drawn outside the verdict path](docs/architecture.svg)
77
+
78
+ The verdict is a pure function of logs and rules, written to disk **before** any model runs. The LLM (dashed red) can only order techniques and narrate — it sits **outside** the verdict path.
79
+
80
+ ---
81
+
82
+ ## Quickstart (offline, no API key, no cloud)
83
+
84
+ The default path is `REPLAY`: it re-evaluates **real telemetry captured from a prior live run** (committed as fixtures with provenance) through the exact same engine used in LIVE mode. No Docker, no key, no network.
85
+
86
+ ```bash
87
+ pip install redgap
88
+ redgap run # REPLAY: prints the coverage table + writes out/coverage.{json,md} + navigator-layer.json
89
+ ```
90
+
91
+ From source instead (or before the first PyPI release):
92
+
93
+ ```bash
94
+ git clone https://github.com/befnoz/redgap && cd redgap
95
+ pip install -e .
96
+ redgap run
97
+ ```
98
+
99
+ **Live dashboard:** the same coverage, as an interactive web page — `https://befnoz.github.io/redgap/` (see [docs/DEPLOY.md](docs/DEPLOY.md) to switch it on).
100
+
101
+ To run the real thing against the local Docker lab:
102
+
103
+ ```bash
104
+ redgap run --live # brings up the disposable lab, executes techniques, captures fresh telemetry
105
+ ```
106
+
107
+ To try the optional LLM planner (needs the `llm` extra and `ANTHROPIC_API_KEY`):
108
+
109
+ ```bash
110
+ pip install -e ".[llm]" # adds the optional anthropic SDK
111
+ redgap run --llm # equivalently: COVERAGE_LLM=1 redgap run
112
+ ```
113
+
114
+ The committed `coverage.json` is identical whichever planner ran — a test asserts it.
115
+
116
+ ---
117
+
118
+ ## What a run shows
119
+
120
+ A v0.1 run is a five-technique mini kill-chain that deliberately produces **both** detections and gaps — and two *different kinds* of gap, because a coverage tool that is all-green is just a checklist:
121
+
122
+ | # | ATT&CK | Tactic | Result |
123
+ |---|--------|--------|--------|
124
+ | 1 | T1087.001 Account Discovery: Local | Discovery | detected |
125
+ | 2 | T1057 Process Discovery | Discovery | **gap (base-rate)** — too noisy for a single-event rule; needs correlation (roadmap) |
126
+ | 3 | T1136.001 Create Account: Local | Persistence | detected |
127
+ | 4 | T1548.001 Setuid/Setgid | Priv. Esc / Defense Evasion | detected (matches a shipped SigmaHQ rule) |
128
+ | 5 | T1070.006 Timestomp | Defense Evasion | **gap (rule)** → closed live in the remediation round-trip |
129
+
130
+ **The remediation round-trip** is the point: technique 5 fires but no rule catches it (a *rule gap*). Write one Sigma rule, re-run the same command, and watch the verdict flip red→green. Both the before and after coverage reports are committed — RedGap is a tool that finds a real blind spot and closes it, not a status printer.
131
+
132
+ ---
133
+
134
+ ## Ethics & scope
135
+
136
+ ⚠️ **RedGap attacks only its own disposable local lab.** There is deliberately no free-form target flag; the live lab runs with **no network**, and every container launch is gated at runtime by an allowlist (`assert_lab_only`) that the test suite proves cannot be widened. Every technique is a benign, published Atomic-Red-Team-derived detection test with no exploit payload, no off-box action, and no runtime downloads. See [ETHICS.md](ETHICS.md), [SCOPE.md](SCOPE.md), and [SECURITY.md](SECURITY.md).
137
+
138
+ Not shipped: weaponizable breadth, real exploits, credential material, or anything that runs against a system you do not own.
139
+
140
+ ---
141
+
142
+ ## Roadmap (honest next steps)
143
+
144
+ - Adaptive, gap-driven technique chaining (agent picks the next attack from the last verdict).
145
+ - Effect / syscall-level detection (e.g. `utimensat` for timestomp) via a higher-fidelity collector.
146
+ - Correlation rules (turn the base-rate gap into a real detection).
147
+ - Portability: the rules are standard Sigma, so they already run unchanged in Zircolite or any SIEM.
148
+
149
+ ---
150
+
151
+ ## License
152
+
153
+ MIT — see [LICENSE](LICENSE). Third-party attributions in [NOTICE](NOTICE). ATT&CK® is a registered trademark of The MITRE Corporation.
redgap-0.1.0/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # RedGap
2
+
3
+ **Find the red gaps in your detection coverage.**
4
+
5
+ RedGap is an automated, MITRE ATT&CK-mapped **offense↔detection coverage harness**. It runs a small set of *benign* ATT&CK techniques against its own disposable local lab, collects real telemetry with an **independent collector**, and then **deterministically** — from logs and Sigma rules, with no AI in the loop — decides whether each technique was *detected* or is a *gap*. The output is a coverage report (`technique → detected? → gap type`) plus an ATT&CK Navigator layer.
6
+
7
+ The name is the output: in the coverage grid, detected techniques are green and gaps are **red**. RedGap finds the red.
8
+
9
+ [![CI](https://github.com/befnoz/redgap/actions/workflows/ci.yml/badge.svg)](https://github.com/befnoz/redgap/actions/workflows/ci.yml)
10
+ <!-- Uncomment once Pages is enabled / the package is on PyPI: -->
11
+ <!-- [![Live demo](https://img.shields.io/badge/demo-live-2e7d32)](https://befnoz.github.io/redgap/) -->
12
+ <!-- [![PyPI](https://img.shields.io/pypi/v/redgap)](https://pypi.org/project/redgap/) -->
13
+
14
+ > **v0.1 — what this is and is not.** RedGap v0.1 is a deterministic harness over a *fixed* set of techniques. It is **not** an autonomous agent that continuously attacks and adapts. Adaptive, gap-driven technique chaining (the agent choosing its next attack from the last result) is the honest **next step**, tracked on the roadmap. Precise scope on purpose.
15
+
16
+ **Status.** RedGap's own parser + evaluator ingests **all 122 real SigmaHQ `linux/process_creation` rules** with zero parser errors and zero evaluator crashes — that ruleset is vendored under [`tests/corpus/`](tests/corpus/sigmahq_linux_process_creation/) and checked by [`test_sigmahq_corpus.py`](tests/test_sigmahq_corpus.py), so the claim is reproducible, not asserted. **290 tests** run fully offline in CI. Coverage is computed from **5 committed real-telemetry captures** — one per technique, each with a raw log + parsed events + sha256 provenance — not authored logs. See [docs/architecture.md](docs/architecture.md) · committed output in [docs/samples/](docs/samples/).
17
+
18
+ ---
19
+
20
+ ## The one idea: the verdict is not the AI's to make
21
+
22
+ Every `detected` verdict is a **pure function of `(logs, rules)`**, computed and written to disk **before** any language model is ever called. An optional LLM planner may (a) choose the order of techniques and decide when to stop, and (b) narrate the report. It **cannot** decide whether something was detected — both the deterministic and the LLM planner return the engine's coverage, never model text. A test asserts the coverage report is byte-identical with and without the LLM.
23
+
24
+ This is deliberate. LLMs hallucinate confident verdicts; a coverage tool whose ground truth an LLM can fabricate is worthless. RedGap draws the trust boundary in code.
25
+
26
+ ![RedGap architecture — the deterministic pipeline, with the optional LLM planner drawn outside the verdict path](docs/architecture.svg)
27
+
28
+ The verdict is a pure function of logs and rules, written to disk **before** any model runs. The LLM (dashed red) can only order techniques and narrate — it sits **outside** the verdict path.
29
+
30
+ ---
31
+
32
+ ## Quickstart (offline, no API key, no cloud)
33
+
34
+ The default path is `REPLAY`: it re-evaluates **real telemetry captured from a prior live run** (committed as fixtures with provenance) through the exact same engine used in LIVE mode. No Docker, no key, no network.
35
+
36
+ ```bash
37
+ pip install redgap
38
+ redgap run # REPLAY: prints the coverage table + writes out/coverage.{json,md} + navigator-layer.json
39
+ ```
40
+
41
+ From source instead (or before the first PyPI release):
42
+
43
+ ```bash
44
+ git clone https://github.com/befnoz/redgap && cd redgap
45
+ pip install -e .
46
+ redgap run
47
+ ```
48
+
49
+ **Live dashboard:** the same coverage, as an interactive web page — `https://befnoz.github.io/redgap/` (see [docs/DEPLOY.md](docs/DEPLOY.md) to switch it on).
50
+
51
+ To run the real thing against the local Docker lab:
52
+
53
+ ```bash
54
+ redgap run --live # brings up the disposable lab, executes techniques, captures fresh telemetry
55
+ ```
56
+
57
+ To try the optional LLM planner (needs the `llm` extra and `ANTHROPIC_API_KEY`):
58
+
59
+ ```bash
60
+ pip install -e ".[llm]" # adds the optional anthropic SDK
61
+ redgap run --llm # equivalently: COVERAGE_LLM=1 redgap run
62
+ ```
63
+
64
+ The committed `coverage.json` is identical whichever planner ran — a test asserts it.
65
+
66
+ ---
67
+
68
+ ## What a run shows
69
+
70
+ A v0.1 run is a five-technique mini kill-chain that deliberately produces **both** detections and gaps — and two *different kinds* of gap, because a coverage tool that is all-green is just a checklist:
71
+
72
+ | # | ATT&CK | Tactic | Result |
73
+ |---|--------|--------|--------|
74
+ | 1 | T1087.001 Account Discovery: Local | Discovery | detected |
75
+ | 2 | T1057 Process Discovery | Discovery | **gap (base-rate)** — too noisy for a single-event rule; needs correlation (roadmap) |
76
+ | 3 | T1136.001 Create Account: Local | Persistence | detected |
77
+ | 4 | T1548.001 Setuid/Setgid | Priv. Esc / Defense Evasion | detected (matches a shipped SigmaHQ rule) |
78
+ | 5 | T1070.006 Timestomp | Defense Evasion | **gap (rule)** → closed live in the remediation round-trip |
79
+
80
+ **The remediation round-trip** is the point: technique 5 fires but no rule catches it (a *rule gap*). Write one Sigma rule, re-run the same command, and watch the verdict flip red→green. Both the before and after coverage reports are committed — RedGap is a tool that finds a real blind spot and closes it, not a status printer.
81
+
82
+ ---
83
+
84
+ ## Ethics & scope
85
+
86
+ ⚠️ **RedGap attacks only its own disposable local lab.** There is deliberately no free-form target flag; the live lab runs with **no network**, and every container launch is gated at runtime by an allowlist (`assert_lab_only`) that the test suite proves cannot be widened. Every technique is a benign, published Atomic-Red-Team-derived detection test with no exploit payload, no off-box action, and no runtime downloads. See [ETHICS.md](ETHICS.md), [SCOPE.md](SCOPE.md), and [SECURITY.md](SECURITY.md).
87
+
88
+ Not shipped: weaponizable breadth, real exploits, credential material, or anything that runs against a system you do not own.
89
+
90
+ ---
91
+
92
+ ## Roadmap (honest next steps)
93
+
94
+ - Adaptive, gap-driven technique chaining (agent picks the next attack from the last verdict).
95
+ - Effect / syscall-level detection (e.g. `utimensat` for timestomp) via a higher-fidelity collector.
96
+ - Correlation rules (turn the base-rate gap into a real detection).
97
+ - Portability: the rules are standard Sigma, so they already run unchanged in Zircolite or any SIEM.
98
+
99
+ ---
100
+
101
+ ## License
102
+
103
+ MIT — see [LICENSE](LICENSE). Third-party attributions in [NOTICE](NOTICE). ATT&CK® is a registered trademark of The MITRE Corporation.
@@ -0,0 +1,56 @@
1
+ # Deploying RedGap
2
+
3
+ Two independent things: the **web dashboard** (GitHub Pages) and the **`pip install redgap`**
4
+ package (PyPI). Both are wired with GitHub Actions; you only do a little one-time setup.
5
+
6
+ ## 1. Web dashboard → GitHub Pages
7
+
8
+ `docs/index.html` is a self-contained dashboard (no external assets). It renders the real
9
+ coverage output — the ATT&CK heatmap, the coverage table, and the `--fix` round-trip toggle.
10
+
11
+ **One-time:** repo **Settings → Pages → Source = "GitHub Actions"**.
12
+
13
+ After that, every push to `main` that touches `docs/**` runs `.github/workflows/pages.yml`
14
+ and publishes to:
15
+
16
+ ```
17
+ https://<your-username>.github.io/redgap/
18
+ ```
19
+
20
+ That URL is the clickable proof to put in the CES application. (Prefer the branch method
21
+ instead? Settings → Pages → "Deploy from a branch" → `main` → `/docs` also works — then you
22
+ can delete `pages.yml`.)
23
+
24
+ ## 2. `pip install redgap` → PyPI
25
+
26
+ The package is already wheel/sdist-clean (`python -m build` + `twine check` pass, and CI's
27
+ `install-smoke` job proves a non-editable install runs from any directory).
28
+
29
+ **First, check the name is free:** open <https://pypi.org/project/redgap/>. If it is taken,
30
+ rename the project in `pyproject.toml` (`name = "..."`, e.g. `redgap-coverage`) and update the
31
+ `url:` lines in `.github/workflows/publish.yml`.
32
+
33
+ **Set up Trusted Publishing (recommended — no tokens/secrets):**
34
+ 1. On PyPI: your account → **Publishing** → **Add a pending publisher**.
35
+ 2. Fill in: PyPI project name `redgap`, owner = your GitHub user, repository `redgap`,
36
+ workflow `publish.yml`, environment `pypi`.
37
+ 3. Save. (A "pending" publisher lets the very first release create the project.)
38
+
39
+ **Release:**
40
+ ```bash
41
+ git tag v0.1.0
42
+ git push origin v0.1.0
43
+ ```
44
+ The tag fires `.github/workflows/publish.yml`, which builds and publishes. Then anyone can:
45
+ ```bash
46
+ pip install redgap
47
+ ```
48
+
49
+ **Token fallback** (if you skip Trusted Publishing): create a PyPI API token, add it as the
50
+ repo secret `PYPI_API_TOKEN`, and pass `with: { password: ${{ secrets.PYPI_API_TOKEN }} }` to
51
+ the `pypa/gh-action-pypi-publish` step.
52
+
53
+ ## Update the version
54
+
55
+ Bump `version` in `pyproject.toml`, then tag `v<that version>`. Keep the tag and the
56
+ `pyproject.toml` version in sync.
@@ -0,0 +1,41 @@
1
+ # Architecture
2
+
3
+ ![RedGap architecture](architecture.svg)
4
+
5
+ RedGap runs a small set of benign, MITRE ATT&CK-mapped techniques against a disposable
6
+ lab, collects real process-execution telemetry with an **independent** collector, and
7
+ decides — deterministically, from logs and Sigma rules — whether each technique was
8
+ *detected* or is a *gap*.
9
+
10
+ ## The trust boundary
11
+
12
+ The single load-bearing property is that the `detected` verdict is a **pure function of
13
+ `(events, rules)`**, computed and written to disk **before** any language model is
14
+ called. The optional LLM planner may choose the order of techniques and narrate the
15
+ report; it drives the same validated tool executor the deterministic planner uses and
16
+ **cannot** produce or change a verdict. `tests/test_planner.py` asserts the coverage is
17
+ byte-identical with and without the LLM — even when the model finishes early, runs a
18
+ subset, or requests a technique that does not exist.
19
+
20
+ ## The pieces
21
+
22
+ | Component | File | Role |
23
+ |-----------|------|------|
24
+ | Technique catalog | `src/redgap/catalog.py`, `techniques/registry.py` | 5 benign techniques + their commands and cleanup |
25
+ | Lab | `lab/`, `src/redgap/lab.py` | Disposable Docker container + a ~40-line `LD_PRELOAD` execve collector |
26
+ | Target | `src/redgap/target.py` | `ReplayTarget` (committed real fixtures, offline) / `LiveDockerTarget` |
27
+ | Telemetry | `src/redgap/telemetry/` | snoopy-format parser → SigmaHQ `process_creation` events |
28
+ | Detection | `src/redgap/detection/` | pySigma parser + RedGap's own AST evaluator; coverage join |
29
+ | Planner | `src/redgap/planner.py` | Heuristic (default) / LLM (optional), one `ToolExecutor` |
30
+ | Report | `src/redgap/report/` | `coverage.json`, `coverage.md`, ATT&CK Navigator layer |
31
+
32
+ ## Two modes, one engine
33
+
34
+ - **REPLAY** (default): re-evaluate committed real-telemetry fixtures. Offline, no key,
35
+ no Docker — what CI runs and what a reviewer reproduces in one command.
36
+ - **LIVE** (`--live`): bring up the Docker lab, execute the techniques, capture fresh
37
+ telemetry, and run the **same** engine.
38
+
39
+ Fixtures are verbatim captures with `provenance.json` (sha256, kernel, image id, exact
40
+ commands, timestamp) and are regenerable via `redgap capture`; the nightly LIVE CI job
41
+ re-captures on a clean runner so the fixtures are auditable, not hand-authored.
@@ -0,0 +1,78 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 360" font-family="-apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif">
2
+ <defs>
3
+ <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
4
+ <path d="M0,0 L10,5 L0,10 z" fill="#57606a"/>
5
+ </marker>
6
+ <marker id="arrowR" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
7
+ <path d="M0,0 L10,5 L0,10 z" fill="#cf222e"/>
8
+ </marker>
9
+ </defs>
10
+
11
+ <rect x="0" y="0" width="900" height="360" fill="#ffffff"/>
12
+ <text x="24" y="34" font-size="18" font-weight="700" fill="#1f2328">RedGap — offense &#8596; detection coverage</text>
13
+ <text x="24" y="54" font-size="12" fill="#57606a">The verdict is deterministic; the LLM is an optional layer that sits outside it.</text>
14
+
15
+ <!-- optional LLM box -->
16
+ <rect x="330" y="88" width="380" height="52" rx="8" fill="#fdeff0" stroke="#cf222e" stroke-width="1.5" stroke-dasharray="6 4"/>
17
+ <text x="520" y="110" font-size="13" font-weight="700" fill="#cf222e" text-anchor="middle">LLM planner &#183; optional</text>
18
+ <text x="520" y="128" font-size="11" fill="#a4404a" text-anchor="middle">orders techniques &#183; narrates &#8212; cannot set a verdict</text>
19
+
20
+ <!-- pipeline boxes -->
21
+ <g font-size="13" font-weight="700" fill="#1f2328">
22
+ <g>
23
+ <rect x="20" y="200" width="120" height="80" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
24
+ <text x="80" y="234" text-anchor="middle">Technique</text>
25
+ <text x="80" y="250" text-anchor="middle">catalog</text>
26
+ <text x="80" y="268" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">5 benign &#183; MITRE</text>
27
+ </g>
28
+ <g>
29
+ <rect x="168" y="200" width="120" height="80" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
30
+ <text x="228" y="242" text-anchor="middle">Lab</text>
31
+ <text x="228" y="262" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">Docker &#183; Replay</text>
32
+ </g>
33
+ <g>
34
+ <rect x="316" y="200" width="120" height="80" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
35
+ <text x="376" y="234" text-anchor="middle">Collector</text>
36
+ <text x="376" y="250" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">independent</text>
37
+ <text x="376" y="266" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">execve &#8594; events</text>
38
+ </g>
39
+ <g>
40
+ <rect x="464" y="200" width="120" height="80" rx="8" fill="#e9f6ef" stroke="#1a7f4b" stroke-width="1.5"/>
41
+ <text x="524" y="234" text-anchor="middle" fill="#12633a">Sigma engine</text>
42
+ <text x="524" y="252" text-anchor="middle" font-size="10.5" font-weight="700" fill="#1a7f4b">deterministic</text>
43
+ <text x="524" y="268" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">verdict = f(logs, rules)</text>
44
+ </g>
45
+ <g>
46
+ <rect x="612" y="200" width="120" height="80" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
47
+ <text x="672" y="242" text-anchor="middle">Coverage</text>
48
+ <text x="672" y="262" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">detected / gap</text>
49
+ </g>
50
+ <g>
51
+ <rect x="760" y="200" width="120" height="80" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
52
+ <text x="820" y="234" text-anchor="middle">Reports</text>
53
+ <text x="820" y="252" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">JSON &#183; Markdown</text>
54
+ <text x="820" y="268" text-anchor="middle" font-size="10.5" font-weight="400" fill="#57606a">ATT&amp;CK Navigator</text>
55
+ </g>
56
+ </g>
57
+
58
+ <!-- pipeline arrows -->
59
+ <g stroke="#57606a" stroke-width="1.6" marker-end="url(#arrow)">
60
+ <line x1="140" y1="240" x2="166" y2="240"/>
61
+ <line x1="288" y1="240" x2="314" y2="240"/>
62
+ <line x1="436" y1="240" x2="462" y2="240"/>
63
+ <line x1="584" y1="240" x2="610" y2="240"/>
64
+ <line x1="732" y1="240" x2="758" y2="240"/>
65
+ </g>
66
+
67
+ <!-- LLM connectors (dashed, red) -->
68
+ <g stroke="#cf222e" stroke-width="1.4" stroke-dasharray="5 4" fill="none">
69
+ <path d="M400,140 C400,175 300,165 260,199" marker-end="url(#arrowR)"/>
70
+ <path d="M672,200 C672,168 640,150 632,141" marker-end="url(#arrowR)"/>
71
+ </g>
72
+ <text x="300" y="182" font-size="10" fill="#cf222e">chooses next</text>
73
+ <text x="686" y="176" font-size="10" fill="#cf222e" text-anchor="start">read-only</text>
74
+
75
+ <!-- caption -->
76
+ <text x="24" y="320" font-size="12" fill="#1f2328">The <tspan font-weight="700">detected / gap</tspan> verdict is a pure function of logs and Sigma rules, written to disk <tspan font-weight="700">before</tspan> any model is called.</text>
77
+ <text x="24" y="340" font-size="12" fill="#57606a">REPLAY re-evaluates real captured telemetry offline; a test asserts the coverage is byte-identical with and without the LLM.</text>
78
+ </svg>