txt2stix 1.0.8__tar.gz → 1.0.9__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 (260) hide show
  1. {txt2stix-1.0.8 → txt2stix-1.0.9}/PKG-INFO +1 -1
  2. {txt2stix-1.0.8 → txt2stix-1.0.9}/pyproject.toml +1 -1
  3. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/attack_flow_demo.txt +3 -1
  4. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/manual-tests/cases-standard-tests.md +18 -0
  5. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_attack_flow.py +76 -26
  6. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/attack_flow.py +16 -5
  7. {txt2stix-1.0.8 → txt2stix-1.0.9}/.env.example +0 -0
  8. {txt2stix-1.0.8 → txt2stix-1.0.9}/.env.markdown +0 -0
  9. {txt2stix-1.0.8 → txt2stix-1.0.9}/.github/workflows/create-release.yml +0 -0
  10. {txt2stix-1.0.8 → txt2stix-1.0.9}/.github/workflows/run-tests.yml +0 -0
  11. {txt2stix-1.0.8 → txt2stix-1.0.9}/.gitignore +0 -0
  12. {txt2stix-1.0.8 → txt2stix-1.0.9}/LICENSE +0 -0
  13. {txt2stix-1.0.8 → txt2stix-1.0.9}/README.md +0 -0
  14. {txt2stix-1.0.8 → txt2stix-1.0.9}/docs/README.md +0 -0
  15. {txt2stix-1.0.8 → txt2stix-1.0.9}/docs/stix-mapping.md +0 -0
  16. {txt2stix-1.0.8 → txt2stix-1.0.9}/docs/txt2stix.png +0 -0
  17. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/__init__.py +0 -0
  18. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/extractions/ai/config.yaml +0 -0
  19. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/extractions/lookup/config.yaml +0 -0
  20. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/extractions/pattern/config.yaml +0 -0
  21. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/helpers/mimetype_filename_extension_list.csv +0 -0
  22. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/helpers/stix_relationship_types.txt +0 -0
  23. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/helpers/tlds.txt +0 -0
  24. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/helpers/windows_registry_key_prefix.txt +0 -0
  25. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/_README.md +0 -0
  26. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/_generate_lookups.py +0 -0
  27. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/attack_pattern.txt +0 -0
  28. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/campaign.txt +0 -0
  29. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/country_iso3166_alpha2.txt +0 -0
  30. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/course_of_action.txt +0 -0
  31. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/disarm_id_v1_5.txt +0 -0
  32. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/disarm_name_v1_5.txt +0 -0
  33. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/extensions.txt +0 -0
  34. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/identity.txt +0 -0
  35. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/infrastructure.txt +0 -0
  36. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/intrusion_set.txt +0 -0
  37. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/malware.txt +0 -0
  38. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_atlas_id_v4_5_2.txt +0 -0
  39. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_atlas_name_v4_5_2.txt +0 -0
  40. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_enterprise_aliases_v16_0.txt +0 -0
  41. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_enterprise_id_v16_0.txt +0 -0
  42. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_enterprise_name_v16_0.txt +0 -0
  43. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_ics_aliases_v16_0.txt +0 -0
  44. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_ics_id_v16_0.txt +0 -0
  45. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_ics_name_v16_0.txt +0 -0
  46. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_mobile_aliases_v16_0.txt +0 -0
  47. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_mobile_id_v16_0.txt +0 -0
  48. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_attack_mobile_name_v16_0.txt +0 -0
  49. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_capec_id_v3_9.txt +0 -0
  50. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_capec_name_v3_9.txt +0 -0
  51. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_cwe_id_v4_15.txt +0 -0
  52. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/mitre_cwe_name_v4_15.txt +0 -0
  53. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/threat_actor.txt +0 -0
  54. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/tld.txt +0 -0
  55. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/lookups/tool.txt +0 -0
  56. {txt2stix-1.0.8 → txt2stix-1.0.9}/includes/tests/test_cases.yaml +0 -0
  57. {txt2stix-1.0.8 → txt2stix-1.0.9}/requirements.txt +0 -0
  58. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/README.md +0 -0
  59. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/ai_country.txt +0 -0
  60. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/ai_mitre_attack_enterprise.txt +0 -0
  61. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/ai_mitre_attack_ics.txt +0 -0
  62. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/ai_mitre_attack_mobile.txt +0 -0
  63. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/ai_mitre_capec.txt +0 -0
  64. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/ai_mitre_cwe.txt +0 -0
  65. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/all_cases.txt +0 -0
  66. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_autonomous_system_number.txt +0 -0
  67. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_all.txt +0 -0
  68. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_amex.txt +0 -0
  69. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_diners.txt +0 -0
  70. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_discover.txt +0 -0
  71. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_jcb.txt +0 -0
  72. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_mastercard.txt +0 -0
  73. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_union_pay.txt +0 -0
  74. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_bank_card_visa.txt +0 -0
  75. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_country_alpha2.txt +0 -0
  76. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cpe_uri.txt +0 -0
  77. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cryptocurrency_btc_transaction.txt +0 -0
  78. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cryptocurrency_btc_wallet.txt +0 -0
  79. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cryptocurrency_eth_transaction.txt +0 -0
  80. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cryptocurrency_eth_wallet.txt +0 -0
  81. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cryptocurrency_xmr_transaction.txt +0 -0
  82. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cryptocurrency_xmr_wallet.txt +0 -0
  83. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_cve_id.txt +0 -0
  84. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_directory_unix.txt +0 -0
  85. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_directory_unix_file.txt +0 -0
  86. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_directory_windows.txt +0 -0
  87. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_directory_windows_with_file.txt +0 -0
  88. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_disarm.txt +0 -0
  89. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_disarm_name.txt +0 -0
  90. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_domain_name_only.txt +0 -0
  91. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_domain_name_subdomain.txt +0 -0
  92. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_email_address.txt +0 -0
  93. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_hash_md5.txt +0 -0
  94. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_hash_sha_1.txt +0 -0
  95. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_hash_sha_224.txt +0 -0
  96. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_hash_sha_256.txt +0 -0
  97. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_hash_sha_384.txt +0 -0
  98. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_hash_sha_512.txt +0 -0
  99. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_file_name.txt +0 -0
  100. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_host_name.txt +0 -0
  101. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_host_name_file.txt +0 -0
  102. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_host_name_path.txt +0 -0
  103. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_host_name_subdomain.txt +0 -0
  104. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_host_name_url.txt +0 -0
  105. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_iban_number.txt +0 -0
  106. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_ipv4_address_cidr.txt +0 -0
  107. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_ipv4_address_only.txt +0 -0
  108. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_ipv4_address_port.txt +0 -0
  109. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_ipv6_address_cidr.txt +0 -0
  110. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_ipv6_address_only.txt +0 -0
  111. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_ipv6_address_port.txt +0 -0
  112. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mac_address.txt +0 -0
  113. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_atlas.txt +0 -0
  114. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_atlas_name.txt +0 -0
  115. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_enterprise.txt +0 -0
  116. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_enterprise_aliases.txt +0 -0
  117. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_enterprise_name.txt +0 -0
  118. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_ics.txt +0 -0
  119. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_ics_aliases.txt +0 -0
  120. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_ics_name.txt +0 -0
  121. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_mobile.txt +0 -0
  122. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_mobile_aliases.txt +0 -0
  123. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_attack_mobile_name.txt +0 -0
  124. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_capec.txt +0 -0
  125. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_capec_name.txt +0 -0
  126. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_cwe.txt +0 -0
  127. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_mitre_cwe_name.txt +0 -0
  128. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_phone_number.txt +0 -0
  129. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_url.txt +0 -0
  130. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_url_file.txt +0 -0
  131. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_url_path.txt +0 -0
  132. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_user_agent.txt +0 -0
  133. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/generic_windows_registry_key.txt +0 -0
  134. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_attack_pattern.txt +0 -0
  135. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_campaign.txt +0 -0
  136. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_course_of_action.txt +0 -0
  137. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_identity.txt +0 -0
  138. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_infrastructure.txt +0 -0
  139. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_intrusion_set.txt +0 -0
  140. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_malware.txt +0 -0
  141. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_threat_actor.txt +0 -0
  142. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/extraction_types/lookup_tool.txt +0 -0
  143. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/attack_navigator_demo.txt +0 -0
  144. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/basic_relationship.txt +0 -0
  145. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/char_length_too_long.txt +0 -0
  146. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/descriptive_for_ai_relationships_1.txt +0 -0
  147. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/disarm_demo.txt +0 -0
  148. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/embedded_img_ignore.txt +0 -0
  149. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/embedded_link_ignore.txt +0 -0
  150. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/ip1.txt +0 -0
  151. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/ip2.txt +0 -0
  152. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/known_whitelist_match.txt +0 -0
  153. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/mitre_attack_enterprise_ai_demo.txt +0 -0
  154. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/mitre_attack_enterprise_lookup_demo.txt +0 -0
  155. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/mixed_extractions.txt +0 -0
  156. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/not_security_content.txt +0 -0
  157. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/test_ai_hash_error_with_stix2_lib.txt +0 -0
  158. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/test_aliases.txt +0 -0
  159. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/test_extraction_boundary.txt +0 -0
  160. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/manually_generated_reports/test_extraction_escapes.txt +0 -0
  161. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/APT28-Center-of-Storm-2017.txt +0 -0
  162. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/Bitdefender-Labs-Report-X-creat6958-en-EN.txt +0 -0
  163. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/FireEyeAPT39.txt +0 -0
  164. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/France_CERT_APT31_Pakdoor_TLPWHITE.txt +0 -0
  165. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/Group-IB_Ransomware_Uncovered_whitepaper_eng.txt +0 -0
  166. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/JOINT_CSA_HUNTING_RU_INTEL_SNAKE_MALWARE_20230509.txt +0 -0
  167. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/TA22-0126-QAKBOT-analysis-TLP-GREEN.txt +0 -0
  168. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/dinners_card.txt +0 -0
  169. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/mandiant-apt1.txt +0 -0
  170. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/data/real_intel_reports/mykings_report_final.txt +0 -0
  171. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/manual-tests/cases-ai-relationships.md +0 -0
  172. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/manual-tests/cases-extraction-type-ai.md +0 -0
  173. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/manual-tests/cases-extraction-type-lookup.md +0 -0
  174. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/manual-tests/cases-extraction-type-pattern.md +0 -0
  175. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/scripts/generate_simple_extraction_test_cases_txt_files.py +0 -0
  176. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/__init__.py +0 -0
  177. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_bundler.py +0 -0
  178. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_extractors.py +0 -0
  179. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_indicator.py +0 -0
  180. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_lookups.py +0 -0
  181. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_main.py +0 -0
  182. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_retriever.py +0 -0
  183. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_run_txt2stix.py +0 -0
  184. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/test_utils.py +0 -0
  185. {txt2stix-1.0.8 → txt2stix-1.0.9}/tests/src/utils.py +0 -0
  186. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/__init__.py +0 -0
  187. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/__init__.py +0 -0
  188. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/anthropic.py +0 -0
  189. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/base.py +0 -0
  190. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/deepseek.py +0 -0
  191. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/gemini.py +0 -0
  192. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/openai.py +0 -0
  193. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/openrouter.py +0 -0
  194. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/prompts.py +0 -0
  195. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/ai_extractor/utils.py +0 -0
  196. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/bundler.py +0 -0
  197. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/common.py +0 -0
  198. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/credential_checker.py +0 -0
  199. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/extractions.py +0 -0
  200. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/indicator.py +0 -0
  201. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/lookups.py +0 -0
  202. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/__init__.py +0 -0
  203. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/__init__.py +0 -0
  204. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/base_extractor.py +0 -0
  205. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/README.md +0 -0
  206. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/__init__.py +0 -0
  207. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/amex_card_extractor.py +0 -0
  208. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/diners_card_extractor.py +0 -0
  209. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/discover_card_extractor.py +0 -0
  210. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/jcb_card_extractor.py +0 -0
  211. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/master_card_extractor.py +0 -0
  212. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/union_card_extractor.py +0 -0
  213. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/card/visa_card_extractor.py +0 -0
  214. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/crypto/__init__.py +0 -0
  215. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/crypto/btc_extractor.py +0 -0
  216. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/directory/__init__.py +0 -0
  217. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/directory/unix_directory_extractor.py +0 -0
  218. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/directory/unix_file_path_extractor.py +0 -0
  219. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/directory/windows_directory_path_extractor.py +0 -0
  220. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/directory/windows_file_path_extractor.py +0 -0
  221. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/domain/__init__.py +0 -0
  222. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/domain/domain_extractor.py +0 -0
  223. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/domain/hostname_extractor.py +0 -0
  224. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/domain/sub_domain_extractor.py +0 -0
  225. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/__init__.py +0 -0
  226. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/md5_extractor.py +0 -0
  227. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/sha1_extractor.py +0 -0
  228. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/sha224_extractor.py +0 -0
  229. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/sha2_256_exactor.py +0 -0
  230. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/sha2_512_exactor.py +0 -0
  231. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/sha3_256_exactor.py +0 -0
  232. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/hashes/sha3_512_exactor.py +0 -0
  233. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/helper.py +0 -0
  234. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/__init__.py +0 -0
  235. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/ipv4_cidr_extractor.py +0 -0
  236. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/ipv4_extractor.py +0 -0
  237. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/ipv4_port_extractor.py +0 -0
  238. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/ipv6_cidr_extractor.py +0 -0
  239. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/ipv6_extractor.py +0 -0
  240. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/ip/ipv6_port_extractor.py +0 -0
  241. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/__init__.py +0 -0
  242. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/asn_extractor.py +0 -0
  243. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/cpe_extractor.py +0 -0
  244. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/cve_extractor.py +0 -0
  245. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/email_extractor.py +0 -0
  246. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/filename_extractor.py +0 -0
  247. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/iban_extractor.py +0 -0
  248. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/mac_address_extractor.py +0 -0
  249. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/phonenumber_extractor.py +0 -0
  250. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/user_agent_extractor.py +0 -0
  251. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/others/windows_registry_key_extractor.py +0 -0
  252. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/url/__init__.py +0 -0
  253. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/url/url_extractor.py +0 -0
  254. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/url/url_file_extractor.py +0 -0
  255. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/pattern/extractors/url/url_path_extractor.py +0 -0
  256. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/retriever.py +0 -0
  257. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/stix.py +0 -0
  258. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/txt2stix.py +0 -0
  259. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix/utils.py +0 -0
  260. {txt2stix-1.0.8 → txt2stix-1.0.9}/txt2stix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: txt2stix
