txt2stix 1.0.2__tar.gz → 1.0.3__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 (258) hide show
  1. {txt2stix-1.0.2 → txt2stix-1.0.3}/PKG-INFO +1 -1
  2. {txt2stix-1.0.2 → txt2stix-1.0.3}/pyproject.toml +1 -1
  3. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_attack_flow.py +133 -44
  4. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_main.py +15 -1
  5. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/attack_flow.py +25 -11
  6. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/txt2stix.py +2 -2
  7. {txt2stix-1.0.2 → txt2stix-1.0.3}/.env.example +0 -0
  8. {txt2stix-1.0.2 → txt2stix-1.0.3}/.env.markdown +0 -0
  9. {txt2stix-1.0.2 → txt2stix-1.0.3}/.github/workflows/create-release.yml +0 -0
  10. {txt2stix-1.0.2 → txt2stix-1.0.3}/.github/workflows/run-tests.yml +0 -0
  11. {txt2stix-1.0.2 → txt2stix-1.0.3}/.gitignore +0 -0
  12. {txt2stix-1.0.2 → txt2stix-1.0.3}/LICENSE +0 -0
  13. {txt2stix-1.0.2 → txt2stix-1.0.3}/README.md +0 -0
  14. {txt2stix-1.0.2 → txt2stix-1.0.3}/docs/README.md +0 -0
  15. {txt2stix-1.0.2 → txt2stix-1.0.3}/docs/stix-mapping.md +0 -0
  16. {txt2stix-1.0.2 → txt2stix-1.0.3}/docs/txt2stix.png +0 -0
  17. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/__init__.py +0 -0
  18. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/extractions/ai/config.yaml +0 -0
  19. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/extractions/lookup/config.yaml +0 -0
  20. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/extractions/pattern/config.yaml +0 -0
  21. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/helpers/mimetype_filename_extension_list.csv +0 -0
  22. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/helpers/stix_relationship_types.txt +0 -0
  23. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/helpers/tlds.txt +0 -0
  24. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/helpers/windows_registry_key_prefix.txt +0 -0
  25. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/_README.md +0 -0
  26. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/_generate_lookups.py +0 -0
  27. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/attack_pattern.txt +0 -0
  28. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/campaign.txt +0 -0
  29. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/country_iso3166_alpha2.txt +0 -0
  30. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/course_of_action.txt +0 -0
  31. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/disarm_id_v1_5.txt +0 -0
  32. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/disarm_name_v1_5.txt +0 -0
  33. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/extensions.txt +0 -0
  34. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/identity.txt +0 -0
  35. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/infrastructure.txt +0 -0
  36. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/intrusion_set.txt +0 -0
  37. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/malware.txt +0 -0
  38. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_atlas_id_v4_5_2.txt +0 -0
  39. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_atlas_name_v4_5_2.txt +0 -0
  40. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_enterprise_aliases_v16_0.txt +0 -0
  41. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_enterprise_id_v16_0.txt +0 -0
  42. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_enterprise_name_v16_0.txt +0 -0
  43. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_ics_aliases_v16_0.txt +0 -0
  44. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_ics_id_v16_0.txt +0 -0
  45. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_ics_name_v16_0.txt +0 -0
  46. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_mobile_aliases_v16_0.txt +0 -0
  47. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_mobile_id_v16_0.txt +0 -0
  48. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_attack_mobile_name_v16_0.txt +0 -0
  49. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_capec_id_v3_9.txt +0 -0
  50. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_capec_name_v3_9.txt +0 -0
  51. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_cwe_id_v4_15.txt +0 -0
  52. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/mitre_cwe_name_v4_15.txt +0 -0
  53. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/threat_actor.txt +0 -0
  54. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/tld.txt +0 -0
  55. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/lookups/tool.txt +0 -0
  56. {txt2stix-1.0.2 → txt2stix-1.0.3}/includes/tests/test_cases.yaml +0 -0
  57. {txt2stix-1.0.2 → txt2stix-1.0.3}/requirements.txt +0 -0
  58. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/README.md +0 -0
  59. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/ai_country.txt +0 -0
  60. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/ai_mitre_attack_enterprise.txt +0 -0
  61. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/ai_mitre_attack_ics.txt +0 -0
  62. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/ai_mitre_attack_mobile.txt +0 -0
  63. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/ai_mitre_capec.txt +0 -0
  64. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/ai_mitre_cwe.txt +0 -0
  65. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/all_cases.txt +0 -0
  66. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_autonomous_system_number.txt +0 -0
  67. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_all.txt +0 -0
  68. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_amex.txt +0 -0
  69. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_diners.txt +0 -0
  70. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_discover.txt +0 -0
  71. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_jcb.txt +0 -0
  72. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_mastercard.txt +0 -0
  73. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_union_pay.txt +0 -0
  74. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_bank_card_visa.txt +0 -0
  75. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_country_alpha2.txt +0 -0
  76. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cpe_uri.txt +0 -0
  77. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cryptocurrency_btc_transaction.txt +0 -0
  78. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cryptocurrency_btc_wallet.txt +0 -0
  79. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cryptocurrency_eth_transaction.txt +0 -0
  80. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cryptocurrency_eth_wallet.txt +0 -0
  81. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cryptocurrency_xmr_transaction.txt +0 -0
  82. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cryptocurrency_xmr_wallet.txt +0 -0
  83. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_cve_id.txt +0 -0
  84. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_directory_unix.txt +0 -0
  85. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_directory_unix_file.txt +0 -0
  86. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_directory_windows.txt +0 -0
  87. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_directory_windows_with_file.txt +0 -0
  88. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_disarm.txt +0 -0
  89. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_disarm_name.txt +0 -0
  90. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_domain_name_only.txt +0 -0
  91. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_domain_name_subdomain.txt +0 -0
  92. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_email_address.txt +0 -0
  93. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_hash_md5.txt +0 -0
  94. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_hash_sha_1.txt +0 -0
  95. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_hash_sha_224.txt +0 -0
  96. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_hash_sha_256.txt +0 -0
  97. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_hash_sha_384.txt +0 -0
  98. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_hash_sha_512.txt +0 -0
  99. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_file_name.txt +0 -0
  100. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_host_name.txt +0 -0
  101. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_host_name_file.txt +0 -0
  102. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_host_name_path.txt +0 -0
  103. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_host_name_subdomain.txt +0 -0
  104. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_host_name_url.txt +0 -0
  105. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_iban_number.txt +0 -0
  106. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_ipv4_address_cidr.txt +0 -0
  107. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_ipv4_address_only.txt +0 -0
  108. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_ipv4_address_port.txt +0 -0
  109. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_ipv6_address_cidr.txt +0 -0
  110. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_ipv6_address_only.txt +0 -0
  111. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_ipv6_address_port.txt +0 -0
  112. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mac_address.txt +0 -0
  113. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_atlas.txt +0 -0
  114. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_atlas_name.txt +0 -0
  115. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_enterprise.txt +0 -0
  116. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_enterprise_aliases.txt +0 -0
  117. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_enterprise_name.txt +0 -0
  118. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_ics.txt +0 -0
  119. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_ics_aliases.txt +0 -0
  120. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_ics_name.txt +0 -0
  121. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_mobile.txt +0 -0
  122. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_mobile_aliases.txt +0 -0
  123. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_attack_mobile_name.txt +0 -0
  124. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_capec.txt +0 -0
  125. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_capec_name.txt +0 -0
  126. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_cwe.txt +0 -0
  127. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_mitre_cwe_name.txt +0 -0
  128. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_phone_number.txt +0 -0
  129. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_url.txt +0 -0
  130. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_url_file.txt +0 -0
  131. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_url_path.txt +0 -0
  132. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_user_agent.txt +0 -0
  133. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/generic_windows_registry_key.txt +0 -0
  134. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_attack_pattern.txt +0 -0
  135. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_campaign.txt +0 -0
  136. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_course_of_action.txt +0 -0
  137. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_identity.txt +0 -0
  138. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_infrastructure.txt +0 -0
  139. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_intrusion_set.txt +0 -0
  140. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_malware.txt +0 -0
  141. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_threat_actor.txt +0 -0
  142. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/extraction_types/lookup_tool.txt +0 -0
  143. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/attack_flow_demo.txt +0 -0
  144. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/attack_navigator_demo.txt +0 -0
  145. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/basic_relationship.txt +0 -0
  146. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/char_length_too_long.txt +0 -0
  147. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/descriptive_for_ai_relationships_1.txt +0 -0
  148. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/disarm_demo.txt +0 -0
  149. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/embedded_img_ignore.txt +0 -0
  150. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/embedded_link_ignore.txt +0 -0
  151. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/ip1.txt +0 -0
  152. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/ip2.txt +0 -0
  153. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/known_whitelist_match.txt +0 -0
  154. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/mitre_attack_enterprise_ai_demo.txt +0 -0
  155. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/mitre_attack_enterprise_lookup_demo.txt +0 -0
  156. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/mixed_extractions.txt +0 -0
  157. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/not_security_content.txt +0 -0
  158. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/test_ai_hash_error_with_stix2_lib.txt +0 -0
  159. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/test_aliases.txt +0 -0
  160. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/test_extraction_boundary.txt +0 -0
  161. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/manually_generated_reports/test_extraction_escapes.txt +0 -0
  162. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/APT28-Center-of-Storm-2017.txt +0 -0
  163. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/Bitdefender-Labs-Report-X-creat6958-en-EN.txt +0 -0
  164. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/FireEyeAPT39.txt +0 -0
  165. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/France_CERT_APT31_Pakdoor_TLPWHITE.txt +0 -0
  166. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/Group-IB_Ransomware_Uncovered_whitepaper_eng.txt +0 -0
  167. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/JOINT_CSA_HUNTING_RU_INTEL_SNAKE_MALWARE_20230509.txt +0 -0
  168. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/TA22-0126-QAKBOT-analysis-TLP-GREEN.txt +0 -0
  169. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/dinners_card.txt +0 -0
  170. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/mandiant-apt1.txt +0 -0
  171. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/data/real_intel_reports/mykings_report_final.txt +0 -0
  172. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/manual-tests/cases-ai-relationships.md +0 -0
  173. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/manual-tests/cases-extraction-type-ai.md +0 -0
  174. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/manual-tests/cases-extraction-type-lookup.md +0 -0
  175. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/manual-tests/cases-extraction-type-pattern.md +0 -0
  176. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/manual-tests/cases-standard-tests.md +0 -0
  177. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/scripts/generate_simple_extraction_test_cases_txt_files.py +0 -0
  178. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/__init__.py +0 -0
  179. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_bundler.py +0 -0
  180. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_extractors.py +0 -0
  181. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_indicator.py +0 -0
  182. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_lookups.py +0 -0
  183. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_run_txt2stix.py +0 -0
  184. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/test_utils.py +0 -0
  185. {txt2stix-1.0.2 → txt2stix-1.0.3}/tests/src/utils.py +0 -0
  186. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/__init__.py +0 -0
  187. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/__init__.py +0 -0
  188. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/anthropic.py +0 -0
  189. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/base.py +0 -0
  190. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/deepseek.py +0 -0
  191. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/gemini.py +0 -0
  192. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/openai.py +0 -0
  193. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/openrouter.py +0 -0
  194. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/prompts.py +0 -0
  195. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/ai_extractor/utils.py +0 -0
  196. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/bundler.py +0 -0
  197. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/common.py +0 -0
  198. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/extractions.py +0 -0
  199. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/indicator.py +0 -0
  200. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/lookups.py +0 -0
  201. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/__init__.py +0 -0
  202. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/__init__.py +0 -0
  203. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/base_extractor.py +0 -0
  204. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/README.md +0 -0
  205. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/__init__.py +0 -0
  206. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/amex_card_extractor.py +0 -0
  207. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/diners_card_extractor.py +0 -0
  208. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/discover_card_extractor.py +0 -0
  209. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/jcb_card_extractor.py +0 -0
  210. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/master_card_extractor.py +0 -0
  211. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/union_card_extractor.py +0 -0
  212. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/card/visa_card_extractor.py +0 -0
  213. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/crypto/__init__.py +0 -0
  214. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/crypto/btc_extractor.py +0 -0
  215. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/directory/__init__.py +0 -0
  216. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/directory/unix_directory_extractor.py +0 -0
  217. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/directory/unix_file_path_extractor.py +0 -0
  218. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/directory/windows_directory_path_extractor.py +0 -0
  219. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/directory/windows_file_path_extractor.py +0 -0
  220. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/domain/__init__.py +0 -0
  221. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/domain/domain_extractor.py +0 -0
  222. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/domain/hostname_extractor.py +0 -0
  223. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/domain/sub_domain_extractor.py +0 -0
  224. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/__init__.py +0 -0
  225. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/md5_extractor.py +0 -0
  226. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/sha1_extractor.py +0 -0
  227. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/sha224_extractor.py +0 -0
  228. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/sha2_256_exactor.py +0 -0
  229. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/sha2_512_exactor.py +0 -0
  230. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/sha3_256_exactor.py +0 -0
  231. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/hashes/sha3_512_exactor.py +0 -0
  232. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/helper.py +0 -0
  233. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/__init__.py +0 -0
  234. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/ipv4_cidr_extractor.py +0 -0
  235. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/ipv4_extractor.py +0 -0
  236. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/ipv4_port_extractor.py +0 -0
  237. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/ipv6_cidr_extractor.py +0 -0
  238. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/ipv6_extractor.py +0 -0
  239. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/ip/ipv6_port_extractor.py +0 -0
  240. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/__init__.py +0 -0
  241. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/asn_extractor.py +0 -0
  242. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/cpe_extractor.py +0 -0
  243. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/cve_extractor.py +0 -0
  244. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/email_extractor.py +0 -0
  245. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/filename_extractor.py +0 -0
  246. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/iban_extractor.py +0 -0
  247. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/mac_address_extractor.py +0 -0
  248. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/phonenumber_extractor.py +0 -0
  249. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/user_agent_extractor.py +0 -0
  250. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/others/windows_registry_key_extractor.py +0 -0
  251. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/url/__init__.py +0 -0
  252. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/url/url_extractor.py +0 -0
  253. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/url/url_file_extractor.py +0 -0
  254. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/pattern/extractors/url/url_path_extractor.py +0 -0
  255. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/retriever.py +0 -0
  256. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/stix.py +0 -0
  257. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix/utils.py +0 -0
  258. {txt2stix-1.0.2 → txt2stix-1.0.3}/txt2stix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: txt2stix
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: txt2stix is a Python script that is designed to identify and extract IoCs and TTPs from text files, identify the relationships between them, convert them to STIX 2.1 objects, and output as a STIX 2.1 bundle.
5
5
  Project-URL: Homepage, https://github.com/muchdogesec/txt2stix
