wg-metasploit_data_models 4.1.4.01 → 4.1.4.02

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 (440) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.github/workflows/verify.yml +68 -0
  4. data/.gitignore +29 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +38 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +6 -0
  9. data/CONTRIBUTING.md +133 -0
  10. data/Gemfile +46 -0
  11. data/LICENSE +27 -0
  12. data/README.md +65 -0
  13. data/RELEASING.md +82 -0
  14. data/Rakefile +72 -0
  15. data/UPGRADING.md +1 -0
  16. data/app/models/mdm/api_key.rb +61 -0
  17. data/app/models/mdm/async_callback.rb +64 -0
  18. data/app/models/mdm/client.rb +50 -0
  19. data/app/models/mdm/cred.rb +205 -0
  20. data/app/models/mdm/event.rb +83 -0
  21. data/app/models/mdm/exploit_attempt.rb +105 -0
  22. data/app/models/mdm/exploited_host.rb +42 -0
  23. data/app/models/mdm/host.rb +619 -0
  24. data/app/models/mdm/host_detail.rb +62 -0
  25. data/app/models/mdm/host_tag.rb +49 -0
  26. data/app/models/mdm/listener.rb +82 -0
  27. data/app/models/mdm/loot.rb +161 -0
  28. data/app/models/mdm/macro.rb +62 -0
  29. data/app/models/mdm/mod_ref.rb +24 -0
  30. data/app/models/mdm/module/action.rb +33 -0
  31. data/app/models/mdm/module/arch.rb +28 -0
  32. data/app/models/mdm/module/author.rb +34 -0
  33. data/app/models/mdm/module/detail.rb +388 -0
  34. data/app/models/mdm/module/mixin.rb +31 -0
  35. data/app/models/mdm/module/platform.rb +29 -0
  36. data/app/models/mdm/module/ref.rb +42 -0
  37. data/app/models/mdm/module/target.rb +37 -0
  38. data/app/models/mdm/nexpose_console.rb +121 -0
  39. data/app/models/mdm/note.rb +125 -0
  40. data/app/models/mdm/payload.rb +103 -0
  41. data/app/models/mdm/profile.rb +45 -0
  42. data/app/models/mdm/ref.rb +48 -0
  43. data/app/models/mdm/route.rb +28 -0
  44. data/app/models/mdm/service.rb +267 -0
  45. data/app/models/mdm/session.rb +203 -0
  46. data/app/models/mdm/session_event.rb +44 -0
  47. data/app/models/mdm/tag.rb +114 -0
  48. data/app/models/mdm/task.rb +168 -0
  49. data/app/models/mdm/task_cred.rb +45 -0
  50. data/app/models/mdm/task_host.rb +41 -0
  51. data/app/models/mdm/task_service.rb +41 -0
  52. data/app/models/mdm/task_session.rb +41 -0
  53. data/app/models/mdm/user.rb +230 -0
  54. data/app/models/mdm/vuln.rb +204 -0
  55. data/app/models/mdm/vuln_attempt.rb +76 -0
  56. data/app/models/mdm/vuln_detail.rb +156 -0
  57. data/app/models/mdm/vuln_ref.rb +21 -0
  58. data/app/models/mdm/web_form.rb +53 -0
  59. data/app/models/mdm/web_page.rb +92 -0
  60. data/app/models/mdm/web_site.rb +113 -0
  61. data/app/models/mdm/web_vuln.rb +193 -0
  62. data/app/models/mdm/wmap_request.rb +101 -0
  63. data/app/models/mdm/wmap_target.rb +56 -0
  64. data/app/models/mdm/workspace.rb +286 -0
  65. data/app/models/metasploit_data_models/automatic_exploitation/match.rb +43 -0
  66. data/app/models/metasploit_data_models/automatic_exploitation/match_result.rb +71 -0
  67. data/app/models/metasploit_data_models/automatic_exploitation/match_set.rb +40 -0
  68. data/app/models/metasploit_data_models/automatic_exploitation/run.rb +29 -0
  69. data/app/models/metasploit_data_models/ip_address/v4/cidr.rb +14 -0
  70. data/app/models/metasploit_data_models/ip_address/v4/nmap.rb +14 -0
  71. data/app/models/metasploit_data_models/ip_address/v4/range.rb +12 -0
  72. data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb +125 -0
  73. data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb +12 -0
  74. data/app/models/metasploit_data_models/ip_address/v4/segment/single.rb +123 -0
  75. data/app/models/metasploit_data_models/ip_address/v4/segmented.rb +200 -0
  76. data/app/models/metasploit_data_models/ip_address/v4/single.rb +53 -0
  77. data/app/models/metasploit_data_models/module_run.rb +213 -0
  78. data/app/models/metasploit_data_models/search/operation/ip_address.rb +60 -0
  79. data/app/models/metasploit_data_models/search/operation/port/number.rb +25 -0
  80. data/app/models/metasploit_data_models/search/operation/port/range.rb +79 -0
  81. data/app/models/metasploit_data_models/search/operation/range.rb +56 -0
  82. data/app/models/metasploit_data_models/search/operator/ip_address.rb +33 -0
  83. data/app/models/metasploit_data_models/search/operator/multitext.rb +73 -0
  84. data/app/models/metasploit_data_models/search/operator/port/list.rb +67 -0
  85. data/app/models/metasploit_data_models/search/visitor/attribute.rb +17 -0
  86. data/app/models/metasploit_data_models/search/visitor/includes.rb +47 -0
  87. data/app/models/metasploit_data_models/search/visitor/joins.rb +67 -0
  88. data/app/models/metasploit_data_models/search/visitor/method.rb +16 -0
  89. data/app/models/metasploit_data_models/search/visitor/relation.rb +91 -0
  90. data/app/models/metasploit_data_models/search/visitor/where.rb +128 -0
  91. data/config/initializers/arel_helper.rb +5 -0
  92. data/config/initializers/ipaddr.rb +29 -0
  93. data/config/locales/en.yml +94 -0
  94. data/console_db.yml +9 -0
  95. data/db/migrate/000_create_tables.rb +79 -0
  96. data/db/migrate/001_add_wmap_tables.rb +35 -0
  97. data/db/migrate/002_add_workspaces.rb +36 -0
  98. data/db/migrate/003_move_notes.rb +20 -0
  99. data/db/migrate/004_add_events_table.rb +16 -0
  100. data/db/migrate/005_expand_info.rb +58 -0
  101. data/db/migrate/006_add_timestamps.rb +26 -0
  102. data/db/migrate/007_add_loots.rb +20 -0
  103. data/db/migrate/008_create_users.rb +16 -0
  104. data/db/migrate/009_add_loots_ctype.rb +10 -0
  105. data/db/migrate/010_add_alert_fields.rb +16 -0
  106. data/db/migrate/011_add_reports.rb +19 -0
  107. data/db/migrate/012_add_tasks.rb +24 -0
  108. data/db/migrate/013_add_tasks_result.rb +10 -0
  109. data/db/migrate/014_add_loots_fields.rb +12 -0
  110. data/db/migrate/015_rename_user.rb +16 -0
  111. data/db/migrate/016_add_host_purpose.rb +10 -0
  112. data/db/migrate/017_expand_info2.rb +58 -0
  113. data/db/migrate/018_add_workspace_user_info.rb +29 -0
  114. data/db/migrate/019_add_workspace_desc.rb +23 -0
  115. data/db/migrate/020_add_user_preferences.rb +11 -0
  116. data/db/migrate/021_standardize_info_and_data.rb +18 -0
  117. data/db/migrate/022_enlarge_event_info.rb +10 -0
  118. data/db/migrate/023_add_report_downloaded_at.rb +10 -0
  119. data/db/migrate/024_convert_service_info_to_text.rb +12 -0
  120. data/db/migrate/025_add_user_admin.rb +19 -0
  121. data/db/migrate/026_add_creds_table.rb +19 -0
  122. data/db/migrate/20100819123300_migrate_cred_data.rb +154 -0
  123. data/db/migrate/20100824151500_add_exploited_table.rb +16 -0
  124. data/db/migrate/20100908001428_add_owner_to_workspaces.rb +9 -0
  125. data/db/migrate/20100911122000_add_report_templates.rb +18 -0
  126. data/db/migrate/20100916151530_require_admin_flag.rb +15 -0
  127. data/db/migrate/20100916175000_add_campaigns_and_templates.rb +61 -0
  128. data/db/migrate/20100920012100_add_generate_exe_column.rb +8 -0
  129. data/db/migrate/20100926214000_add_template_prefs.rb +11 -0
  130. data/db/migrate/20101001000000_add_web_tables.rb +57 -0
  131. data/db/migrate/20101002000000_add_query.rb +10 -0
  132. data/db/migrate/20101007000000_add_vuln_info.rb +15 -0
  133. data/db/migrate/20101008111800_add_clients_to_campaigns.rb +10 -0
  134. data/db/migrate/20101009023300_add_campaign_attachments.rb +15 -0
  135. data/db/migrate/20101104135100_add_imported_creds.rb +17 -0
  136. data/db/migrate/20101203000000_fix_web_tables.rb +34 -0
  137. data/db/migrate/20101203000001_expand_host_comment.rb +12 -0
  138. data/db/migrate/20101206212033_add_limit_to_network_to_workspaces.rb +9 -0
  139. data/db/migrate/20110112154300_add_module_uuid_to_tasks.rb +9 -0
  140. data/db/migrate/20110204112800_add_host_tags.rb +28 -0
  141. data/db/migrate/20110317144932_add_session_table.rb +110 -0
  142. data/db/migrate/20110414180600_add_local_id_to_session_table.rb +11 -0
  143. data/db/migrate/20110415175705_add_routes_table.rb +18 -0
  144. data/db/migrate/20110422000000_convert_binary.rb +73 -0
  145. data/db/migrate/20110425095900_add_last_seen_to_sessions.rb +8 -0
  146. data/db/migrate/20110513143900_track_successful_exploits.rb +31 -0
  147. data/db/migrate/20110517160800_rename_and_prune_nessus_vulns.rb +26 -0
  148. data/db/migrate/20110527000000_add_task_id_to_reports_table.rb +11 -0
  149. data/db/migrate/20110527000001_add_api_keys_table.rb +12 -0
  150. data/db/migrate/20110606000001_add_macros_table.rb +16 -0
  151. data/db/migrate/20110622000000_add_settings_to_tasks_table.rb +12 -0
  152. data/db/migrate/20110624000001_add_listeners_table.rb +19 -0
  153. data/db/migrate/20110625000001_add_macro_to_listeners_table.rb +12 -0
  154. data/db/migrate/20110630000001_add_nexpose_consoles_table.rb +21 -0
  155. data/db/migrate/20110630000002_add_name_to_nexpose_consoles_table.rb +12 -0
  156. data/db/migrate/20110717000001_add_profiles_table.rb +15 -0
  157. data/db/migrate/20110727163801_expand_cred_ptype_column.rb +9 -0
  158. data/db/migrate/20110730000001_add_initial_indexes.rb +85 -0
  159. data/db/migrate/20110812000001_prune_indexes.rb +23 -0
  160. data/db/migrate/20110922000000_expand_notes.rb +9 -0
  161. data/db/migrate/20110928101300_add_mod_ref_table.rb +17 -0
  162. data/db/migrate/20111011110000_add_display_name_to_reports_table.rb +24 -0
  163. data/db/migrate/20111203000000_inet_columns.rb +13 -0
  164. data/db/migrate/20111204000000_more_inet_columns.rb +17 -0
  165. data/db/migrate/20111210000000_add_scope_to_hosts.rb +9 -0
  166. data/db/migrate/20120126110000_add_virtual_host_to_hosts.rb +9 -0
  167. data/db/migrate/20120411173220_rename_workspace_members.rb +9 -0
  168. data/db/migrate/20120601152442_add_counter_caches_to_hosts.rb +21 -0
  169. data/db/migrate/20120625000000_add_vuln_details.rb +34 -0
  170. data/db/migrate/20120625000001_add_host_details.rb +16 -0
  171. data/db/migrate/20120625000002_expand_details.rb +16 -0
  172. data/db/migrate/20120625000003_expand_details2.rb +24 -0
  173. data/db/migrate/20120625000004_add_vuln_attempts.rb +19 -0
  174. data/db/migrate/20120625000005_add_vuln_and_host_counter_caches.rb +14 -0
  175. data/db/migrate/20120625000006_add_module_details.rb +118 -0
  176. data/db/migrate/20120625000007_add_exploit_attempts.rb +26 -0
  177. data/db/migrate/20120625000008_add_fail_message.rb +12 -0
  178. data/db/migrate/20120718202805_add_owner_and_payload_to_web_vulns.rb +13 -0
  179. data/db/migrate/20130228214900_change_required_columns_to_null_false_in_web_vulns.rb +19 -0
  180. data/db/migrate/20130412154159_change_foreign_key_in_module_actions.rb +25 -0
  181. data/db/migrate/20130412171844_change_foreign_key_in_module_archs.rb +25 -0
  182. data/db/migrate/20130412173121_change_foreign_key_in_module_authors.rb +25 -0
  183. data/db/migrate/20130412173640_change_foreign_key_in_module_mixins.rb +25 -0
  184. data/db/migrate/20130412174254_change_foreign_key_in_module_platforms.rb +25 -0
  185. data/db/migrate/20130412174719_change_foreign_key_in_module_refs.rb +25 -0
  186. data/db/migrate/20130412175040_change_foreign_key_in_module_targets.rb +25 -0
  187. data/db/migrate/20130423211152_add_creds_counter_cache.rb +24 -0
  188. data/db/migrate/20130430151353_change_required_columns_to_null_false_in_hosts.rb +11 -0
  189. data/db/migrate/20130430162145_enforce_address_uniqueness_in_workspace_in_hosts.rb +101 -0
  190. data/db/migrate/20130510021637_remove_campaigns.rb +11 -0
  191. data/db/migrate/20130515164311_change_web_vulns_confidence_to_integer.rb +48 -0
  192. data/db/migrate/20130515172727_valid_mdm_web_vuln_params.rb +30 -0
  193. data/db/migrate/20130516204810_making_vulns_refs_a_real_ar_model.rb +5 -0
  194. data/db/migrate/20130522001343_create_task_creds.rb +9 -0
  195. data/db/migrate/20130522032517_create_task_hosts.rb +9 -0
  196. data/db/migrate/20130522041110_create_task_services.rb +9 -0
  197. data/db/migrate/20130525015035_remove_campaign_id_from_clients.rb +9 -0
  198. data/db/migrate/20130525212420_drop_table_imported_creds.rb +14 -0
  199. data/db/migrate/20130531144949_making_host_tags_a_real_ar_model.rb +6 -0
  200. data/db/migrate/20130604145732_create_task_sessions.rb +9 -0
  201. data/db/migrate/20130717150737_remove_pname_validation.rb +7 -0
  202. data/db/migrate/20131002004641_create_automatic_exploitation_matches.rb +13 -0
  203. data/db/migrate/20131002164449_create_automatic_exploitation_match_sets.rb +12 -0
  204. data/db/migrate/20131008213344_create_automatic_exploitation_runs.rb +11 -0
  205. data/db/migrate/20131011184338_module_detail_on_automatic_exploitation_match.rb +10 -0
  206. data/db/migrate/20131017150735_create_automatic_exploitation_match_results.rb +11 -0
  207. data/db/migrate/20131021185657_make_match_polymorphic.rb +11 -0
  208. data/db/migrate/20140905031549_add_detected_arch_to_host.rb +5 -0
  209. data/db/migrate/20150112203945_remove_duplicate_services.rb +17 -0
  210. data/db/migrate/20150205192745_drop_service_uniqueness_index.rb +5 -0
  211. data/db/migrate/20150209195939_add_vuln_id_to_note.rb +6 -0
  212. data/db/migrate/20150212214222_remove_duplicate_services2.rb +17 -0
  213. data/db/migrate/20150219173821_create_module_runs.rb +23 -0
  214. data/db/migrate/20150219215039_add_module_run_to_session.rb +8 -0
  215. data/db/migrate/20150226151459_add_module_run_fk_to_loot.rb +8 -0
  216. data/db/migrate/20150312155312_add_module_full_name_to_match.rb +6 -0
  217. data/db/migrate/20150317145455_rename_module_indices.rb +29 -0
  218. data/db/migrate/20150326183742_add_missing_ae_indices.rb +13 -0
  219. data/db/migrate/20150421211719_rename_automatic_exploitation_index.rb +16 -0
  220. data/db/migrate/20150514182921_add_origin_to_mdm_vuln.rb +13 -0
  221. data/db/migrate/20160415153312_remove_not_null_from_web_vuln_p_arams.rb +5 -0
  222. data/db/migrate/20161004165612_add_fingerprinted_to_workspace.rb +5 -0
  223. data/db/migrate/20161227212223_add_os_family_to_hosts.rb +5 -0
  224. data/db/migrate/20180904120211_create_payloads.rb +21 -0
  225. data/db/migrate/20190308134512_create_async_callbacks.rb +13 -0
  226. data/db/migrate/20190507120211_remove_payload_workspaces.rb +5 -0
  227. data/lib/mdm/host/operating_system_normalization.rb +942 -0
  228. data/lib/mdm/module.rb +13 -0
  229. data/lib/mdm.rb +57 -0
  230. data/lib/metasploit_data_models/automatic_exploitation.rb +25 -0
  231. data/lib/metasploit_data_models/base64_serializer.rb +99 -0
  232. data/lib/metasploit_data_models/change_required_columns_to_null_false.rb +21 -0
  233. data/lib/metasploit_data_models/engine.rb +32 -0
  234. data/lib/metasploit_data_models/ip_address/cidr.rb +174 -0
  235. data/lib/metasploit_data_models/ip_address/range.rb +181 -0
  236. data/lib/metasploit_data_models/ip_address/v4/segment/nmap.rb +7 -0
  237. data/lib/metasploit_data_models/ip_address/v4/segment.rb +7 -0
  238. data/lib/metasploit_data_models/ip_address/v4.rb +11 -0
  239. data/lib/metasploit_data_models/ip_address.rb +9 -0
  240. data/lib/metasploit_data_models/match/child.rb +48 -0
  241. data/lib/metasploit_data_models/match/parent.rb +103 -0
  242. data/lib/metasploit_data_models/match.rb +8 -0
  243. data/lib/metasploit_data_models/search/operation/port.rb +9 -0
  244. data/lib/metasploit_data_models/search/operation.rb +9 -0
  245. data/lib/metasploit_data_models/search/operator/port.rb +6 -0
  246. data/lib/metasploit_data_models/search/operator.rb +8 -0
  247. data/lib/metasploit_data_models/search/visitor.rb +11 -0
  248. data/lib/metasploit_data_models/search.rb +8 -0
  249. data/lib/metasploit_data_models/serialized_prefs.rb +27 -0
  250. data/lib/metasploit_data_models/version.rb +13 -0
  251. data/lib/metasploit_data_models.rb +56 -0
  252. data/metasploit_data_models.gemspec +65 -0
  253. data/script/rails +8 -0
  254. data/spec/app/models/mdm/api_key_spec.rb +3 -0
  255. data/spec/app/models/mdm/client_spec.rb +43 -0
  256. data/spec/app/models/mdm/cred_spec.rb +346 -0
  257. data/spec/app/models/mdm/event_spec.rb +90 -0
  258. data/spec/app/models/mdm/exploit_attempt_spec.rb +59 -0
  259. data/spec/app/models/mdm/exploited_host_spec.rb +44 -0
  260. data/spec/app/models/mdm/host_detail_spec.rb +48 -0
  261. data/spec/app/models/mdm/host_spec.rb +1139 -0
  262. data/spec/app/models/mdm/host_tag_spec.rb +69 -0
  263. data/spec/app/models/mdm/listener_spec.rb +107 -0
  264. data/spec/app/models/mdm/loot_spec.rb +84 -0
  265. data/spec/app/models/mdm/macro_spec.rb +3 -0
  266. data/spec/app/models/mdm/mod_ref_spec.rb +3 -0
  267. data/spec/app/models/mdm/module/action_spec.rb +34 -0
  268. data/spec/app/models/mdm/module/arch_spec.rb +34 -0
  269. data/spec/app/models/mdm/module/author_spec.rb +52 -0
  270. data/spec/app/models/mdm/module/detail_spec.rb +746 -0
  271. data/spec/app/models/mdm/module/mixin_spec.rb +34 -0
  272. data/spec/app/models/mdm/module/platform_spec.rb +34 -0
  273. data/spec/app/models/mdm/module/ref_spec.rb +58 -0
  274. data/spec/app/models/mdm/module/target_spec.rb +36 -0
  275. data/spec/app/models/mdm/nexpose_console_spec.rb +146 -0
  276. data/spec/app/models/mdm/note_spec.rb +91 -0
  277. data/spec/app/models/mdm/profile_spec.rb +3 -0
  278. data/spec/app/models/mdm/ref_spec.rb +71 -0
  279. data/spec/app/models/mdm/route_spec.rb +35 -0
  280. data/spec/app/models/mdm/service_spec.rb +232 -0
  281. data/spec/app/models/mdm/session_event_spec.rb +42 -0
  282. data/spec/app/models/mdm/session_spec.rb +118 -0
  283. data/spec/app/models/mdm/tag_spec.rb +116 -0
  284. data/spec/app/models/mdm/task_cred_spec.rb +51 -0
  285. data/spec/app/models/mdm/task_host_spec.rb +50 -0
  286. data/spec/app/models/mdm/task_service_spec.rb +50 -0
  287. data/spec/app/models/mdm/task_session_spec.rb +46 -0
  288. data/spec/app/models/mdm/task_spec.rb +71 -0
  289. data/spec/app/models/mdm/user_spec.rb +50 -0
  290. data/spec/app/models/mdm/vuln_attempt_spec.rb +53 -0
  291. data/spec/app/models/mdm/vuln_detail_spec.rb +65 -0
  292. data/spec/app/models/mdm/vuln_ref_spec.rb +46 -0
  293. data/spec/app/models/mdm/vuln_spec.rb +299 -0
  294. data/spec/app/models/mdm/web_form_spec.rb +46 -0
  295. data/spec/app/models/mdm/web_page_spec.rb +101 -0
  296. data/spec/app/models/mdm/web_site_spec.rb +85 -0
  297. data/spec/app/models/mdm/web_vuln_spec.rb +312 -0
  298. data/spec/app/models/mdm/wmap_request_spec.rb +5 -0
  299. data/spec/app/models/mdm/wmap_target_spec.rb +5 -0
  300. data/spec/app/models/mdm/workspace_spec.rb +500 -0
  301. data/spec/app/models/metasploit_data_models/automatic_exploitation/match_result_spec.rb +86 -0
  302. data/spec/app/models/metasploit_data_models/automatic_exploitation/match_set_spec.rb +46 -0
  303. data/spec/app/models/metasploit_data_models/automatic_exploitation/match_spec.rb +37 -0
  304. data/spec/app/models/metasploit_data_models/automatic_exploitation/run_spec.rb +38 -0
  305. data/spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb +119 -0
  306. data/spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb +149 -0
  307. data/spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb +298 -0
  308. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb +276 -0
  309. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb +302 -0
  310. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb +27 -0
  311. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +324 -0
  312. data/spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb +181 -0
  313. data/spec/app/models/metasploit_data_models/module_run_spec.rb +134 -0
  314. data/spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb +180 -0
  315. data/spec/app/models/metasploit_data_models/search/operation/port/number_spec.rb +39 -0
  316. data/spec/app/models/metasploit_data_models/search/operation/port/range_spec.rb +138 -0
  317. data/spec/app/models/metasploit_data_models/search/operation/range_spec.rb +233 -0
  318. data/spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb +17 -0
  319. data/spec/app/models/metasploit_data_models/search/operator/multitext_spec.rb +160 -0
  320. data/spec/app/models/metasploit_data_models/search/operator/port/list_spec.rb +162 -0
  321. data/spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb +96 -0
  322. data/spec/app/models/metasploit_data_models/search/visitor/includes_spec.rb +175 -0
  323. data/spec/app/models/metasploit_data_models/search/visitor/joins_spec.rb +396 -0
  324. data/spec/app/models/metasploit_data_models/search/visitor/method_spec.rb +49 -0
  325. data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +925 -0
  326. data/spec/app/models/metasploit_data_models/search/visitor/where_spec.rb +187 -0
  327. data/spec/dummy/Rakefile +7 -0
  328. data/spec/dummy/app/assets/config/manifest.js +1 -0
  329. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  330. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  331. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  332. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  333. data/spec/dummy/app/mailers/.gitkeep +0 -0
  334. data/spec/dummy/app/models/.gitkeep +0 -0
  335. data/spec/dummy/app/models/application_record.rb +3 -0
  336. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  337. data/spec/dummy/bin/bundle +3 -0
  338. data/spec/dummy/bin/rails +4 -0
  339. data/spec/dummy/bin/rake +4 -0
  340. data/spec/dummy/config/application.rb +61 -0
  341. data/spec/dummy/config/boot.rb +4 -0
  342. data/spec/dummy/config/database.yml.example +22 -0
  343. data/spec/dummy/config/database.yml.github_actions +21 -0
  344. data/spec/dummy/config/environment.rb +5 -0
  345. data/spec/dummy/config/environments/development.rb +37 -0
  346. data/spec/dummy/config/environments/production.rb +78 -0
  347. data/spec/dummy/config/environments/test.rb +39 -0
  348. data/spec/dummy/config/initializers/active_record_migrations.rb +4 -0
  349. data/spec/dummy/config/initializers/assets.rb +8 -0
  350. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  351. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  352. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  353. data/spec/dummy/config/initializers/inflections.rb +16 -0
  354. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  355. data/spec/dummy/config/initializers/session_store.rb +3 -0
  356. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  357. data/spec/dummy/config/locales/en.yml +23 -0
  358. data/spec/dummy/config/routes.rb +2 -0
  359. data/spec/dummy/config.ru +4 -0
  360. data/spec/dummy/db/structure.sql +3430 -0
  361. data/spec/dummy/db/structure.sql.from_rails_3 +3403 -0
  362. data/spec/dummy/lib/assets/.gitkeep +0 -0
  363. data/spec/dummy/log/.gitkeep +0 -0
  364. data/spec/dummy/public/404.html +26 -0
  365. data/spec/dummy/public/422.html +26 -0
  366. data/spec/dummy/public/500.html +25 -0
  367. data/spec/dummy/public/favicon.ico +0 -0
  368. data/spec/dummy/script/rails +6 -0
  369. data/spec/factories/mdm/addresses.rb +12 -0
  370. data/spec/factories/mdm/clients.rb +8 -0
  371. data/spec/factories/mdm/creds.rb +17 -0
  372. data/spec/factories/mdm/events.rb +15 -0
  373. data/spec/factories/mdm/exploit_attempts.rb +8 -0
  374. data/spec/factories/mdm/exploited_hosts.rb +7 -0
  375. data/spec/factories/mdm/fingerprints/nessus_fingerprints.rb +6 -0
  376. data/spec/factories/mdm/fingerprints/nexpose_fingerprints.rb +6 -0
  377. data/spec/factories/mdm/fingerprints/nmap_fingerprints.rb +6 -0
  378. data/spec/factories/mdm/fingerprints/retina_fingerprints.rb +6 -0
  379. data/spec/factories/mdm/fingerprints/session_fingerprints.rb +6 -0
  380. data/spec/factories/mdm/host_details.rb +8 -0
  381. data/spec/factories/mdm/host_tags.rb +9 -0
  382. data/spec/factories/mdm/hosts.rb +85 -0
  383. data/spec/factories/mdm/listeners.rb +12 -0
  384. data/spec/factories/mdm/loots.rb +11 -0
  385. data/spec/factories/mdm/module/actions.rb +14 -0
  386. data/spec/factories/mdm/module/archs.rb +14 -0
  387. data/spec/factories/mdm/module/authors.rb +22 -0
  388. data/spec/factories/mdm/module/details.rb +73 -0
  389. data/spec/factories/mdm/module/mixins.rb +14 -0
  390. data/spec/factories/mdm/module/platforms.rb +14 -0
  391. data/spec/factories/mdm/module/refs.rb +14 -0
  392. data/spec/factories/mdm/module/targets.rb +19 -0
  393. data/spec/factories/mdm/nexpose_consoles.rb +15 -0
  394. data/spec/factories/mdm/notes.rb +12 -0
  395. data/spec/factories/mdm/refs.rb +9 -0
  396. data/spec/factories/mdm/routes.rb +36 -0
  397. data/spec/factories/mdm/services.rb +41 -0
  398. data/spec/factories/mdm/session_events.rb +8 -0
  399. data/spec/factories/mdm/sessions.rb +13 -0
  400. data/spec/factories/mdm/tags.rb +14 -0
  401. data/spec/factories/mdm/task.rb +16 -0
  402. data/spec/factories/mdm/task_creds.rb +9 -0
  403. data/spec/factories/mdm/task_hosts.rb +9 -0
  404. data/spec/factories/mdm/task_services.rb +8 -0
  405. data/spec/factories/mdm/task_sessions.rb +8 -0
  406. data/spec/factories/mdm/users.rb +22 -0
  407. data/spec/factories/mdm/vuln_attempts.rb +8 -0
  408. data/spec/factories/mdm/vuln_details.rb +8 -0
  409. data/spec/factories/mdm/vuln_refs.rb +4 -0
  410. data/spec/factories/mdm/vulns.rb +20 -0
  411. data/spec/factories/mdm/web_forms.rb +33 -0
  412. data/spec/factories/mdm/web_pages.rb +64 -0
  413. data/spec/factories/mdm/web_sites.rb +8 -0
  414. data/spec/factories/mdm/web_vulns.rb +64 -0
  415. data/spec/factories/mdm/workspaces.rb +23 -0
  416. data/spec/factories/metasploit_data_models/automatic_exploitation/match_results.rb +7 -0
  417. data/spec/factories/metasploit_data_models/automatic_exploitation/match_sets.rb +8 -0
  418. data/spec/factories/metasploit_data_models/automatic_exploitation/matches.rb +7 -0
  419. data/spec/factories/metasploit_data_models/automatic_exploitation/runs.rb +6 -0
  420. data/spec/factories/module_runs.rb +40 -0
  421. data/spec/lib/base64_serializer_spec.rb +172 -0
  422. data/spec/lib/ipaddr_spec.rb +29 -0
  423. data/spec/lib/metasploit_data_models/ip_address/cidr_spec.rb +356 -0
  424. data/spec/lib/metasploit_data_models/ip_address/range_spec.rb +75 -0
  425. data/spec/lib/metasploit_data_models/match/child_spec.rb +59 -0
  426. data/spec/lib/metasploit_data_models/match/parent_spec.rb +153 -0
  427. data/spec/lib/metasploit_data_models_spec.rb +13 -0
  428. data/spec/spec_helper.rb +148 -0
  429. data/spec/support/matchers/match_regex_exactly.rb +28 -0
  430. data/spec/support/shared/contexts/rex/text.rb +15 -0
  431. data/spec/support/shared/examples/coerces_inet_column_type_to_string.rb +15 -0
  432. data/spec/support/shared/examples/mdm/module/detail/does_not_support_stance_with_mtype.rb +20 -0
  433. data/spec/support/shared/examples/mdm/module/detail/supports_stance_with_mtype.rb +36 -0
  434. data/spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb +109 -0
  435. data/spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_children.rb +38 -0
  436. data/spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_metasploit_model_search_operation_base.rb +26 -0
  437. data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record.rb +50 -0
  438. data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_equality.rb +34 -0
  439. data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_metasploit_model_search_group_base.rb +51 -0
  440. metadata +444 -6