3
- Version: 1.0.8
3
+ Version: 1.0.9
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.8"
7
+ version = "1.0.9"
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."
@@ -4,4 +4,6 @@ Due to password protection, the zip files are able to bypass some AV detections.
4
4
 
5
5
  The zip files are extracted and usually contain a malicious document, such as a .doc, .pdf, or .xls. Some examples are malware.pdf and bad.com
6
6
 
7
- The extracted files contain malicious macros that connect to a C2 server 1.1.1.1
7
+ The extracted files contain malicious macros that connect to a C2 server 1.1.1.1
8
+
9
+ And here is a mobile ID to test behaviour of multiple matrices T1630.001
@@ -486,6 +486,24 @@ python3 txt2stix.py \
486
486
  --report_id 3b160a8d-12dd-4e7c-aee8-5af6e371b425
487
487
  ```
488
488
 
489
+ with two domains
490
+
491
+ no indicators
492
+
493
+ ```shell
494
+ python3 txt2stix.py \
495
+ --relationship_mode ai \
496
+ --ai_settings_relationships openai:gpt-5 \
497
+ --input_file tests/data/manually_generated_reports/attack_flow_demo.txt \
498
+ --name 'Test MITRE ATT&CK Flow demo' \
499
+ --tlp_level clear \
500
+ --confidence 100 \
501
+ --use_extractions 'ai_mitre_attack_*' \
502
+ --ai_settings_extractions openai:gpt-5 \
503
+ --ai_create_attack_flow \
504
+ --report_id ccc8c844-6a89-4762-b4e7-77c918fa4b8f
505
+ ```
506
+
489
507
  ### attack navigator demo
490
508
 
491
509
  ```shell