6
6
  Project-URL: Issues, https://github.com/muchdogesec/txt2stix/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "txt2stix"
7
- version = "1.0.2"
7
+ version = "1.0.3"
8
8
  authors = [{ name = "dogesec" }]
9
9
  maintainers = [{ name = "dogesec" }]
10
10
  description = "txt2stix is a Python script that is designed to identify and extract IoCs and TTPs from text files, identify the relationships between them, convert them to STIX 2.1 objects, and output as a STIX 2.1 bundle."
@@ -3,9 +3,7 @@ import pytest
3
3
  from unittest.mock import MagicMock, patch
4
4
  from stix2extensions._extensions import attack_flow_ExtensionDefinitionSMO
5
5
 
6
- from txt2stix.ai_extractor.utils import (
7
- AttackFlowList,
8
- )
6
+ from txt2stix.ai_extractor.utils import AttackFlowList, AttackFlowItem
9
7
  from txt2stix.attack_flow import (
10
8
  create_navigator_layer,
11
9
  get_all_tactics,
@@ -55,6 +53,7 @@ def test_parse_flow__no_success(dummy_report):
55
53
  success=False,
56
54
  matrix="enterprise",
57
55
  items=[],
56
+ tactic_selection=[],
58
57
  ),
59
58
  None,
60
59
  None,