@@ -0,0 +1,79 @@
1
+ # Search operation on an attribute that holds a port number and is being search with a range of port numbers. The
2
+ # range is specified as `<min>-<max>` with `<min>` being less than `<max>` and both being within
3
+ # {MetasploitDataModels::Search::Operation::Port::Range the valid port range}.
4
+ class MetasploitDataModels::Search::Operation::Port::Range < MetasploitDataModels::Search::Operation::Range
5
+ #
6
+ # Validations
7
+ #
8
+
9
+ validate :ports
10
+
11
+ #
12
+ # Instance Methods
13
+ #
14
+
15
+ # Sets `#value` to a range of ports.
16
+ #
17
+ # @param formatted_value [#to_s] '\d+-\d+'
18
+ def value=(formatted_value)
19
+ super(formatted_value)
20
+
21
+ # could not be a `Range` if super conversion failed
22
+ # setters return the argument, not the return value from the method, so access `#value` directly
23
+ if value.is_a? Range
24
+ begin
25
+ # use Integer() instead of String#to_i as String#to_i will ignore trailing letters (i.e. '1two' -> 1) and turn all
26
+ # string without an integer in it to 0.
27
+ integer_begin = Integer(value.begin.to_s)
28
+ integer_end = Integer(value.end.to_s)
29
+ rescue ArgumentError
30
+ # setter returned is ignored in MRI, but do it anyway for other implementation
31
+ @value
32
+ else
33
+ @value = Range.new(integer_begin, integer_end)
34
+ end
35
+ else
36
+ # setter returned is ignored in MRI, but do it anyway for other implementation
37
+ # return unconvertible value from `super`
38
+ @value
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # @note `#value` should be check to be a `Range` before calling {#port}.
45
+ #
46
+ # Validate that either `Range#begin` or `Range#end` is a valid port number in `#value`
47
+ #
48
+ # @param extreme [:begin, :end] Which extreme of the `Range` in `value` to validate.
49
+ # @return [void]
50
+ def port(extreme)
51
+ extreme_value = value.send(extreme)
52
+
53
+ if extreme_value.is_a? Integer
54
+ unless MetasploitDataModels::Search::Operation::Port::Number::RANGE.cover?(extreme_value)
55
+ errors.add(
56
+ :value,
57
+ :port_range_extreme_inclusion,
58
+ extreme: extreme,
59
+ extreme_value: extreme_value,
60
+ maximum: MetasploitDataModels::Search::Operation::Port::Number::MAXIMUM,
61
+ minimum: MetasploitDataModels::Search::Operation::Port::Number::MINIMUM
62
+ )
63
+ end
64
+ else
65
+ errors.add(:value, :port_range_extreme_not_an_integer, extreme: extreme, extreme_value: extreme_value)
66
+ end
67
+ end
68
+
69
+ # Validates that the `Range#begin` and `Range#end` of `#value` are valid port numbers.
70
+ #
71
+ # @return [void]
72
+ def ports
73
+ if value.is_a? Range
74
+ [:begin, :end].each do |extreme|
75
+ port(extreme)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,56 @@
1
+ # Search operation on a `Range`.
2
+ class MetasploitDataModels::Search::Operation::Range < Metasploit::Model::Search::Operation::Base
3
+ #
4
+ # CONSTANTS
5
+ #
6
+
7
+ # Separates beginning from end of the range.
8
+ SEPARATOR = '-'
9
+
10
+ #
11
+ # Validation
12
+ #
13
+
14
+ validate :ordered
15
+ validate :range
16
+
17
+ #
18
+ # Instance Methods
19
+ #
20
+
21
+ # Sets `#value` to a `Range` composed by separating `formatted_value` by `-`.
22
+ #
23
+ # @param formatted_value [#to_s]
24
+ # @return [Range<String>]
25
+ def value=(formatted_value)
26
+ range_arguments = formatted_value.to_s.split(SEPARATOR, 2)
27
+
28
+ begin
29
+ @value = Range.new(*range_arguments)
30
+ rescue ArgumentError
31
+ @value = formatted_value
32
+ end
33
+
34
+ @value
35
+ end
36
+
37
+ private
38
+
39
+ # Validates that `#value` is a `Range` with `Range#begin` less than or equal to `Range#begin`
40
+ #
41
+ # @return [void]
42
+ def ordered
43
+ if value.is_a?(Range) && value.begin > value.end
44
+ errors.add(:value, :order, begin: value.begin.inspect, end: value.end.inspect)
45
+ end
46
+ end
47
+
48
+ # Validates that `#value` is a `Range`
49
+ #
50
+ # @return [void]
51
+ def range
52
+ unless value.is_a? Range
53
+ errors.add(:value, :range)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,33 @@
1
+ # Operator for `inet` columns in a PostgreSQL database, which operates on formatted values using
2
+ # {MetasploitDataModels::Search::Operation::IPAddress}.
3
+ class MetasploitDataModels::Search::Operator::IPAddress < Metasploit::Model::Search::Operator::Single
4
+ #
5
+ # Attributes
6
+ #
7
+
8
+ # @!attribute [r] attribute
9
+ # The attribute on `Metasploit::Model::Search::Operator::Base#klass` that is searchable.
10
+ #
11
+ # @return [Symbol] the attribute name
12
+ attr_accessor :attribute
13
+
14
+ #
15
+ # Validations
16
+ #
17
+
18
+ validates :attribute,
19
+ presence: true
20
+
21
+ #
22
+ # Instance Methods
23
+ #
24
+
25
+ alias_method :name, :attribute
26
+
27
+ # The class used for `Metasploit::Model::Search::Operator::Single#operate_on`.
28
+ #
29
+ # @return [String] `'MetasploitDataModels::Search::Operation::IPAddress'`
30
+ def operation_class_name
31
+ @operation_class_name ||= 'MetasploitDataModels::Search::Operation::IPAddress'
32
+ end
33
+ end
@@ -0,0 +1,73 @@
1
+ require 'shellwords'
2
+
3
+ # Searches multiple text fields by breaking up the formatted value into words and doing text search for each word across
4
+ # each operator named in {#operator_names}.
5
+ class MetasploitDataModels::Search::Operator::Multitext < Metasploit::Model::Search::Operator::Group::Intersection
6
+ #
7
+ # Attributes
8
+ #
9
+
10
+ # @!attribute name
11
+ # The name of this operator.
12
+ #
13
+ # @return [Symbol]
14
+ attr_accessor :name
15
+
16
+ # @!attribute operator_names
17
+ # The name of the operators to search across.
18
+ #
19
+ # @return [Array<Symbol>]
20
+ attr_writer :operator_names
21
+
22
+ #
23
+ # Validations
24
+ #
25
+
26
+ validates :operator_names,
27
+ length: {
28
+ minimum: 2
29
+ }
30
+ validates :name,
31
+ presence: true
32
+
33
+ #
34
+ # Instance Methods
35
+ #
36
+
37
+ # Breaks `formatted_value` into words using `Shellwords.split`. Each word is then searched across all {#operators},
38
+ # where any operator can match for that word. The search for multiple multiple is intersected, so that additional
39
+ # words can refine the search.
40
+ #
41
+ # @param formatted_value [#to_s]
42
+ # @return [Array<Metasploit::Model::Search::Operation::Group::Union>] Unions to be intersected.
43
+ def children(formatted_value)
44
+ words = Shellwords.split formatted_value.to_s
45
+
46
+ words.map { |word|
47
+ child_operators = operators.map { |operator|
48
+ operator.operate_on(word)
49
+ }
50
+
51
+ Metasploit::Model::Search::Operation::Group::Union.new(
52
+ children: child_operators,
53
+ operator: self
54
+ )
55
+ }
56
+ end
57
+
58
+ # The name of the operators to search for each word.
59
+ #
60
+ # @return [Array<Symbol>] Default to `[]`
61
+ def operator_names
62
+ @operator_names ||= []
63
+ end
64
+
65
+ # Operators with {#operator_names}.
66
+ #
67
+ # @return [Array<Metasploit::Model::Search::Operator::Base>]
68
+ def operators
69
+ @operators ||= operator_names.map { |operator_name|
70
+ operator(operator_name)
71
+ }
72
+ end
73
+ end
@@ -0,0 +1,67 @@
1
+ # Searches for a network port attribute. Ports can be given as a single number or range of numbers and either or both
2
+ # forms can be combined into a comma separated list. Individual port numbers are validated to be greater than 0 and
3
+ class MetasploitDataModels::Search::Operator::Port::List < Metasploit::Model::Search::Operator::Group::Union
4
+ #
5
+ # CONSTANTS
6
+ #
7
+
8
+ # Separates port number and/or port ranges
9
+ SEPARATOR = ','
10
+
11
+ #
12
+ # Attributes
13
+ #
14
+
15
+ # @!attribute [rw] attribute
16
+ # Attribute holding port number.
17
+ #
18
+ # @return [Symbol] `:port`
19
+ attr_writer :attribute
20
+
21
+ #
22
+ # Class Methods
23
+ #
24
+
25
+ # @note Can't be called `name` because it would alias `Class#name`
26
+ #
27
+ # Name of this operator.
28
+ #
29
+ # @return [String] `'port_list'`
30
+ def self.operator_name
31
+ 'port_list'
32
+ end
33
+
34
+ #
35
+ # Instance Methods
36
+ #
37
+
38
+ # Defaults to `:port`.
39
+ #
40
+ # @return [Symbol]
41
+ def attribute
42
+ @attribute ||= :port
43
+ end
44
+
45
+ # Turns `{#attribute}:<number>,<range>` into the union of port <number> and port <range> searches.
46
+ #
47
+ # @param formatted_value [String] comma separated list of port numbers and ranges.
48
+ # @return [Array<Metasploit::Model::Search::Operation::Base]
49
+ def children(formatted_value)
50
+ separated_formatted_values = formatted_value.split(SEPARATOR)
51
+
52
+ separated_formatted_values.collect { |separated_formatted_value|
53
+ operation_class = MetasploitDataModels::Search::Operation::Port::Number
54
+
55
+ if separated_formatted_value.include? MetasploitDataModels::Search::Operation::Range::SEPARATOR
56
+ operation_class = MetasploitDataModels::Search::Operation::Port::Range
57
+ end
58
+
59
+ operation_class.new(
60
+ value: separated_formatted_value,
61
+ operator: self
62
+ )
63
+ }
64
+ end
65
+
66
+ alias_method :name, :attribute
67
+ end
@@ -0,0 +1,17 @@
1
+ # Extracts the `Arel::Attribute` objects from `Metasploit::Model::Search::Operator::Base` subclasses.
2
+ class MetasploitDataModels::Search::Visitor::Attribute
3
+ include Metasploit::Model::Visitation::Visit
4
+
5
+ visit 'Metasploit::Model::Search::Operator::Association' do |operator|
6
+ visit operator.source_operator
7
+ end
8
+
9
+ visit 'Metasploit::Model::Search::Operator::Attribute',
10
+ 'MetasploitDataModels::Search::Operator::IPAddress',
11
+ 'MetasploitDataModels::Search::Operator::Port::List' do |operator|
12
+ table = operator.klass.arel_table
13
+ table[operator.attribute]
14
+ end
15
+
16
+ Metasploit::Concern.run(self)
17
+ end
@@ -0,0 +1,47 @@
1
+ # Gathers all the association names to pass to `ActiveRecord::Relation#includes` from a
2
+ # `Metasploit::Model::Search::Query`
3
+ class MetasploitDataModels::Search::Visitor::Includes
4
+ include Metasploit::Model::Visitation::Visit
5
+
6
+ #
7
+ # Visitors
8
+ #
9
+
10
+ visit 'Metasploit::Model::Search::Group::Base',
11
+ 'Metasploit::Model::Search::Operation::Group::Base' do |parent|
12
+ parent.children.flat_map { |child|
13
+ visit child
14
+ }
15
+ end
16
+
17
+ visit 'Metasploit::Model::Search::Operation::Association' do |operation|
18
+ association = visit operation.operator
19
+ nested_associations = visit operation.source_operation
20
+
21
+ if nested_associations.empty?
22
+ [association]
23
+ else
24
+ [
25
+ {
26
+ association => nested_associations
27
+ }
28
+ ]
29
+ end
30
+ end
31
+
32
+ visit 'Metasploit::Model::Search::Operation::Base' do |operation|
33
+ visit operation.operator
34
+ end
35
+
36
+ visit 'Metasploit::Model::Search::Operator::Association' do |operator|
37
+ operator.association
38
+ end
39
+
40
+ visit 'Metasploit::Model::Search::Operator::Attribute',
41
+ 'MetasploitDataModels::Search::Operator::IPAddress',
42
+ 'MetasploitDataModels::Search::Operator::Port::List' do |_operator|
43
+ []
44
+ end
45
+
46
+ Metasploit::Concern.run(self)
47
+ end
@@ -0,0 +1,67 @@
1
+ # Gathers all the association names to pass to `ActiveRecord::Relation#joins` from a `Metasploit::Model::Search::Query`
2
+ class MetasploitDataModels::Search::Visitor::Joins
3
+ include Metasploit::Model::Visitation::Visit
4
+
5
+ #
6
+ # Visitors
7
+ #
8
+
9
+ visit 'Metasploit::Model::Search::Group::Intersection',
10
+ 'Metasploit::Model::Search::Operation::Group::Intersection' do |parent|
11
+ parent.children.flat_map { |child|
12
+ visit child
13
+ }
14
+ end
15
+
16
+ visit 'Metasploit::Model::Search::Group::Union',
17
+ 'Metasploit::Model::Search::Operation::Group::Union' do |parent|
18
+ # A Set<Set> because if all children have multiple joins, but those multiple joins contain the same elements for
19
+ # all children, then all joins can be counted as common:
20
+ #
21
+ # (a.b:1 && c.d:2) || (a.b:3 && c.d:4) should return [:a, :c] since its common to both
22
+ # (a.b:1 && c.d:2 && e.f:3) || (a.b:3 && c.d:4) should return [:a, :c] since its the common _subset_
23
+ join_set_set = parent.children.each_with_object(Set.new) { |child, set|
24
+ child_joins = visit child
25
+ child_join_set = Set.new child_joins
26
+
27
+ set.add child_join_set
28
+ }
29
+
30
+ common_join_set = join_set_set.reduce { |common_subset, set|
31
+ common_subset & set
32
+ }
33
+
34
+ common_join_set.to_a
35
+ end
36
+
37
+ visit 'Metasploit::Model::Search::Operation::Association' do |operation|
38
+ association = visit operation.operator
39
+ nested_associations = visit operation.source_operation
40
+
41
+ if nested_associations.empty?
42
+ [association]
43
+ else
44
+ [
45
+ {
46
+ association => nested_associations
47
+ }
48
+ ]
49
+ end
50
+ end
51
+
52
+ visit 'Metasploit::Model::Search::Operation::Base' do |operation|
53
+ visit operation.operator
54
+ end
55
+
56
+ visit 'Metasploit::Model::Search::Operator::Association' do |operator|
57
+ operator.association
58
+ end
59
+
60
+ visit 'Metasploit::Model::Search::Operator::Attribute',
61
+ 'MetasploitDataModels::Search::Operator::IPAddress',
62
+ 'MetasploitDataModels::Search::Operator::Port::List' do |_|
63
+ []
64
+ end
65
+
66
+ Metasploit::Concern.run(self)
67
+ end
@@ -0,0 +1,16 @@
1
+ # Extracts which AREL method to use as a translation for `Metasploit::Model::Search::Group::Base` subclasses.
2
+ class MetasploitDataModels::Search::Visitor::Method
3
+ include Metasploit::Model::Visitation::Visit
4
+
5
+ visit 'Metasploit::Model::Search::Group::Intersection',
6
+ 'Metasploit::Model::Search::Operation::Group::Intersection' do
7
+ :and
8
+ end
9
+
10
+ visit 'Metasploit::Model::Search::Group::Union',
11
+ 'Metasploit::Model::Search::Operation::Group::Union' do
12
+ :or
13
+ end
14
+
15
+ Metasploit::Concern.run(self)
16
+ end
@@ -0,0 +1,91 @@
1
+ # Generates a `ActiveRecord::Relation` from an `Metasploit::Model::Search::Query#tree`
2
+ class MetasploitDataModels::Search::Visitor::Relation < Metasploit::Model::Base
3
+ #
4
+ # CONSTANTS
5
+ #
6
+
7
+ # `ActiveRecord::Relation` methods that can compute their argument with a visitor under the
8
+ # {MetasploitDataModels::Search::Visitor} namespace.
9
+ RELATION_METHODS = [
10
+ :joins,
11
+ :includes,
12
+ :where
13
+ ]
14
+
15
+ #
16
+ # Attributes
17
+ #
18
+
19
+ # @!attribute [rw] query
20
+ # The query to visit. Query supplies Class with #scope upon which to build `ActiveRecord::Relation`.
21
+ #
22
+ # @return [Metasploit::Model::Search::Query]
23
+ attr_accessor :query
24
+
25
+ #
26
+ # Validations
27
+ #
28
+
29
+ validate :valid_query
30
+
31
+ validates :query,
32
+ :presence => true
33
+
34
+ #
35
+ # Methods
36
+ #
37
+
38
+ # Visits {#query} tree to produce an `ActiveRecord::Relation` on the `Metasploit::Model::Search::Query#klass`.
39
+ #
40
+ # @return [ActiveRecord::Relation]
41
+ def visit
42
+ tree = query.tree
43
+
44
+ # Enumerable#inject does not support 3 arity for Hashes so need to unpack pair
45
+ visitor_by_relation_method.inject(query.klass.all) do |relation, pair|
46
+ relation_method, visitor = pair
47
+ visited = visitor.visit(tree)
48
+ relation.send(relation_method, visited)
49
+ end
50
+ end
51
+
52
+ # Map method on `ActiveRecord::Relation` to visitor that can visit `Metasploit::Model::Search::Query#tree` to
53
+ # produce the arguments to the method on `ActiveRecord::Relation`.
54
+ #
55
+ # @return [Hash{Symbol => #visit}]
56
+ def visitor_by_relation_method
57
+ # Enumerable#each_with_object does not support 3 arity for Hashes so need to unpack pair
58
+ @visitor_by_relation_method ||= self.class.visitor_class_by_relation_method.each_with_object({}) { |pair, visitor_by_relation_method|
59
+ relation_method, visitor_class = pair
60
+ visitor_by_relation_method[relation_method] = visitor_class.new
61
+ }
62
+ end
63
+
64
+ # Maps method on `ActiveRecord::Relation` to the `Class` under {MetasploitDataModels::Search::Visitor} whose
65
+ # `#visit` method can produce the arguments to the `ActiveRecord::Relation` method.
66
+ #
67
+ # @return [Hash{Symbol => Class}]
68
+ def self.visitor_class_by_relation_method
69
+ @relation_method_by_visitor_class ||= RELATION_METHODS.each_with_object({}) { |relation_method, relation_method_by_visitor_class|
70
+ visitor_class_name = "#{parent.name}::#{relation_method.to_s.camelize}"
71
+ visitor_class = visitor_class_name.constantize
72
+
73
+ relation_method_by_visitor_class[relation_method] = visitor_class
74
+ }
75
+ end
76
+
77
+ private
78
+
79
+ # Validates that {#query} is valid.
80
+ #
81
+ # @return [void]
82
+ def valid_query
83
+ if query and !query.valid?
84
+ errors.add(:query, :invalid)
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ Metasploit::Concern.run(self)
91
+ end
@@ -0,0 +1,128 @@
1
+ # Generates AREL to pass to `ActiveRecord::Relation#where` from a `Metasploit::Model::Search::Query`.
2
+ class MetasploitDataModels::Search::Visitor::Where
3
+ include Metasploit::Model::Visitation::Visit
4
+
5
+ #
6
+ # CONSTANTS
7
+ #
8
+
9
+ # `Metasploit::Model::Search::Operation::Base` subclasses that check their value with the equality operator in
10
+ # AREL
11
+ EQUALITY_OPERATION_CLASS_NAMES = [
12
+ 'Metasploit::Model::Search::Operation::Boolean',
13
+ 'Metasploit::Model::Search::Operation::Date',
14
+ 'Metasploit::Model::Search::Operation::Integer',
15
+ 'Metasploit::Model::Search::Operation::Set'
16
+ ]
17
+
18
+ #
19
+ # Visitor
20
+ #
21
+
22
+ visit 'Metasploit::Model::Search::Group::Base',
23
+ 'Metasploit::Model::Search::Operation::Group::Base' do |parent|
24
+ method = method_visitor.visit parent
25
+
26
+ children_arel = parent.children.collect { |child|
27
+ visit child
28
+ }
29
+
30
+ children_arel.inject { |group_arel, child_arel|
31
+ group_arel.send(method, child_arel)
32
+ }
33
+ end
34
+
35
+ visit(*EQUALITY_OPERATION_CLASS_NAMES) do |operation|
36
+ attribute = attribute_visitor.visit operation.operator
37
+
38
+ attribute.eq(operation.value)
39
+ end
40
+
41
+ visit 'Metasploit::Model::Search::Operation::Association' do |operation|
42
+ visit operation.source_operation
43
+ end
44
+
45
+ visit 'Metasploit::Model::Search::Operation::String' do |operation|
46
+ attribute = attribute_visitor.visit operation.operator
47
+ match_value = "%#{operation.value}%"
48
+
49
+ attribute.matches(match_value)
50
+ end
51
+
52
+ visit 'MetasploitDataModels::IPAddress::CIDR' do |cidr|
53
+ cast_to_inet "#{cidr.address}/#{cidr.prefix_length}"
54
+ end
55
+
56
+ visit 'MetasploitDataModels::IPAddress::Range' do |ip_address_range|
57
+ range = ip_address_range.value
58
+
59
+ begin_node = visit range.begin
60
+ end_node = visit range.end
61
+
62
+ # AND nodes should be created with a list
63
+ Arel::Nodes::And.new([begin_node, end_node])
64
+ end
65
+
66
+ visit 'MetasploitDataModels::IPAddress::V4::Single' do |ip_address|
67
+ cast_to_inet(ip_address.to_s)
68
+ end
69
+
70
+ visit 'MetasploitDataModels::Search::Operation::IPAddress' do |operation|
71
+ attribute = attribute_visitor.visit operation.operator
72
+ value = operation.value
73
+ value_node = visit value
74
+
75
+ case value
76
+ when MetasploitDataModels::IPAddress::CIDR
77
+ Arel::Nodes::InfixOperation.new(
78
+ '<<',
79
+ attribute,
80
+ value_node
81
+ )
82
+ when MetasploitDataModels::IPAddress::Range
83
+ Arel::Nodes::Between.new(attribute, value_node)
84
+ when MetasploitDataModels::IPAddress::V4::Single
85
+ Arel::Nodes::Equality.new(attribute, value_node)
86
+ else
87
+ raise TypeError, "Don't know how to handle #{value.class}"
88
+ end
89
+ end
90
+
91
+ visit 'MetasploitDataModels::Search::Operation::Port::Range' do |range_operation|
92
+ attribute = attribute_visitor.visit range_operation.operator
93
+
94
+ attribute.between(range_operation.value)
95
+ end
96
+
97
+ #
98
+ # Methods
99
+ #
100
+
101
+ # Visitor for `Metasploit::Model::Search::Operator::Base` subclasses to generate `Arel::Attributes::Attribute`.
102
+ #
103
+ # @return [MetasploitDataModels::Search::Visitor::Attribute]
104
+ def attribute_visitor
105
+ @attribute_visitor ||= MetasploitDataModels::Search::Visitor::Attribute.new
106
+ end
107
+
108
+ # Visitor for `Metasploit::Model::Search::Group::Base` subclasses to generate equivalent AREL node methods.
109
+ #
110
+ # @return [MetasploitDataModels::Search::Visitor::Method]
111
+ def method_visitor
112
+ @method_visitor ||= MetasploitDataModels::Search::Visitor::Method.new
113
+ end
114
+
115
+ private
116
+
117
+ # Casts a literal string to INET in AREL.
118
+ #
119
+ # @return [Arel::Nodes::NamedFunction]
120
+ def cast_to_inet(string)
121
+ cast_argument = Arel::Nodes::As.new(Arel::Nodes.build_quoted(string), Arel::Nodes::SqlLiteral.new('INET'))
122
+ Arel::Nodes::NamedFunction.new('CAST', [cast_argument])
123
+ end
124
+
125
+ public
126
+
127
+ Metasploit::Concern.run(self)
128
+ end
@@ -0,0 +1,5 @@
1
+ # Including arel-helpers in all active record models.
2
+ # https://github.com/camertron/arel-helpers
3
+
4
+ ApplicationRecord.send(:include, ArelHelpers::ArelTable)
5
+ ApplicationRecord.send(:include, ArelHelpers::JoinAssociation)