@@ -8,6 +8,7 @@ from txt2stix.attack_flow import (
8
8
  create_navigator_layer,
9
9
  get_all_tactics,
10
10
  get_techniques_from_extracted_objects,
11
+ parse_domain_flow,
11
12
  parse_flow,
12
13
  extract_attack_flow_and_navigator,
13
14
  )
@@ -21,31 +22,30 @@ def test_parse_flow(dummy_report, dummy_objects, dummy_flow):
21
22
  techniques = get_techniques_from_extracted_objects(dummy_objects, tactics)
22
23
  flow = dummy_flow
23
24
  report = dummy_report
24
- expected_ids = set(
25
- [
26
- "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
27
- "extension-definition--fb9c968a-745b-4ade-9b25-c324172197f4",
28
- "attack-flow--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
29
- "relationship--6346ead9-49cc-5ede-89e2-449f1c22ed13",
30
- "x-mitre-tactic--696af733-728e-49d7-8261-75fdc590f453",
31
- "attack-pattern--0fe075d5-beac-4d02-b93e-0f874997db72",
32
- "attack-action--51dc1572-cb10-581b-b9ef-9e589615ecaa",
33
- "x-mitre-tactic--5bc1d813-693e-4823-9961-abf9af4b0e92",
34
- "attack-pattern--f9e9365a-9ca2-4d9c-8e7c-050d73d1101a",
35
- "attack-action--e03c89ba-a476-5509-ac0a-049b61514be7",
36
- "x-mitre-tactic--298fe907-7931-4fd2-8131-2814dd493134",
37
- "attack-pattern--1b22b676-9347-4c55-9a35-ef0dc653db5b",
38
- "attack-action--1fd63972-ef98-5da5-81f5-4090c7dfa585",
39
- "x-mitre-tactic--2558fd61-8c75-4730-94c4-11926db2a263",
40
- "attack-pattern--1a80d097-54df-41d8-9d33-34e755ec5e72",
41
- "attack-action--c7e06b10-252d-520d-82eb-e32314bbec34",
42
- ]
43
- )
25
+ expected_ids = {
26
+ "attack-pattern--1b22b676-9347-4c55-9a35-ef0dc653db5b",
27
+ "x-mitre-tactic--298fe907-7931-4fd2-8131-2814dd493134",
28
+ "attack-action--1fd63972-ef98-5da5-81f5-4090c7dfa585",
29
+ "extension-definition--fb9c968a-745b-4ade-9b25-c324172197f4",
30
+ "attack-pattern--1a80d097-54df-41d8-9d33-34e755ec5e72",
31
+ "report--9c88fbcb-8c0d-4124-868b-3dcb1e9b696c",
32
+ "attack-flow--bb21585c-5f82-55cf-b73d-89b5217ef092",
33
+ "relationship--22e97298-819a-55ac-b57b-2185ffb72c62",
34
+ "x-mitre-tactic--2558fd61-8c75-4730-94c4-11926db2a263",
35
+ "attack-action--c7e06b10-252d-520d-82eb-e32314bbec34",
36
+ "x-mitre-tactic--696af733-728e-49d7-8261-75fdc590f453",
37
+ "x-mitre-tactic--5bc1d813-693e-4823-9961-abf9af4b0e92",
38
+ "attack-pattern--f9e9365a-9ca2-4d9c-8e7c-050d73d1101a",
39
+ "attack-action--51dc1572-cb10-581b-b9ef-9e589615ecaa",
40
+ "relationship--931f6b0d-5136-534a-93bc-8cce065e04dc",
41
+ "attack-pattern--0fe075d5-beac-4d02-b93e-0f874997db72",
42
+ "attack-flow--b48ec5d9-407c-5e4a-a6d0-fe851cd4ea0e",
43
+ "attack-action--e03c89ba-a476-5509-ac0a-049b61514be7",
44
+ }
44
45
 