@@ -71,28 +70,28 @@ def test_get_techniques_from_extracted_objects(dummy_objects):
71
70
  "T0814": {
72
71
  "domain": "ics-attack",
73
72
  "name": "Denial of Service",
74
- "possible_tactics": {"TA0107": "inhibit-response-function"},
73
+ "possible_tactics": {"inhibit-response-function": "TA0107"},
75
74
  "id": "T0814",
76
75
  "platforms": [],
77
76
  },
78
77
  "T0887": {
79
78
  "domain": "ics-attack",
80
79
  "name": "Wireless Sniffing",
81
- "possible_tactics": {"TA0102": "discovery" , "TA0100": "collection"},
80
+ "possible_tactics": {"discovery": "TA0102", "collection": "TA0100"},
82
81
  "id": "T0887",
83
82
  "platforms": [],
84
83
  },
85
84
  "T1505.001": {
86
85
  "domain": "enterprise-attack",
87
86
  "name": "SQL Stored Procedures",
88
- "possible_tactics": {"TA0003":"persistence"},
87
+ "possible_tactics": {"persistence": "TA0003"},
89
88
  "id": "T1505.001",
90
89
  "platforms": ["Windows", "Linux"],
91
90
  },
92
91
  "T1555.002": {
93
92
  "domain": "enterprise-attack",
94
93
  "name": "Securityd Memory",
95
- "possible_tactics": {"TA0006": "credential-access"},
94
+ "possible_tactics": {"credential-access": "TA0006"},
96
95
  "id": "T1555.002",
97
96
  "platforms": ["Linux", "macOS"],
98
97
  },
@@ -202,15 +201,36 @@ def test_create_navigator_layer(dummy_report):
202
201
  "TA91": "exfiltration",
203
202
  }
204
203
  flow.items = [
205
- SimpleNamespace(attack_technique_id="T0001", attack_tactic_id="TA01"),
206
- SimpleNamespace(attack_technique_id="T0002", attack_tactic_id="TA02"),
207
- SimpleNamespace(attack_technique_id="T0003", attack_tactic_id="TA03"),
208
- SimpleNamespace(attack_technique_id="T1001", attack_tactic_id="TA11"),
209
- SimpleNamespace(attack_technique_id="T1002", attack_tactic_id="TA12"),
210
- SimpleNamespace(attack_technique_id="T1003", attack_tactic_id="TA25"),
211
- SimpleNamespace(attack_technique_id="T2001", attack_tactic_id="TA11"),
212
- SimpleNamespace(attack_technique_id="T2002", attack_tactic_id="TA123"),
213
- SimpleNamespace(attack_technique_id="T2003", attack_tactic_id="TA91"),
204
+ SimpleNamespace(
205
+ attack_technique_id="T0001",
206
+ attack_tactic_id="TA01",
207
+ description="description 1",
208
+ ),
209
+ SimpleNamespace(
210
+ attack_technique_id="T0003",
211
+ attack_tactic_id="TA03",
212
+ description="description 2",
213
+ ),
214
+ SimpleNamespace(
215
+ attack_technique_id="T1001",
216
+ attack_tactic_id="TA11",
217
+ description="description 3",
218
+ ),
219
+ SimpleNamespace(
220
+ attack_technique_id="T1002",
221
+ attack_tactic_id="TA12",
222
+ description="description 4",
223
+ ),
224
+ SimpleNamespace(
225
+ attack_technique_id="T2001",
226
+ attack_tactic_id="TA11",
227
+ description="description 28jhsjhs",
228
+ ),
229
+ SimpleNamespace(
230
+ attack_technique_id="T2003",
231
+ attack_tactic_id="TA91",
232
+ description="description sasa",
233
+ ),
214
234
  ]