45
46
  flow_objects = parse_flow(report, flow, techniques, tactics)
46
47
  assert {obj["id"] for obj in flow_objects} == expected_ids
47
48
 
48
-
49
49
  def test_parse_flow__no_success(dummy_report):
50
50
  flow_objects = parse_flow(
51
51
  dummy_report,
@@ -61,6 +61,48 @@ def test_parse_flow__no_success(dummy_report):
61
61
  assert len(flow_objects) == 0
62
62
 
63
63
 
64
+ @pytest.mark.parametrize(
65
+ ["domain", "expected_ids"],
66
+ [
67
+ ("mobile-attack", set()),
68
+ [
69
+ "ics-attack",
70
+ {
71
+ "x-mitre-tactic--298fe907-7931-4fd2-8131-2814dd493134",
72
+ "x-mitre-tactic--696af733-728e-49d7-8261-75fdc590f453",
73
+ "attack-pattern--1b22b676-9347-4c55-9a35-ef0dc653db5b",
74
+ "relationship--22e97298-819a-55ac-b57b-2185ffb72c62",
75
+ "attack-action--1fd63972-ef98-5da5-81f5-4090c7dfa585",
76
+ "attack-pattern--0fe075d5-beac-4d02-b93e-0f874997db72",
77
+ "attack-flow--bb21585c-5f82-55cf-b73d-89b5217ef092",
78
+ "attack-action--51dc1572-cb10-581b-b9ef-9e589615ecaa",
79
+ },
80
+ ],
81
+ [
82
+ "enterprise-attack",
83
+ {
84
+ "attack-action--e03c89ba-a476-5509-ac0a-049b61514be7",
85
+ "relationship--931f6b0d-5136-534a-93bc-8cce065e04dc",
86
+ "attack-flow--b48ec5d9-407c-5e4a-a6d0-fe851cd4ea0e",
87
+ "attack-pattern--f9e9365a-9ca2-4d9c-8e7c-050d73d1101a",
88
+ "x-mitre-tactic--2558fd61-8c75-4730-94c4-11926db2a263",
89
+ "attack-pattern--1a80d097-54df-41d8-9d33-34e755ec5e72",
90
+ "x-mitre-tactic--5bc1d813-693e-4823-9961-abf9af4b0e92",
91
+ "attack-action--c7e06b10-252d-520d-82eb-e32314bbec34",
92
+ },
93
+ ],
94
+ ],
95
+ )
96
+ def test_parse_domain_flow(dummy_report, dummy_objects, dummy_flow, domain, expected_ids):
97
+ tactics = get_all_tactics()
98
+ techniques = get_techniques_from_extracted_objects(dummy_objects, tactics)
99
+ flow = dummy_flow
100
+ report = dummy_report
101
+ flow_objects = parse_domain_flow(report, flow, techniques, tactics, domain)
102
+ print([domain, {obj["id"] for obj in flow_objects}], ",")
103
+ assert {obj["id"] for obj in flow_objects} == expected_ids
104
+
105
+
64
106
  def test_get_techniques_from_extracted_objects(dummy_objects):
65
107
  tactics = get_all_tactics()
66
108
  techniques = get_techniques_from_extracted_objects(dummy_objects, tactics)
@@ -142,7 +184,11 @@ def test_extract_attack_flow_and_navigator(dummy_objects, dummy_report):
142
184
  mock_extract_flow.assert_called_once_with(text, techniques)
143
185
 
144
186
  mock_create_navigator_layer.assert_called_once_with(
145
- bundler.report, bundler.summary, mock_extract_flow.return_value, techniques, tactics
187
+ bundler.report,
188
+ bundler.summary,
189
+ mock_extract_flow.return_value,
190
+ techniques,
191
+ tactics,
146
192
  )
147
193
 
148
194
  ### reset mocks
@@ -181,7 +227,11 @@ def test_extract_attack_flow_and_navigator(dummy_objects, dummy_report):
181
227
  mock_parse_flow.assert_not_called()
182
228
 
183
229
  mock_create_navigator_layer.assert_called_once_with(
184
- bundler.report, bundler.summary, mock_extract_flow.return_value, techniques, tactics
230
+ bundler.report,
231
+ bundler.summary,
232
+ mock_extract_flow.return_value,
233
+ techniques,
234
+ tactics,
185
235
  )
186
236
 
187
237
  ### reset mocks
@@ -281,7 +331,7 @@ def test_create_navigator_layer(dummy_report):
281
331
  {
282
332
  "versions": {
283
333
  "layer": "4.5",
284
- "attack": '16.1',
334
+ "attack": "16.1",
285
335
  "navigator": "5.1.0",
286
336
  },
287
337
  "name": "some markdown document",
@@ -311,7 +361,7 @@ def test_create_navigator_layer(dummy_report):
311
361
  {
312
362
  "versions": {
313
363
  "layer": "4.5",
314
- "attack": '17.0',
364
+ "attack": "17.0",
315
365
  "navigator": "5.1.0",
316
366
  },
317
367
  "name": "some markdown document",
@@ -341,7 +391,7 @@ def test_create_navigator_layer(dummy_report):
341
391
  {
342
392
  "versions": {
343
393
  "layer": "4.5",
344
- "attack": '13.1',
394
+ "attack": "13.1",
345
395
  "navigator": "5.1.0",
346
396
  },
347
397
  "name": "some markdown document",
@@ -16,15 +16,26 @@ def parse_flow(report, flow: AttackFlowList, techniques, tactics):
16
16
  logging.info(f"flow.success = {flow.success}")
17
17
  if not flow.success:
18
18
  return []
19
- flow_objects = [report, attack_flow_ExtensionDefinitionSMO]
19
+ objects = [report, attack_flow_ExtensionDefinitionSMO]
20
+ for domain in ["enterprise-attack", "mobile-attack", "ics-attack"]:
21
+ flow_objects = parse_domain_flow(report, flow, techniques, tactics, domain)
22
+ objects.extend(flow_objects)
23
+ return objects
24
+
25
+ def parse_domain_flow(report, flow: AttackFlowList, techniques, tactics, domain):
26
+ flow_objects = []
27
+ flow_obj = None
20
28
  last_action = None
21
29
  for i, item in enumerate(flow.items):
22
30
  try:
23
31
  technique = techniques[item.attack_technique_id]
32
+ if technique["domain"] != domain:
33
+ continue
24
34
  tactic_id = technique["possible_tactics"][
25
35
  flow.tactic_mapping[item.attack_technique_id]
26
36
  ]
27
37
  technique_obj = technique["stix_obj"]
38
+
28
39
  tactic_obj = tactics[technique["domain"]][tactic_id]
29
40
  action_obj = AttackAction(
30
41
  **{
@@ -40,16 +51,16 @@ def parse_flow(report, flow: AttackFlowList, techniques, tactics):
40
51
  allow_custom=True,
41
52
  )
42
53
  action_obj.effect_refs.clear()
43
- if i == 0:
54
+ if not flow_obj:
44
55
  flow_obj = {
45
56
  "type": "attack-flow",
46
- "id": report.id.replace("report", "attack-flow"),
57
+ "id": "attack-flow--"+str(uuid.uuid5(UUID_NAMESPACE, f"attack-flow+{domain}+{report.id}")),
47
58
  "spec_version": "2.1",
48
59
  "created": report.created,
49
60
  "modified": report.modified,
50
61
  "created_by_ref": report.created_by_ref,
51
62
  "start_refs": [action_obj["id"]],
52
- "name": report.name,
63
+ "name": f"[{domain.split('-')[0].upper()}] {report.name}",
53
64
  "description": report.description,
54
65
  "scope": "malware",
55
66
  "external_references": report.external_references,
@@ -61,7 +72,7 @@ def parse_flow(report, flow: AttackFlowList, techniques, tactics):
61
72
  type="relationship",
62
73
  spec_version="2.1",
63
74
  id="relationship--"
64
- + str(uuid.uuid5(UUID_NAMESPACE, f"attack-flow+{report.id}")),
75
+ + str(uuid.uuid5(UUID_NAMESPACE, f"attack-flow+{report.id}+{flow_obj['id']}")),
65
76
  created_by_ref=report.created_by_ref,
66
77
  created=report.created,
67
78
  modified=report.modified,
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