215
235
  techniques = {
216
236
  "T0001": dict(
@@ -239,18 +259,25 @@ def test_create_navigator_layer(dummy_report):
239
259
  "name": "some markdown document",
240
260
  "domain": "enterprise-attack",
241
261
  "description": "this is a summary",
242
- "techniques": [
243
- {"techniqueID": "T0001", "tactic": "initial-access"},
244
- {"techniqueID": "T0002", "tactic": "lateral-movement"},
245
- {"techniqueID": "T0003", "tactic": "command-and-control"},
246
- ],
262
+ "techniques": [],
247
263
  "gradient": {
248
264
  "colors": ["#ffffff", "#ff6666"],
249
265
  "minValue": 0,
250
266
  "maxValue": 100,
251
267
  },
252
268
  "legendItems": [],
253
- "metadata": [],
269
+ "metadata": [
270
+ {
271
+ "name": "report_id",
272
+ "value": "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
273
+ }
274
+ ],
275
+ "links": [
276
+ {
277
+ "label": "Generated using txt2stix",
278
+ "url": "https://github.com/muchdogesec/txt2stix/",
279
+ }
280
+ ],
254
281
  "layout": {"layout": "side"},
255
282
  },
256
283
  {
@@ -258,18 +285,25 @@ def test_create_navigator_layer(dummy_report):
258
285
  "name": "some markdown document",
259
286
  "domain": "ics-attack",
260
287
  "description": "this is a summary",
261
- "techniques": [
262
- {"techniqueID": "T1001", "tactic": "initial-access"},
263
- {"techniqueID": "T1002", "tactic": "lateral-movement"},
264
- {"techniqueID": "T1003", "tactic": "command-and-control"},
265
- ],
288
+ "techniques": [],
266
289
  "gradient": {
267
290
  "colors": ["#ffffff", "#ff6666"],
268
291
  "minValue": 0,
269
292
  "maxValue": 100,
270
293
  },
271
294
  "legendItems": [],
272
- "metadata": [],
295
+ "metadata": [
296
+ {
297
+ "name": "report_id",
298
+ "value": "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
299
+ }
300
+ ],
301
+ "links": [
302
+ {
303
+ "label": "Generated using txt2stix",
304
+ "url": "https://github.com/muchdogesec/txt2stix/",
305
+ }
306
+ ],
273
307
  "layout": {"layout": "side"},
274
308
  },
275
309
  {
@@ -277,18 +311,25 @@ def test_create_navigator_layer(dummy_report):
277
311
  "name": "some markdown document",
278
312
  "domain": "mobile-attack",
279
313
  "description": "this is a summary",
280
- "techniques": [
281
- {"techniqueID": "T2001", "tactic": "initial-access"},
282
- {"techniqueID": "T2002", "tactic": "persistence"},
283
- {"techniqueID": "T2003", "tactic": "exfiltration"},
284
- ],
314
+ "techniques": [],
285
315
  "gradient": {
286
316
  "colors": ["#ffffff", "#ff6666"],
287
317
  "minValue": 0,
288
318
  "maxValue": 100,
289
319
  },
290
320
  "legendItems": [],
291
- "metadata": [],
321
+ "metadata": [
322
+ {
323
+ "name": "report_id",
324
+ "value": "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
325
+ }
326
+ ],
327
+ "links": [
328
+ {
329
+ "label": "Generated using txt2stix",
330
+ "url": "https://github.com/muchdogesec/txt2stix/",
331
+ }
332
+ ],
292
333
  "layout": {"layout": "side"},
293
334
  },
294
335
  ]
@@ -307,8 +348,20 @@ def test_create_navigator_layer__real_flow(dummy_report, dummy_flow, dummy_objec
307
348
  "domain": "ics-attack",
308
349
  "description": "a summary",
309
350
  "techniques": [
310
- {"techniqueID": "T0814", "tactic": "inhibit-response-function"},
311
- {"techniqueID": "T0887", "tactic": "discovery"},
351
+ {
352
+ "techniqueID": "T0814",
353
+ "tactic": "inhibit-response-function",
354
+ "score": 100,
355
+ "showSubtechniques": True,
356
+ "comment": "The SQL injection requests lead to a denial of service condition, disrupting the availability of the targeted service.",
357
+ },
358
+ {
359
+ "techniqueID": "T0887",
360
+ "tactic": "discovery",
361
+ "score": 100,
362
+ "showSubtechniques": True,
363
+ "comment": "The attack begins by using Wireshark to sniff network packets with a specific source, indicating a reconnaissance or discovery phase to gather information about the network traffic.",
364
+ },
312
365
  ],
313
366
  "gradient": {
314
367
  "colors": ["#ffffff", "#ff6666"],
@@ -316,7 +369,18 @@ def test_create_navigator_layer__real_flow(dummy_report, dummy_flow, dummy_objec
316
369
  "maxValue": 100,
317
370
  },
318
371
  "legendItems": [],
319
- "metadata": [],
372
+ "metadata": [
373
+ {
374
+ "name": "report_id",
375
+ "value": "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
376
+ }
377
+ ],
378
+ "links": [
379
+ {
380
+ "label": "Generated using txt2stix",
381
+ "url": "https://github.com/muchdogesec/txt2stix/",
382
+ }
383
+ ],
320
384
  "layout": {"layout": "side"},
321
385
  },
322
386
  {
@@ -325,8 +389,20 @@ def test_create_navigator_layer__real_flow(dummy_report, dummy_flow, dummy_objec
325
389
  "domain": "enterprise-attack",
326
390
  "description": "a summary",
327
391
  "techniques": [
328
- {"techniqueID": "T1505.001", "tactic": "persistence"},
329
- {"techniqueID": "T1555.002", "tactic": "credential-access"},
392
+ {
393
+ "techniqueID": "T1505.001",
394
+ "tactic": "persistence",
395
+ "score": 100,
396
+ "showSubtechniques": True,
397
+ "comment": "A series of SQL injection requests are sent to a specific port, potentially to establish persistence or manipulate database operations.",
398
+ },
399
+ {
400
+ "techniqueID": "T1555.002",
401
+ "tactic": "credential-access",
402
+ "score": 100,
403
+ "showSubtechniques": True,
404
+ "comment": "An additional method is employed to bypass Securityd, likely to gain unauthorized access to credentials or sensitive information.",
405
+ },
330
406
  ],
331
407
  "gradient": {
332
408
  "colors": ["#ffffff", "#ff6666"],
@@ -334,7 +410,18 @@ def test_create_navigator_layer__real_flow(dummy_report, dummy_flow, dummy_objec
334
410
  "maxValue": 100,
335
411
  },
336
412
  "legendItems": [],
337
- "metadata": [],
413
+ "metadata": [
414
+ {
415
+ "name": "report_id",
416
+ "value": "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
417
+ }
418
+ ],
419
+ "links": [
420
+ {
421
+ "label": "Generated using txt2stix",
422
+ "url": "https://github.com/muchdogesec/txt2stix/",
423
+ }
424
+ ],
338
425
  "layout": {"layout": "side"},
339
426
  },
340
427
  ]
@@ -623,33 +710,35 @@ def dummy_flow():
623
710
  "items": [
624
711
  {
625
712
  "position": 0,
626
- "attack_tactic_id": "TA0102",
627
713
  "attack_technique_id": "T0887",
628
714
  "name": "Packet Sniffing with Wireshark",
629
715
  "description": "The attack begins by using Wireshark to sniff network packets with a specific source, indicating a reconnaissance or discovery phase to gather information about the network traffic.",
630
716
  },
631
717
  {
632
718
  "position": 1,
633
- "attack_tactic_id": "TA0003",
634
719
  "attack_technique_id": "T1505.001",
635
720
  "name": "SQL Injection for Persistence",
636
721
  "description": "A series of SQL injection requests are sent to a specific port, potentially to establish persistence or manipulate database operations.",
637
722
  },
638
723
  {
639
724
  "position": 2,
640
- "attack_tactic_id": "TA0107",
641
725
  "attack_technique_id": "T0814",
642
726
  "name": "Denial of Service via SQLi",
643
727
  "description": "The SQL injection requests lead to a denial of service condition, disrupting the availability of the targeted service.",
644
728
  },
645
729
  {
646
730
  "position": 3,
647
- "attack_tactic_id": "TA0006",
648
731
  "attack_technique_id": "T1555.002",
649
732
  "name": "Bypassing Securityd",
650
733
  "description": "An additional method is employed to bypass Securityd, likely to gain unauthorized access to credentials or sensitive information.",
651
734
  },
652
735
  ],
653
736
  "success": True,
737
+ "tactic_selection": [
738
+ ("T0887", "discovery"),
739
+ ("T1505.001", "persistence"),
740
+ ("T0814", "inhibit-response-function"),
741
+ ("T1555.002", "credential-access"),
742
+ ],
654
743
  }
655
744
  )
@@ -146,7 +146,21 @@ def test_parse_args_fails(monkeypatch):
146
146
  "standard",
147
147
  "--ai_create_attack_flow",
148
148
  ])
149
- with pytest.raises(argparse.ArgumentError, match="--ai_create_attack_flow requires --ai_settings_relationships"):
149
+ with pytest.raises(argparse.ArgumentError, match="argument --ai_create_attack_flow: --ai_settings_relationships must be set"):
150
+ parse_args()
151
+
152
+
153
+ monkeypatch.setattr(sys, 'argv', [
154
+ "program",
155
+ "--input-file",
156
+ tmp.name,
157
+ "--name",
158
+ "a",
159
+ "--relationship_mode",
160
+ "standard",
161
+ "--ai_create_attack_navigator_layer",
162
+ ])
163
+ with pytest.raises(argparse.ArgumentError, match="argument --ai_create_attack_navigator_layer: --ai_settings_relationships must be set"):
150
164
  parse_args()
151
165
 
152
166
  monkeypatch.setattr(sys, 'argv', [
@@ -21,14 +21,14 @@ def parse_flow(report, flow: AttackFlowList, techniques, tactics):
21
21
  for i, item in enumerate(flow.items):
22
22
  try:
23
23
  technique = techniques[item.attack_technique_id]
24
- tactic_id = technique['possible_tactics'][flow.tactic_mapping[item.attack_technique_id]]
24
+ tactic_id = technique["possible_tactics"][
25
+ flow.tactic_mapping[item.attack_technique_id]
26
+ ]
25
27
  technique_obj = technique["stix_obj"]
26
28
  tactic_obj = tactics[technique["domain"]][tactic_id]
27
29
  action_obj = AttackAction(
28
30
  **{
29
- "id": flow_id(
30
- report["id"], item.attack_technique_id, tactic_id
31
- ),
31
+ "id": flow_id(report["id"], item.attack_technique_id, tactic_id),
32
32
  "effect_refs": [f"attack-action--{str(uuid.uuid4())}"],
33
33
  "technique_id": item.attack_technique_id,
34
34
  "technique_ref": technique_obj["id"],
@@ -149,14 +149,21 @@ def get_techniques_from_extracted_objects(objects: dict, tactics: dict):
149
149
 
150
150
  def create_navigator_layer(report, summary, flow: AttackFlowList, techniques):
151
151
  domains = {}
152
+ comments = {item.attack_technique_id: item.description for item in flow.items}
152
153
  for technique in techniques.values():
153
154
  domain_techniques = domains.setdefault(technique["domain"], [])
154
155
  technique_id = technique["id"]
155
156
  if technique_id not in flow.tactic_mapping:
156
157
  continue
157
- domain_techniques.append(
158
- dict(techniqueID=technique_id, tactic=flow.tactic_mapping[technique_id])
158
+ technique_item = dict(
159
+ techniqueID=technique_id,
160
+ tactic=flow.tactic_mapping[technique_id],
161
+ score=100,
162
+ showSubtechniques=True,
159
163
  )
164
+ if comment := comments.get(technique_id):
165
+ technique_item["comment"] = comment
166
+ domain_techniques.append(technique_item)
160
167
 
161
168
  retval = []
162
169
 
@@ -174,7 +181,13 @@ def create_navigator_layer(report, summary, flow: AttackFlowList, techniques):
174
181
  "maxValue": 100,
175
182
  },
176
183
  "legendItems": [],
177
- "metadata": [],
184
+ "metadata": [{"name": "report_id", "value": report.id}],
185
+ "links": [
186
+ {
187
+ "label": "Generated using txt2stix",
188
+ "url": "https://github.com/muchdogesec/txt2stix/",
189
+ }
190
+ ],
178
191
  "layout": {"layout": "side"},
179
192
  }
180
193
  )
@@ -192,9 +205,8 @@ def extract_attack_flow_and_navigator(
192
205
  tactics = get_all_tactics()
193
206
  techniques = get_techniques_from_extracted_objects(bundler.bundle.objects, tactics)
194
207
  logged_techniques = [
195
- {k: v for k, v in t.items() if k != "stix_obj"}
196
- for t in techniques.values()
197
- ]
208
+ {k: v for k, v in t.items() if k != "stix_obj"} for t in techniques.values()
209
+ ]
198
210
  logging.debug(f"parsed techniques: {json.dumps(logged_techniques, indent=4)}")
199
211
 
200
212
  flow = ex.extract_attack_flow(preprocessed_text, techniques)
@@ -204,5 +216,7 @@ def extract_attack_flow_and_navigator(
204
216
  bundler.flow_objects = parse_flow(bundler.report, flow, techniques, tactics)
205
217
 
206
218
  if ai_create_attack_navigator_layer:
207
- navigator = create_navigator_layer(bundler.report, bundler.summary, flow, techniques)
219
+ navigator = create_navigator_layer(
220
+ bundler.report, bundler.summary, flow, techniques
221
+ )
208
222
  return flow, navigator
@@ -440,11 +440,11 @@ def main():
440
440
  output_path = output_dir/f"{bundler.bundle.id}.json"
441
441
  output_path.write_text(out)
442
442
  logger.info(f"Wrote bundle output to `{output_path}`")
443
- data_path = output_dir/"data.json"
443
+ data_path = output_dir/f"data--{args.report_id}.json"
444
444
  data_path.write_text(data.model_dump_json(indent=4))
445
445
  logger.info(f"Wrote data output to `{data_path}`")
446
446
  for nav_layer in data.navigator_layer or []:
447
- nav_path = output_dir/f"navigator-{nav_layer['domain']}.json"
447
+ nav_path = output_dir/f"navigator-{nav_layer['domain']}----{args.report_id}.json"
448
448
  nav_path.write_text(json.dumps(nav_layer, indent=4))
449
449
  logger.info(f"Wrote navigator output to `{nav_path}`")
450
450
  except argparse.ArgumentError as e:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes