Class: InsightVMApi
- Inherits:
-
Object
- Object
- InsightVMApi
- Defined in:
- lib/domain/tag/api.rb,
lib/domain/site/api.rb,
lib/domain/asset/api.rb,
lib/domain/report/api.rb,
lib/domain/country/api.rb,
lib/domain/software/api.rb,
lib/service/api/insightvm.rb,
lib/domain/asset_group/api.rb,
lib/domain/scan_engine/api.rb,
lib/domain/site_target/api.rb,
lib/domain/scan_schedule/api.rb,
lib/domain/vulnerability/api.rb,
lib/domain/operating_system/api.rb,
lib/domain/scan_engine_pool/api.rb,
lib/domain/shared_credential/api.rb
Instance Attribute Summary collapse
-
#base_auth ⇒ Object
readonly
Returns the value of attribute base_auth.
-
#base_url ⇒ Object
readonly
Returns the value of attribute base_url.
-
#http ⇒ Object
readonly
Returns the value of attribute http.
Instance Method Summary collapse
- #_fetch_all_scan_engines_pools ⇒ Object
- #add_shared_credentials(site) ⇒ Object
- #add_site_scan_engine_pool(site_id:, pool_id:) ⇒ Object
- #add_utr_tags(vulnerability_id:, tag_ids:) ⇒ Object
- #all_asset_groups(opts) ⇒ Object
- #all_scan_engines ⇒ Object
- #all_shared_credentials ⇒ Object
- #all_site_scan_schedules(site_id:) ⇒ Object
- #all_tags ⇒ Object
-
#append_new_status(engines:, csv_file:, previous_status:) ⇒ Object
append the new engine status in the csv_file only if it is different from the previous status.
- #create_asset_group(name:, description: nil, type: 'dynamic', search_criteria: { match: 'all', filters: [] }) ⇒ Object
- #create_asset_group_for(site_id:, site_name:) ⇒ Object
- #create_report(name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: []) ⇒ Object
- #create_scan_schedule(site_id:, scan_engine_id:, scan_template_id:, duration:, repeat:, start:, on_scan_repeat: ScanSchedule::OnRepeat::RESTART, scan_name: nil, excluded_asset_group_ids: [], included_asset_group_ids: [], excluded_targets: [], included_targets: [], enabled: false) ⇒ Object
- #create_site(name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: []) ⇒ Object
- #create_tag(name:, color: 'default', risk_modifier: 1.0, type: 'custom', source: 'custom') ⇒ Object
- #create_utr_report(name:, description:, targets:, engine_id:, scan_template_id:) ⇒ Object
-
#create_utr_report_from(report_name:, cmdb_assets:, cached_tags: {}) ⇒ Object
return report.id if success only return the onboard assets.
- #create_utr_report_schedule(report_id:) ⇒ Object
- #create_utr_reports_for(business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true) ⇒ Object
- #create_utr_site(name:, description:, targets:, engine_id:, scan_template_id:) ⇒ Object
-
#create_utr_site_from(site_name:, cmdb_assets:, cached_tags: {}) ⇒ Object
return site.id if success only return the onboard assets.
- #create_utr_site_schedule(site_id:) ⇒ Object
- #create_utr_sites_for(business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true) ⇒ Object
- #create_utr_vulnerabilities_for(business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true) ⇒ Object
- #create_utr_vulnerability(name:, description:, targets:, engine_id:, scan_template_id:) ⇒ Object
-
#create_utr_vulnerability_from(vulnerability_name:, cmdb_assets:, cached_tags: {}) ⇒ Object
return vulnerability.id if success only return the onboard assets.
- #create_utr_vulnerability_schedule(vulnerability_id:) ⇒ Object
- #create_vulnerability(name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: []) ⇒ Object
- #create_weekly_scan(day_of_week:, start_hour:, country_code:, duration_in_hours:, site_id:, start_minute: 0, scan_name: nil, scan_engine_id: nil, scan_template_id: nil) ⇒ Object
- #delete_asset(id) ⇒ Object
- #delete_asset_group_by(id: nil, name: nil) ⇒ Object
-
#delete_assets(ids = [], threads = nil) ⇒ Object
Use Typhoeus for concurrency.
- #delete_report(report_id) ⇒ Object
- #delete_report_by(id:, name:) ⇒ Object
- #delete_scan_schedule(site_id:, schedule_id:) ⇒ Object
- #delete_site(site_id) ⇒ Object
- #delete_site_by(id:, name:) ⇒ Object
- #delete_utr_report_schedules(report_id:) ⇒ Object
- #delete_utr_reports ⇒ Object
- #delete_utr_site_schedules(site_id:) ⇒ Object
- #delete_utr_sites ⇒ Object
- #delete_utr_vulnerabilities ⇒ Object
- #delete_vulnerability(site_id) ⇒ Object
- #delete_vulnerability_by(site_idte_idte_idte_id:, name:) ⇒ Object
- #engine_last_status_from(csv_file) ⇒ Object
-
#fetch_all(endpoint, opts = {}, &block) ⇒ Object
Fetchs all resources.
-
#fetch_all_targets(site_id) ⇒ Object
Returns included and excluded targets for site id.
- #fetch_asset_group(site_id) ⇒ Object
- #fetch_asset_group_assets(id, opts = { read_timeout: 200 }) ⇒ Object
- #fetch_asset_group_by_name(name) ⇒ Object
- #fetch_asset_groups(opts = {}) ⇒ Object
-
#fetch_country_cyberark(country) ⇒ Object
TODO: use directly country code 2024-04-25 08:53.
-
#fetch_country_scan_engine_pools(country) ⇒ Object
return scan engines that went from up to down given the previous status in a hash if the previous status is not known, assume it was up.
- #fetch_discovery_scan_template_id(country) ⇒ Object
- #fetch_domain_cyberark(domains = []) ⇒ Object
- #fetch_microsoft_product_lifecycle(spreadsheet, tabsheet_name: 'lifecycle_data') ⇒ Object
- #fetch_report(report_id) ⇒ Object
- #fetch_report_by_name(name) ⇒ Object
- #fetch_report_cyberark_credentials(report) ⇒ Object
- #fetch_report_domains(report) ⇒ Object
- #fetch_report_shared_credentials(report_id:) ⇒ Object
- #fetch_reports ⇒ Object
- #fetch_scan_engine_pools ⇒ Object
- #fetch_scan_engines ⇒ Object
- #fetch_shared_credential(id) ⇒ Object
- #fetch_shared_credentials ⇒ Object
- #fetch_site(site_id) ⇒ Object
- #fetch_site_by_name(name) ⇒ Object
- #fetch_site_cyberark_credentials(site) ⇒ Object
- #fetch_site_domains(site) ⇒ Object
- #fetch_site_excluded_targets(site_id) ⇒ Object
- #fetch_site_included_targets(site_id) ⇒ Object
- #fetch_site_scan_schedules(site_id:) ⇒ Object
- #fetch_site_shared_credentials(site_id:) ⇒ Object
- #fetch_site_target_domains(site_id) ⇒ Object
- #fetch_sites ⇒ Object
- #fetch_tag(site_id) ⇒ Object
- #fetch_tag_by_name(name) ⇒ Object
- #fetch_tags ⇒ Object
- #fetch_utr_reports ⇒ Object
- #fetch_utr_sites ⇒ Object
- #fetch_utr_vulnerabilities ⇒ Object
- #fetch_vulnerabilities ⇒ Object
- #fetch_vulnerability(site_id) ⇒ Object
- #fetch_vulnerability_by_name(name) ⇒ Object
- #find_by_country_code(cc) ⇒ Object
-
#get_or_create_asset_group(name:, cached_asset_groups: {}) ⇒ Object
Given a asset_group name return asset_group in the cache if not found in cache, update the cache return the asset_group if the cache contains the name create the custom asset_group with name return asset_group.
-
#get_or_create_tag(name:, cached_tags: {}) ⇒ Object
Given a tag name return tag in the cache if not found in cache, update the cache return the tag if the cache contains the name create the custom tag with name return tag.
-
#initialize(base_url, username, password) ⇒ InsightVMApi
constructor
A new instance of InsightVMApi.
- #list_shared_credential_utr_sites(credential, utr_sites) ⇒ Object
- #remove_shared_credential_sites(credential, site_ids = []) ⇒ Object
- #remove_shared_credential_utr_sites(credential, utr_sites) ⇒ Object
- #scan_engine_pools ⇒ Object
-
#scan_engines_from_up_to_down(engines, previous_status) ⇒ Object
return scan engines that went from up to down given the previous status in a hash if the previous status is not known, assume it was up.
-
#scan_slot(utr_digits) ⇒ Object
return day of week and starts Time of scan ScanSchedule given the UTR digits.
- #settings ⇒ Object
- #starts_discovery_scan(vulnerability_id:) ⇒ Object
- #toggle_utr_site_schedule(site:, enabled:) ⇒ Object
- #update_report_owner(report, owner_id) ⇒ Object
- #update_scan_schedule(scan_schedule, site_id:) ⇒ Object
-
#update_shared_credential_sites(credential:, site_ids: []) ⇒ Object
Add the site_id to the shared credential sites.
- #update_xxx_report_owner(owner_id) ⇒ Object
- #upsert_site_shared_credentials(site_id:) ⇒ Object
- #upsert_utr_report_schedule(report_id:) ⇒ Object
- #upsert_utr_site_schedule(site_id:) ⇒ Object
Constructor Details
#initialize(base_url, username, password) ⇒ InsightVMApi
Returns a new instance of InsightVMApi.
61 62 63 64 65 66 67 |
# File 'lib/service/api/insightvm.rb', line 61 def initialize(base_url, username, password) @base_url = URI(base_url) @http = Net::HTTP.new(@base_url.host, @base_url.port) @http.use_ssl = true @http.verify_mode = OpenSSL::SSL::VERIFY_NONE # Reminder: Adjust for production use @base_auth = ['Basic', Base64.strict_encode64("#{username}:#{password}")].join(' ') end |
Instance Attribute Details
#base_auth ⇒ Object (readonly)
Returns the value of attribute base_auth.
12 13 14 |
# File 'lib/service/api/insightvm.rb', line 12 def base_auth @base_auth end |
#base_url ⇒ Object (readonly)
Returns the value of attribute base_url.
12 13 14 |
# File 'lib/service/api/insightvm.rb', line 12 def base_url @base_url end |
#http ⇒ Object (readonly)
Returns the value of attribute http.
12 13 14 |
# File 'lib/service/api/insightvm.rb', line 12 def http @http end |
Instance Method Details
#_fetch_all_scan_engines_pools ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/domain/scan_engine_pool/api.rb', line 17 def _fetch_all_scan_engines_pools @scan_engine_pools = [] fetch_scan_engine_pools do |scan_engine_pool| @scan_engine_pools << scan_engine_pool end @scan_engine_pools end |
#add_shared_credentials(site) ⇒ Object
260 261 262 263 264 265 266 267 |
# File 'lib/domain/site/api.rb', line 260 def add_shared_credentials(site) site_ids = [site.id] shared_credentials = fetch_site_cyberark_credentials(site) shared_credentials.each do |credential| puts "#{site.name} Shared Credential #{credential.name}" update_shared_credential_sites(credential:, site_ids:) end end |
#add_site_scan_engine_pool(site_id:, pool_id:) ⇒ Object
114 115 116 117 118 119 120 121 122 |
# File 'lib/domain/scan_engine/api.rb', line 114 def add_site_scan_engine_pool(site_id:, pool_id:) # retrieve the credential_id pool = fetch_scan_engine_pool(pool_id) return if pool.sites.include?(site_id) pool.sites += [site_id] endpoint = "/scan_engine_pool/#{pool_id}" put(endpoint, pool) end |
#add_utr_tags(vulnerability_id:, tag_ids:) ⇒ Object
269 270 271 272 273 |
# File 'lib/domain/site/api.rb', line 269 def (site_id:, tag_ids:) tag_ids.each do |tag_id| put("/sites/#{site_id}/tags/#{tag_id}", nil) end end |
#all_asset_groups(opts) ⇒ Object
24 25 26 27 28 29 30 |
# File 'lib/domain/asset_group/api.rb', line 24 def all_asset_groups(opts) asset_groups = [] fetch_asset_groups(opts) do |e| asset_groups << e end asset_groups end |
#all_scan_engines ⇒ Object
19 20 21 22 23 24 25 |
# File 'lib/domain/scan_engine/api.rb', line 19 def all_scan_engines engines = [] fetch_scan_engines do |e| engines << e end engines end |
#all_shared_credentials ⇒ Object
10 11 12 |
# File 'lib/domain/shared_credential/api.rb', line 10 def all_shared_credentials @all_shared_credentials ||= fetch_all_shared_credentials end |
#all_site_scan_schedules(site_id:) ⇒ Object
13 14 15 16 17 18 19 |
# File 'lib/domain/scan_schedule/api.rb', line 13 def all_site_scan_schedules(site_id:) schedules = [] fetch_scan_schedules(site_id:) do |e| schedules << e end schedules end |
#all_tags ⇒ Object
12 13 14 15 16 17 18 |
# File 'lib/domain/tag/api.rb', line 12 def = [] do |e| << e end end |
#append_new_status(engines:, csv_file:, previous_status:) ⇒ Object
append the new engine status in the csv_file only if it is different from the previous status
54 55 56 57 58 59 60 61 62 |
# File 'lib/domain/scan_engine/api.rb', line 54 def append_new_status(engines:, csv_file:, previous_status:) CSV.open(csv_file, 'a') do |csv| engines.each do |engine| next if previous_status[engine.id] == engine.up? csv << [Time.now.strftime('%Y-%m-%dT%H:%M'), engine.id, engine.up?.to_s] end end end |
#create_asset_group(name:, description: nil, type: 'dynamic', search_criteria: { match: 'all', filters: [] }) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/domain/asset_group/api.rb', line 80 def create_asset_group( name:, description: nil, type: 'dynamic', search_criteria: { match: 'all', filters: [] } ) params = { description:, name:, searchCriteria: search_criteria, type: } result = post('/asset_groups', params) result&.dig('id') end |
#create_asset_group_for(site_id:, site_name:) ⇒ Object
69 70 71 72 73 74 75 76 77 78 |
# File 'lib/domain/asset_group/api.rb', line 69 def create_asset_group_for(site_id:, site_name:) filter = SearchCriteria::Filter.from_site_id(site_id) search_criteria = { match: 'all', filters: [filter.to_json] } create_asset_group( name: site_name, description: "Access group for site #{site_id}", type: 'dynamic', search_criteria: ) end |
#create_report(name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: []) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/domain/report/api.rb', line 73 def create_report( name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: [] ) # Construct the request body params = { name:, description:, importance:, engineId: engine_id, scanTemplateId: scan_template_id, scan: { assets: { includedTargets: { addresses: included_targets }, excludedTargets: { addresses: excluded_targets }, includedAssetGroups: { assetGroupIDs: included_asset_group_ids }, excludedAssetGroups: { assetGroupIDs: excluded_asset_group_ids } } } } result = post('/reports', params) result&.dig('id') end |
#create_scan_schedule(site_id:, scan_engine_id:, scan_template_id:, duration:, repeat:, start:, on_scan_repeat: ScanSchedule::OnRepeat::RESTART, scan_name: nil, excluded_asset_group_ids: [], included_asset_group_ids: [], excluded_targets: [], included_targets: [], enabled: false) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/domain/scan_schedule/api.rb', line 66 def create_scan_schedule( site_id:, scan_engine_id:, scan_template_id:, duration:, repeat:, start:, on_scan_repeat: ScanSchedule::OnRepeat::RESTART, scan_name: nil, # required ISO8601 string excluded_asset_group_ids: [], included_asset_group_ids: [], excluded_targets: [], included_targets: [], enabled: false ) params = { assets: { excludedAssetGroups: { assetGroupIDs: excluded_asset_group_ids }, excludedTargets: { addresses: excluded_targets }, includedAssetGroups: { assetGroupIDs: included_asset_group_ids }, includedTargets: { addresses: included_targets } }, duration:, enabled:, start:, repeat: JSON.parse(repeat.to_json), scanEngineId: scan_engine_id, scanTemplateId: scan_template_id, onScanRepeat: on_scan_repeat, scanName: scan_name } result = post("/sites/#{site_id}/scan_schedules", params) result&.dig('id') end |
#create_site(name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: []) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/domain/site/api.rb', line 60 def create_site( name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: [] ) # Construct the request body params = { name:, description:, importance:, engineId: engine_id, scanTemplateId: scan_template_id, scan: { assets: { includedTargets: { addresses: included_targets }, excludedTargets: { addresses: excluded_targets }, includedAssetGroups: { assetGroupIDs: included_asset_group_ids }, excludedAssetGroups: { assetGroupIDs: excluded_asset_group_ids } } } } result = post('/sites', params) result&.dig('id') end |
#create_tag(name:, color: 'default', risk_modifier: 1.0, type: 'custom', source: 'custom') ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/domain/tag/api.rb', line 57 def create_tag( name:, color: 'default', risk_modifier: 1.0, type: 'custom', source: 'custom' ) params = { color:, name:, riskModifier: risk_modifier, type:, source: } result = post('/tags', params) result&.dig('id') end |
#create_utr_report(name:, description:, targets:, engine_id:, scan_template_id:) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/domain/report/api.rb', line 274 def create_utr_report( name:, description:, targets:, engine_id:, scan_template_id: ) create_report( name:, description:, importance: 'high', engine_id:, scan_template_id:, included_targets: targets ) end |
#create_utr_report_from(report_name:, cmdb_assets:, cached_tags: {}) ⇒ Object
return report.id if success only return the onboard assets
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/domain/report/api.rb', line 200 def create_utr_report_from( report_name:, cmdb_assets:, cached_tags: {} ) assets = cmdb_assets.select { |asset| asset.report_name == report_name } .select(&:onboard?) return if assets.empty? country = assets.first.country targets = assets.map(&:fqdn) scan_engine_pool = fetch_country_scan_engine_pools(country) # puts "Scan engine pool #{scan_engine_pool}" engine_id = scan_engine_pool[:id] scan_template_id = fetch_discovery_scan_template_id(country) puts puts '-' * 40 puts "Report #{report_name}\nTargets: #{targets.length} #{targets.join(' ')}" puts '-' * 40 # TODO: check if the report already exists report_id = create_utr_report( name: report_name, description: report_name, targets:, engine_id:, scan_template_id: ) if report_id.nil? puts "Report #{report_name} already exists!" return end # add report to shared credential report = fetch_report(report_id) add_shared_credentials(report) # tag assets with business unit code, sub_area, app + utr, tag_names = assets.first.utr_tag_names = tag_names.map do |tag_name| puts "\tAdd tag: #{tag_name}" get_or_create_tag(name: tag_name, cached_tags:) end tag_ids = .map(&:id) (report_id:, tag_ids:) report_id end |
#create_utr_report_schedule(report_id:) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/domain/report/api.rb', line 176 def create_utr_report_schedule(report_id:) report = fetch_report(report_id) raise 'The report is not a valid UTR report' unless report.utr? scan_name = report.name report.utr_digits slot = scan_slot(report.utr_digits) country_code = report.country_code scan_template_id = report.scan_template_id duration_in_hours = 2 create_weekly_scan( country_code:, day_of_week: slot[:day_of_week], start_hour: slot[:start_time], duration_in_hours:, report_id:, scan_name:, scan_template_id: ) end |
#create_utr_reports_for(business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/domain/report/api.rb', line 112 def create_utr_reports_for( business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true ) assets = cmdb_assets.select { |asset| asset.business_unit == business_unit } report_names = assets.map(&:report_name).uniq report_names.each do |report_name| report_id = create_utr_report_from( report_name:, cmdb_assets: assets, cached_tags: ) if report_id.nil? puts "Cannot create #{report_name} report" next end puts "\tCreate asset group: #{report_name}" create_asset_group_for(report_id:, report_name:) puts "\tSchedule the scan" # TODO next unless starts_discovery puts "\tStart discovery scan" starts_discovery_scan(report_id:) end end |
#create_utr_site(name:, description:, targets:, engine_id:, scan_template_id:) ⇒ Object
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/domain/site/api.rb', line 309 def create_utr_site( name:, description:, targets:, engine_id:, scan_template_id: ) create_site( name:, description:, importance: 'high', engine_id:, scan_template_id:, included_targets: targets ) end |
#create_utr_site_from(site_name:, cmdb_assets:, cached_tags: {}) ⇒ Object
return site.id if success only return the onboard assets
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/domain/site/api.rb', line 204 def create_utr_site_from( site_name:, cmdb_assets:, cached_tags: {} ) assets = cmdb_assets.select { |asset| asset.site_name == site_name } .select(&:onboard?) return if assets.empty? country = assets.first.country targets = assets.map(&:fqdn) scan_engine_pool = fetch_country_scan_engine_pools(country) # puts "Scan engine pool #{scan_engine_pool}" engine_id = scan_engine_pool[:id] scan_template_id = fetch_discovery_scan_template_id(country) puts puts '-' * 40 puts "Site #{site_name}\nTargets: #{targets.length} #{targets.join(' ')}" puts '-' * 40 # TODO: check if the site already exists site_id = create_utr_site( name: site_name, description: site_name, targets:, engine_id:, scan_template_id: ) if site_id.nil? puts "Site #{site_name} already exists!" return end # add site to shared credential site = fetch_site(site_id) add_shared_credentials(site) # tag assets with business unit code, sub_area, app + utr, tag_names = assets.first.utr_tag_names = tag_names.map do |tag_name| puts "\tAdd tag: #{tag_name}" get_or_create_tag(name: tag_name, cached_tags:) end tag_ids = .map(&:id) (site_id:, tag_ids:) site_id end |
#create_utr_site_schedule(site_id:) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/domain/site/api.rb', line 173 def create_utr_site_schedule(site_id:) site = fetch_site(site_id) raise 'The site is not a valid UTR site' unless site.utr? scan_name = site.name slot = scan_slot(site.utr_digits) country_code = site.country_code scan_template_id = site.scan_template_id duration_in_hours = 2 create_weekly_scan( country_code:, day_of_week: slot[:day_of_week], start_hour: slot[:start_time], duration_in_hours:, site_id:, scan_name:, scan_template_id: ) end |
#create_utr_sites_for(business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/domain/site/api.rb', line 99 def create_utr_sites_for( business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true ) assets = cmdb_assets.select { |asset| asset.business_unit == business_unit } site_names = assets.map(&:site_name).uniq site_names.each do |site_name| site_id = create_utr_site_from( site_name:, cmdb_assets: assets, cached_tags: ) if site_id.nil? puts "Cannot create #{site_name} site" next end puts "\tCreate asset group: #{site_name}" create_asset_group_for(site_id:, site_name:) puts "\tSchedule the scan" # TODO next unless starts_discovery puts "\tStart discovery scan" starts_discovery_scan(site_id:) end end |
#create_utr_vulnerabilities_for(business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/domain/vulnerability/api.rb', line 92 def create_utr_vulnerabilities_for( business_unit:, cmdb_assets:, cached_tags: {}, starts_discovery: true ) assets = cmdb_assets.select { |asset| asset.business_unit == business_unit } vulnerability_names = assets.map(&:vulnerability_name).uniq vulnerability_names.each do |vulnerability_name| vulnerability_id = create_utr_vulnerability_from( vulnerability_name:, cmdb_assets: assets, cached_tags: ) if vulnerability_id.nil? puts "Cannot create #{vulnerability_name} vulnerability" next end puts "\tCreate asset group: #{vulnerability_name}" create_asset_group_for(vulnerability_id:, vulnerability_name:) puts "\tSchedule the scan" # TODO next unless starts_discovery puts "\tStart discovery scan" starts_discovery_scan(vulnerability_id:) end end |
#create_utr_vulnerability(name:, description:, targets:, engine_id:, scan_template_id:) ⇒ Object
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/domain/vulnerability/api.rb', line 261 def create_utr_vulnerability( name:, description:, targets:, engine_id:, scan_template_id: ) create_vulnerability( name:, description:, importance: 'high', engine_id:, scan_template_id:, included_targets: targets ) end |
#create_utr_vulnerability_from(vulnerability_name:, cmdb_assets:, cached_tags: {}) ⇒ Object
return vulnerability.id if success only return the onboard assets
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/domain/vulnerability/api.rb', line 171 def create_utr_vulnerability_from( vulnerability_name:, cmdb_assets:, cached_tags: {} ) assets = cmdb_assets.select { |asset| asset.vulnerability_name == vulnerability_name } .select(&:onboard?) return if assets.empty? country = assets.first.country targets = assets.map(&:fqdn) scan_engine_pool = fetch_country_scan_engine_pools(country) # puts "Scan engine pool #{scan_engine_pool}" engine_id = scan_engine_pool[:id] scan_template_id = fetch_discovery_scan_template_id(country) puts puts '-' * 40 puts "Vulnerability #{vulnerability_name}\nTargets: #{targets.length} #{targets.join(' ')}" puts '-' * 40 # TODO: check if the vulnerability already exists vulnerability_id = create_utr_vulnerability( name: vulnerability_name, description: vulnerability_name, targets:, engine_id:, scan_template_id: ) if vulnerability_id.nil? puts "Vulnerability #{vulnerability_name} already exists!" return end # add vulnerability credential shared_credential = fetch_cyberark(country) puts "\tAdd credential: #{shared_credential.name}" credential_id = shared_credential.id add_vulnerability_shared_credentials(vulnerability_id:, credential_id:) # tag assets with business unit code, sub_area, app + utr, tag_names = assets.first.utr_tag_names = tag_names.map do |tag_name| puts "\tAdd tag: #{tag_name}" get_or_create_tag(name: tag_name, cached_tags:) end tag_ids = .map(&:id) (vulnerability_id:, tag_ids:) vulnerability_id end |
#create_utr_vulnerability_schedule(vulnerability_id:) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/domain/vulnerability/api.rb', line 141 def create_utr_vulnerability_schedule(vulnerability_id:) vulnerability = fetch_vulnerability(vulnerability_id) raise 'The vulnerability is not a valid UTR vulnerability' unless vulnerability.utr? scan_name = vulnerability.name vulnerability.utr_digits slot = scan_slot(vulnerability.utr_digits) scan_template_id = vulnerability.scan_template_id duration_in_hours = 2 create_weekly_scan( day_of_week: slot[:day_of_week], start_time: slot[:start_time], duration_in_hours:, vulnerability_id:, scan_name:, scan_template_id: ) end |
#create_vulnerability(name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: []) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/domain/vulnerability/api.rb', line 53 def create_vulnerability( name:, description:, engine_id:, scan_template_id:, importance: 'normal', included_targets: [], excluded_targets: [], included_asset_group_ids: [], excluded_asset_group_ids: [] ) # Construct the request body params = { name:, description:, importance:, engineId: engine_id, scanTemplateId: scan_template_id, scan: { assets: { includedTargets: { addresses: included_targets }, excludedTargets: { addresses: excluded_targets }, includedAssetGroups: { assetGroupIDs: included_asset_group_ids }, excludedAssetGroups: { assetGroupIDs: excluded_asset_group_ids } } } } result = post('/vulnerabilities', params) result&.dig('id') end |
#create_weekly_scan(day_of_week:, start_hour:, country_code:, duration_in_hours:, site_id:, start_minute: 0, scan_name: nil, scan_engine_id: nil, scan_template_id: nil) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/domain/scan_schedule/api.rb', line 21 def create_weekly_scan( day_of_week:, start_hour:, country_code:, duration_in_hours:, site_id:, start_minute: 0, scan_name: nil, scan_engine_id: nil, scan_template_id: nil ) now = DateTime.now year = now.year month = now.month day = now.day start_time = DateTime.new(year, month, day, start_hour, start_minute) local_time = Service::DateTime.closest_day_of_week(start_time, day_of_week) start = Service::TimeZone.iso8601(country_code:, local_time:) puts start puts scan_name puts country_code repeat = ScanSchedule::Repeat.new( every: 'week', day_of_week:, interval: 1 ) create_scan_schedule( site_id:, duration: "PT#{duration_in_hours}H", scan_engine_id:, scan_template_id:, repeat:, start:, scan_name: ) end |
#delete_asset(id) ⇒ Object
8 9 10 11 12 |
# File 'lib/domain/asset/api.rb', line 8 def delete_asset(id) raise 'Cannot delete asset without ID' if id.nil? delete('/assets', id) end |
#delete_asset_group_by(id: nil, name: nil) ⇒ Object
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/domain/asset_group/api.rb', line 104 def delete_asset_group_by(id: nil, name: nil) raise 'Specify either id or name' if id.nil? && name.nil? if id delete_asset_group(id) else asset_group = fetch_asset_group_by_name(name) delete_asset_group(asset_group.site_idte_id) if asset_group end end |
#delete_assets(ids = [], threads = nil) ⇒ Object
Use Typhoeus for concurrency
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/domain/asset/api.rb', line 15 def delete_assets(ids = [], threads = nil) return if ids.empty? threads ||= ids.size**0.5 size = ids.size / threads batches = ids.each_slice(size) hydra = Typhoeus::Hydra.new(max_concurrency: threads) batches.each do |batch| batch.each do |id| request = create_delete_request(id) hydra.queue(request) end # Run the queued batch of requests hydra.run end # TODO: give the number of deleted assets puts 'All assets in the group have been successfully deleted.' end |
#delete_report(report_id) ⇒ Object
259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/domain/report/api.rb', line 259 def delete_report(report_id) raise 'Cannot delete report without id' if report_id.nil? report = fetch_report(report_id) raise "Report #{report_id} does not exist." if report.nil? puts 'Delete asset group with the same name as the report' delete_asset_group_by(name: report.name) puts "Delete assets from report #{report_id}" delete("/reports/#{report_id}/assets", '') puts "Delete report #{report_id}" delete('/reports', report_id) end |
#delete_report_by(id:, name:) ⇒ Object
248 249 250 251 252 253 254 255 256 257 |
# File 'lib/domain/report/api.rb', line 248 def delete_report_by(id:, name:) raise 'Specify either id or name' if id.nil? && name.nil? if id delete_report(id) else report = fetch_report_by_name(name) delete_report(report.id) end end |
#delete_scan_schedule(site_id:, schedule_id:) ⇒ Object
56 57 58 |
# File 'lib/domain/scan_schedule/api.rb', line 56 def delete_scan_schedule(site_id:, schedule_id:) delete("/sites/#{site_id}/scan_schedules", schedule_id) end |
#delete_site(site_id) ⇒ Object
294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/domain/site/api.rb', line 294 def delete_site(site_id) raise 'Cannot delete site without id' if site_id.nil? site = fetch_site(site_id) raise "Site #{site_id} does not exist." if site.nil? puts 'Delete asset group with the same name as the site' delete_asset_group_by(name: site.name) puts "Delete assets from site #{site_id}" delete("/sites/#{site_id}/assets", '') puts "Delete site #{site_id}" delete('/sites', site_id) end |
#delete_site_by(id:, name:) ⇒ Object
283 284 285 286 287 288 289 290 291 292 |
# File 'lib/domain/site/api.rb', line 283 def delete_site_by(id:, name:) raise 'Specify either id or name' if id.nil? && name.nil? if id delete_site(id) else site = fetch_site_by_name(name) delete_site(site.id) end end |
#delete_utr_report_schedules(report_id:) ⇒ Object
161 162 163 164 165 |
# File 'lib/domain/report/api.rb', line 161 def delete_utr_report_schedules(report_id:) fetch_report_scan_schedules(report_id:) do |scan_schedule| delete_scan_schedule(report_id:, schedule_id: scan_schedule.id) end end |
#delete_utr_reports ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/domain/report/api.rb', line 34 def delete_utr_reports puts 'Fetching UTR reports can take up to 5 minutes, patience ...' reports = fetch_utr_reports # TODO: add progress bar raise 'No UTR reports were found.' if reports.empty? # TODO: ask for confirmation puts "#{reports.count} reports will be deleted. Are you sure?" reports.each do |report| next unless report.utr? # double-check puts "Deleting report #{report.name}" delete_report(report.id) end end |
#delete_utr_site_schedules(site_id:) ⇒ Object
148 149 150 151 152 |
# File 'lib/domain/site/api.rb', line 148 def delete_utr_site_schedules(site_id:) fetch_site_scan_schedules(site_id:) do |scan_schedule| delete_scan_schedule(site_id:, schedule_id: scan_schedule.id) end end |
#delete_utr_sites ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/domain/site/api.rb', line 43 def delete_utr_sites puts 'Fetching UTR sites can take up to 5 minutes, patience ...' sites = fetch_utr_sites # TODO: add progress bar raise 'No UTR sites were found.' if sites.empty? # TODO: ask for confirmation puts "#{sites.count} sites will be deleted. Are you sure?" sites.each do |site| next unless site.utr? # double-check puts "Deleting site #{site.name}" delete_site(site.id) end end |
#delete_utr_vulnerabilities ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/domain/vulnerability/api.rb', line 36 def delete_utr_vulnerabilities puts 'Fetching UTR vulnerabilities can take up to 5 minutes, patience ...' vulnerabilities = fetch_utr_vulnerabilities # TODO: add progress bar raise 'No UTR vulnerabilities were found.' if vulnerabilities.empty? # TODO: ask for confirmation puts "#{vulnerabilities.count} vulnerabilities will be deleted. Are you sure?" vulnerabilities.each do |vulnerability| next unless vulnerability.utr? # double-check puts "Deleting vulnerability #{vulnerability.name}" delete_vulnerability(vulnerability.id) end end |
#delete_vulnerability(site_id) ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/domain/vulnerability/api.rb', line 246 def delete_vulnerability(site_id) raise 'Cannot delete vulnerability without id' if site_id.nil? vulnerability = fetch_vulnerability(site_id) raise "Vulnerability #{site_id} does not exist." if vulnerability.nil? puts 'Delete asset group with the same name as the vulnerability' delete_asset_group_by(name: vulnerability.name) puts "Delete assets from vulnerability #{site_id}" delete("/vulnerabilities/#{site_id}/assets", '') puts "Delete vulnerability #{site_id}" delete('/vulnerabilities', site_id) end |
#delete_vulnerability_by(site_idte_idte_idte_id:, name:) ⇒ Object
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/domain/vulnerability/api.rb', line 235 def delete_vulnerability_by(site_idte_idte_idte_id:, name:) raise 'Specify either id or name' if site_idte_id.nil? && name.nil? if site_idte_id delete_vulnerability(site_idte_id) else vulnerability = fetch_vulnerability_by_name(name) delete_vulnerability(vulnerability.site_idte_id) end end |
#engine_last_status_from(csv_file) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/domain/scan_engine/api.rb', line 39 def engine_last_status_from(csv_file) result = {} csv_data = CSV.read(csv_file, headers: true) sorted_data = csv_data.sort_by { |row| row['timestamp'] } sorted_data.each do |row| engine_id = row['engine_id'].to_i status = row['up'] == 'true' result[engine_id] = status end result end |
#fetch_all(endpoint, opts = {}, &block) ⇒ Object
Fetchs all resources
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/service/api/insightvm.rb', line 18 def fetch_all(endpoint, opts = {}, &block) params = { page: 0, size: 100, read_timeout: 5 }.merge opts loop do full_url = @base_url.dup full_url.path += endpoint full_url.query = URI.encode_www_form( params ) request = Net::HTTP::Get.new(full_url) request['Authorization'] = @base_auth @http.read_timeout = params[:read_timeout] response = @http.request(request) unless response.is_a?(Net::HTTPSuccess) puts "Error with code #{response.code}" break end json_response = JSON.parse(response.body) resources = json_response['resources'] break if resources.nil? resources.each(&block) # equivalent to resources.each {|resource| yield resource} # Check if this is the last page current_page = json_response['page']&.[]('number') || 0 pages = json_response['page']&.[]('totalPages') || 0 break if params[:page] >= pages break if current_page + 1 >= pages params[:page] += 1 end rescue Net::ReadTimeout opts[:read_timeout] = 2 * params[:read_timeout] || 30 raise 'Fail after multiple attempts' if opts[:read_timeout] > 300 puts "Increase the timeout to #{opts[:read_timeout]}" fetch_all(endpoint, opts, &block) end |
#fetch_all_targets(site_id) ⇒ Object
Returns included and excluded targets for site id
19 20 21 22 23 |
# File 'lib/domain/site_target/api.rb', line 19 def fetch_all_targets(site_id) [true, false].reduce([]) do |accu, included| accu + fetch_site_targets(site_id, included:) end end |
#fetch_asset_group(site_id) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/domain/asset_group/api.rb', line 96 def fetch_asset_group(site_id) result = nil fetch("/asset_groups/#{site_id}") do |data| result = AssetGroup.from_json(data) end result end |
#fetch_asset_group_assets(id, opts = { read_timeout: 200 }) ⇒ Object
15 16 17 18 19 20 21 22 |
# File 'lib/domain/asset_group/api.rb', line 15 def fetch_asset_group_assets(id, opts = { read_timeout: 200 }) asset_ids = [] endpoint = "/asset_groups/#{id}/assets" fetch_all(endpoint, opts) do |asset_id| asset_ids << asset_id end asset_ids end |
#fetch_asset_group_by_name(name) ⇒ Object
61 62 63 64 65 66 67 |
# File 'lib/domain/asset_group/api.rb', line 61 def fetch_asset_group_by_name(name) fetch_all('/asset_groups', name:) do |resource| asset_group = AssetGroup.from_json(resource) return asset_group if asset_group.name == name end nil end |
#fetch_asset_groups(opts = {}) ⇒ Object
7 8 9 10 11 12 13 |
# File 'lib/domain/asset_group/api.rb', line 7 def fetch_asset_groups(opts = {}) puts 'fetching asset groups' fetch_all('/asset_groups', opts) do |resource| puts resource yield AssetGroup.from_json(resource) end end |
#fetch_country_cyberark(country) ⇒ Object
TODO: use directly country code 2024-04-25 08:53
15 16 17 18 |
# File 'lib/domain/shared_credential/api.rb', line 15 def fetch_country_cyberark(country) credentials = all_shared_credentials credentials.find { |credential| credential.cyberark?(country) } end |
#fetch_country_scan_engine_pools(country) ⇒ Object
return scan engines that went from up to down given the previous status in a hash if the previous status is not known, assume it was up
TODO fetch pools from API
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/domain/scan_engine/api.rb', line 66 def fetch_country_scan_engine_pools(country) pools = [ { "id": 31, "name": 'DRC Core Network Scanners', "engines": [32, 145], "sites": [640, 258, 1222, 70, 904, 1097, 1225, 78, 79, 1040, 1107, 406, 920, 795, 412, 797, 1185, 1058, 1188, 997, 1192, 1193, 1194, 491, 749, 750, 942, 751, 752, 753, 562, 1144] }, { "id": 19, "name": 'Ghana Core Network Scanners', "engines": [16, 22], "sites": [1220, 133, 197, 198, 199, 1227, 1163, 463, 1039, 80, 145, 405, 1111, 984, 920, 414, 990, 802, 99, 803, 1190, 551, 999, 1127, 234, 1066, 1195, 492, 1196, 1197, 1198, 942, 1199, 560, 1072, 1010, 1014, 119, 760, 761, 1017, 762, 1082, 763, 764, 1023] }, { "id": 88, "name": 'Jersey Core Network Scanners', "engines": [147], "sites": [843, 844, 1164, 845, 1165, 846, 255] }, { "id": 59, "name": 'Mozambique Core Network Scanners', "engines": [113, 97], "sites": [132, 263, 1099, 1163, 721, 785, 1233, 786, 147, 787, 84, 788, 789, 790, 920, 409, 1249, 1251, 421, 1253, 1254, 103, 1255, 1260, 942, 1199, 819, 820, 950, 954] }, { "id": 41, "name": 'Zimbabwe Core Network Scanners', "engines": [40], "sites": [64, 837, 838, 839, 1095, 1287, 1288, 841, 1289, 842, 1290, 1291, 1163, 1292, 144, 1173, 1241, 990, 1002, 428, 110, 116, 120, 1082, 959] }, { "id": 18, "name": 'Malawi Core Network Scanners', "engines": [92], "sites": [128, 960, 261, 903, 136, 1032, 778, 779, 971, 1163, 780, 781, 1231, 464, 146, 83, 1171, 920, 1305, 1052, 1054, 990, 992, 1248, 609, 418, 1060, 869, 1253, 102, 1000, 1128, 1256, 1065, 1257, 1258, 1259, 1132, 942, 815, 816, 883, 1011, 887, 1082] }, { "id": 77, "name": 'Uganda Core Network Scanners', "engines": [134, 149, 69], "sites": [1025, 266, 459, 142, 1038, 720, 1296, 852, 470, 599, 1239, 152, 1112, 920, 857, 858, 731, 1307, 1308, 1053, 1309, 1310, 990, 1311, 1056, 1312, 296, 108, 300, 1069, 494, 942, 1199, 561, 821, 439, 824, 1016, 953, 826, 1018, 124, 828, 1020, 829] }, { "id": 29, "name": 'Mauritius Core Network Scanners', "engines": [93], "sites": [4, 5, 6, 262, 1159, 9, 137, 1163, 1101, 782, 783, 1295, 784, 1232, 1170, 1302, 1303, 920, 1305, 1306, 990, 419, 430, 1199, 817, 818, 1082] }, { "id": 127, "name": 'International (London, Beijing...) Core Network Scanners', "engines": [121], "sites": [912, 305, 854, 855, 444, 479] }, { "id": 52, "name": 'Angola Core Network Scanners', "engines": [95], "sites": [1163, 1298, 531, 1299, 22, 1174, 23, 1175, 408, 920, 1049, 1177, 26, 410, 1178, 27, 1179, 1180, 1311, 544, 942, 1199, 1077, 1082, 1223, 327, 328, 1096, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 990, 735, 736, 737, 738, 739, 740, 996, 741, 490, 634] }, { "id": 36, "name": 'Zambia Core Network Scanners', "engines": [79], "sites": [1280, 513, 1281, 1283, 902, 1163, 143, 1041, 920, 1050, 925, 547, 1059, 420, 1064, 427, 942, 945, 1076, 181, 63, 831, 832, 833, 834, 835, 1091, 836, 967, 201, 850, 1108, 853, 1240, 474, 986, 606, 994, 1001, 364, 109, 114, 243, 885, 886, 122, 1274, 1277, 1278, 1279] }, { "id": 72, "name": 'Lesotho Core Network Scanners', "engines": [70], "sites": [962, 260, 773, 1093, 774, 135, 775, 776, 777, 461, 1230, 655, 82, 607, 417, 101, 487, 811, 812, 1202, 1208, 1209, 1210, 1211, 127] }, { "id": 26, "name": 'Swaziland Core Network Scanners', "engines": [20], "sites": [129, 1094, 139, 1163, 460, 1294, 1237, 150, 920, 798, 990, 799, 1315, 1316, 998, 1318, 871, 1319, 424, 106, 876, 942, 1199, 112, 241, 754, 755, 947, 756, 884, 757, 758, 759, 1079, 1082] }, { "id": 26, "name": 'Eswatini Core Network Scanners', "engines": [20], "sites": [129, 1094, 139, 1163, 460, 1294, 1237, 150, 920, 798, 990, 799, 1315, 1316, 998, 1318, 871, 1319, 424, 106, 876, 942, 1199, 112, 241, 754, 755, 947, 756, 884, 757, 758, 759, 1079, 1082] }, { "id": 48, "name": 'Kenya Core Network Scanners', "engines": [106], "sites": [768, 769, 514, 770, 771, 772, 1092, 1221, 1029, 966, 1160, 1161, 651, 1229, 654, 81, 1105, 1043, 404, 920, 1243, 1244, 284, 1245, 1118, 1246, 287, 416, 288, 289, 545, 100, 806, 807, 873, 1129, 1004, 238, 1071, 564, 1141, 952, 505, 253, 126] }, { "id": 76, "name": 'Botswana Core Network Scanners', "engines": [75, 74], "sites": [1028, 1224, 972, 1100, 983, 920, 665, 1113, 411, 987, 1051, 1181, 991, 1183, 1184, 1187, 37, 1061, 1189, 742, 870, 39, 743, 744, 872, 745, 746, 43, 747, 875, 1003, 44, 748, 45, 237, 877, 944, 882, 1075] }, { "id": 73, "name": 'Ivory Coast Core Network Scanners', "engines": [146], "sites": [259, 804, 805, 1098, 1228, 141, 1200, 1201, 1203, 1172, 1204, 117, 1206, 407, 1207, 282, 765, 766, 415, 767] }, { "id": 84, "name": 'Nigeria Core Network Scanners', "engines": [82, 83], "sites": [800, 801, 130, 1157, 423, 264, 105, 1102, 942, 847, 1263, 848, 432, 1265, 946, 1235, 1267, 1268, 149, 86, 920, 1273, 1086] }, { "id": 12, "name": 'South Africa Core Network Scanners', "engines": [8, 14, 9, 13, 91, 11, 7, 6], "sites": [515, 516, 517, 520, 525, 526, 527, 528, 529, 530, 532, 533, 534, 535, 537, 539, 540, 541, 286, 542, 543, 548, 549, 550, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 48, 304, 1328, 1329, 1330, 307, 1331, 1332, 1333, 1334, 567, 1335, 568, 570, 571, 572, 573, 574, 576, 65, 577, 578, 66, 579, 583, 74, 587, 594, 597, 598, 1110, 87, 600, 601, 604, 349, 353, 610, 612, 613, 615, 360, 616, 617, 618, 620, 1135, 624, 1138, 1139, 1140, 629, 630, 632, 633, 642, 1156, 1162, 1163, 1166, 658, 662, 663, 664, 920, 666, 667, 668, 669, 413, 670, 671, 927, 673, 675, 676, 677, 678, 679, 169, 681, 682, 683, 684, 686, 942, 433, 689, 690, 436, 692, 440, 441, 186, 187, 699, 188, 1212, 1213, 189, 190, 703, 1215, 704, 1216, 1217, 195, 196, 205, 206, 465, 212, 213, 216, 728, 729, 218, 730, 219, 220, 222, 478, 990, 1247, 480, 228, 229, 230, 231, 488, 235, 242, 500, 245, 504, 506, 507, 509, 511] }, { "id": 123, "name": 'Namibia Core Network Scanners', "engines": [122], "sites": [1089, 131, 585, 586, 1037, 657, 1234, 148, 85, 791, 792, 793, 538, 989, 422, 1062, 104, 552, 1005, 1261, 1266, 948, 1012, 822, 1270, 823, 1271, 1272, 639] }, { "id": 39, "name": 'Tanzania Core Network Scanners', "engines": [38, 44], "sites": [384, 1024, 1026, 1282, 1284, 1285, 1286, 265, 395, 652, 462, 849, 851, 659, 596, 1238, 151, 985, 608, 808, 425, 809, 810, 107, 1067, 493, 1006, 113, 1009, 1015, 379, 1019, 1275, 380, 61, 125, 381, 382, 510, 1022, 383, 1087] } ] pools.find { |pool| pool[:name].downcase.include?(country.downcase) } end |
#fetch_discovery_scan_template_id(country) ⇒ Object
194 195 196 197 198 199 200 |
# File 'lib/domain/site/api.rb', line 194 def fetch_discovery_scan_template_id(country) if country == 'South Africa' settings[:za_discovery_template_id] else settings[:ar_discovery_template_id] end end |
#fetch_domain_cyberark(domains = []) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/domain/shared_credential/api.rb', line 39 def fetch_domain_cyberark(domains = []) credentials = Set.new domains.map(&:downcase) .each do |domain| if domain.include?('eswitch.sbicdirectory.com') credentials.add 'CyberArk South Africa SBICZA01' credentials.add 'CyberArk South Africa ESWITCH' elsif domain.include?('branches.sbicdirectory.com') credentials.add 'CyberArk South Africa SBICZA01' elsif domain.include?('scmbdicdirectory.com') credentials.add 'CyberArk South Africa SBICZA01' elsif domain.include?('za.sbicdirectory') credentials.add 'CyberArk South Africa SBICZA01' elsif domain.include?('stanlibdirectory.com') credentials.add 'CyberArk South Africa STANLIB' end end # puts "Credentials #{credentials}" return [] if credentials.empty? all_shared_credentials.select do |shared_credential| credentials.include?(shared_credential.name) end end |
#fetch_microsoft_product_lifecycle(spreadsheet, tabsheet_name: 'lifecycle_data') ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/domain/software/api.rb', line 10 def fetch_microsoft_product_lifecycle(spreadsheet, tabsheet_name: 'lifecycle_data') xlsx = Roo::Excelx.new(spreadsheet) sheet = xlsx.sheet(tabsheet_name) headers = xlsx.row(7) p headers models = [] total_rows = sheet.last_row - 7 = ProgressBar.create( title: "Processing #{spreadsheet}", total: total_rows, format: '%a %B %p%% %t' ) xlsx.each_row_streaming(offset: 7) do |row| values = row.map(&:value) attributes = Hash[headers.zip(values)] models << MicrosoftProductLifecycle.new(attributes) .increment end models end |
#fetch_report(report_id) ⇒ Object
12 13 14 15 16 17 |
# File 'lib/domain/report/api.rb', line 12 def fetch_report(report_id) fetch("/reports/#{report_id}") do |data| return Report.from_json(data) end nil end |
#fetch_report_by_name(name) ⇒ Object
19 20 21 22 23 24 |
# File 'lib/domain/report/api.rb', line 19 def fetch_report_by_name(name) fetch_reports do |report| return report if report.name.downcase == name.downcase end nil end |
#fetch_report_cyberark_credentials(report) ⇒ Object
298 299 300 301 302 303 304 305 306 307 |
# File 'lib/domain/report/api.rb', line 298 def fetch_report_cyberark_credentials(report) country_code = report.country_code if country_code != 'za' country = find_by_country_code report.country_code Array(fetch_country_cyberark(country.name)) else domains = fetch_report_domains(report) fetch_domain_cyberark(domains) end end |
#fetch_report_domains(report) ⇒ Object
309 310 311 |
# File 'lib/domain/report/api.rb', line 309 def fetch_report_domains(report) fetch_report_target_domains(report.id) end |
#fetch_report_shared_credentials(report_id:) ⇒ Object
291 292 293 294 295 296 |
# File 'lib/domain/report/api.rb', line 291 def fetch_report_shared_credentials(report_id:) report = fetch_report(report_id) raise "Report #{report_id} not found" if report.nil? fetch_report_cyberark_credentials(report) end |
#fetch_reports ⇒ Object
6 7 8 9 10 |
# File 'lib/domain/report/api.rb', line 6 def fetch_reports fetch_all('/reports') do |resource| yield Report.from_json(resource) end end |
#fetch_scan_engine_pools ⇒ Object
7 8 9 10 11 |
# File 'lib/domain/scan_engine/api.rb', line 7 def fetch_scan_engine_pools fetch_all('/scan_engine_pools') do |resource| yield ScanEnginePool.from_json(resource) end end |
#fetch_scan_engines ⇒ Object
13 14 15 16 17 |
# File 'lib/domain/scan_engine/api.rb', line 13 def fetch_scan_engines fetch_all('/scan_engines') do |resource| yield ScanEngine.from_json(resource) end end |
#fetch_shared_credential(id) ⇒ Object
83 84 85 86 87 |
# File 'lib/domain/shared_credential/api.rb', line 83 def fetch_shared_credential(id) fetch("/shared_credentials/#{id}") do |data| SharedCredential.from_json(data) end end |
#fetch_shared_credentials ⇒ Object
77 78 79 80 81 |
# File 'lib/domain/shared_credential/api.rb', line 77 def fetch_shared_credentials fetch_all('/shared_credentials') do |resource| yield SharedCredential.from_json(resource) end end |
#fetch_site(site_id) ⇒ Object
21 22 23 24 25 26 |
# File 'lib/domain/site/api.rb', line 21 def fetch_site(site_id) fetch("/sites/#{site_id}") do |data| return Site.from_json(data) end nil end |
#fetch_site_by_name(name) ⇒ Object
28 29 30 31 32 33 |
# File 'lib/domain/site/api.rb', line 28 def fetch_site_by_name(name) fetch_sites do |site| return site if site.name.downcase == name.downcase end nil end |
#fetch_site_cyberark_credentials(site) ⇒ Object
333 334 335 336 337 338 339 340 341 342 |
# File 'lib/domain/site/api.rb', line 333 def fetch_site_cyberark_credentials(site) country_code = site.country_code if country_code != 'za' country = find_by_country_code site.country_code Array(fetch_country_cyberark(country.name)) else domains = fetch_site_domains(site) fetch_domain_cyberark(domains) end end |
#fetch_site_domains(site) ⇒ Object
344 345 346 |
# File 'lib/domain/site/api.rb', line 344 def fetch_site_domains(site) fetch_site_target_domains(site.id) end |
#fetch_site_excluded_targets(site_id) ⇒ Object
14 15 16 |
# File 'lib/domain/site_target/api.rb', line 14 def fetch_site_excluded_targets(site_id) fetch_site_targets(site_id, included: false) end |
#fetch_site_included_targets(site_id) ⇒ Object
10 11 12 |
# File 'lib/domain/site_target/api.rb', line 10 def fetch_site_included_targets(site_id) fetch_site_targets(site_id, included: true) end |
#fetch_site_scan_schedules(site_id:) ⇒ Object
7 8 9 10 11 |
# File 'lib/domain/scan_schedule/api.rb', line 7 def fetch_site_scan_schedules(site_id:) fetch_all("/sites/#{site_id}/scan_schedules") do |resource| yield ScanSchedule.from_json(resource) end end |
#fetch_site_shared_credentials(site_id:) ⇒ Object
326 327 328 329 330 331 |
# File 'lib/domain/site/api.rb', line 326 def fetch_site_shared_credentials(site_id:) site = fetch_site(site_id) raise "Site #{site_id} not found" if site.nil? fetch_site_cyberark_credentials(site) end |
#fetch_site_target_domains(site_id) ⇒ Object
25 26 27 28 29 30 31 32 33 |
# File 'lib/domain/site_target/api.rb', line 25 def fetch_site_target_domains(site_id) targets = fetch_site_included_targets(site_id) hosts = targets.select { |target| target.type == 'host' } # remove the host part of the fqdns hosts.each_with_object(Set.new) do |host, accu| domain = remove_first_part(host.target) accu.add domain unless domain.nil? || domain.blank? end end |
#fetch_sites ⇒ Object
15 16 17 18 19 |
# File 'lib/domain/site/api.rb', line 15 def fetch_sites fetch_all('/sites') do |resource| yield Site.from_json(resource) end end |
#fetch_tag(site_id) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/domain/tag/api.rb', line 75 def fetch_tag(site_id) result = nil fetch("/tags/#{site_id}") do |data| result = Tag.from_json(data) end result end |
#fetch_tag_by_name(name) ⇒ Object
49 50 51 52 53 54 55 |
# File 'lib/domain/tag/api.rb', line 49 def fetch_tag_by_name(name) fetch_all('/tags', { name: }) do |resource| tag = Tag.from_json(resource) return tag if tag.name == name end nil end |
#fetch_tags ⇒ Object
6 7 8 9 10 |
# File 'lib/domain/tag/api.rb', line 6 def fetch_all('/tags') do |resource| yield Tag.from_json(resource) end end |
#fetch_utr_reports ⇒ Object
26 27 28 29 30 31 32 |
# File 'lib/domain/report/api.rb', line 26 def fetch_utr_reports reports = [] fetch_reports do |report| reports << report if report.utr? end reports end |
#fetch_utr_sites ⇒ Object
35 36 37 38 39 40 41 |
# File 'lib/domain/site/api.rb', line 35 def fetch_utr_sites sites = [] fetch_sites do |site| sites << site if site.utr? end sites end |
#fetch_utr_vulnerabilities ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/domain/vulnerability/api.rb', line 28 def fetch_utr_vulnerabilities vulnerabilities = [] fetch_vulnerabilities do |vulnerability| vulnerabilities << vulnerability if vulnerability.utr? end vulnerabilities end |
#fetch_vulnerabilities ⇒ Object
8 9 10 11 12 |
# File 'lib/domain/vulnerability/api.rb', line 8 def fetch_vulnerabilities fetch_all('/vulnerabilities') do |resource| yield Vulnerability.from_json(resource) end end |
#fetch_vulnerability(site_id) ⇒ Object
14 15 16 17 18 19 |
# File 'lib/domain/vulnerability/api.rb', line 14 def fetch_vulnerability(site_id) fetch("/vulnerabilities/#{site_id}") do |data| return Vulnerability.from_json(data) end nil end |
#fetch_vulnerability_by_name(name) ⇒ Object
21 22 23 24 25 26 |
# File 'lib/domain/vulnerability/api.rb', line 21 def fetch_vulnerability_by_name(name) fetch_vulnerabilities do |vulnerability| return vulnerability if vulnerability.name.downcase == name.downcase end nil end |
#find_by_country_code(cc) ⇒ Object
9 10 11 |
# File 'lib/domain/country/api.rb', line 9 def find_by_country_code(cc) App.db.countries.find { |country| country.code == cc } end |
#get_or_create_asset_group(name:, cached_asset_groups: {}) ⇒ Object
Given a asset_group name return asset_group in the cache if not found in cache,
update the cache
return the asset_group if the cache contains the name
create the custom asset_group with name
return asset_group
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/domain/asset_group/api.rb', line 39 def get_or_create_asset_group(name:, cached_asset_groups: {}) # Check if the asset_group name already exists in the cache from_cache = cached_asset_groups[name] return from_cache unless from_cache.nil? # If the asset_group is not found in the cache, # fetch asset_groups from the API from_api = fetch_asset_group_by_name(name) unless from_api.nil? cached_asset_groups[from_api.name] = from_api return from_api end # create the asset_group and update the cache id = create_asset_group(name:) return nil if id.nil? asset_group = fetch_asset_group(id) cached_asset_groups[name] = asset_group asset_group end |
#get_or_create_tag(name:, cached_tags: {}) ⇒ Object
Given a tag name return tag in the cache if not found in cache,
update the cache
return the tag if the cache contains the name
create the custom tag with name
return tag
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/domain/tag/api.rb', line 27 def get_or_create_tag(name:, cached_tags: {}) # Check if the tag name already exists in the cache from_cache = [name] return from_cache unless from_cache.nil? # If the tag is not found in the cache, # fetch tags from the API from_api = fetch_tag_by_name(name) unless from_api.nil? [from_api.name] = from_api return from_api end # create the tag and update the cache id = create_tag(name:) return nil if id.nil? tag = fetch_tag(id) [name] = tag tag end |
#list_shared_credential_utr_sites(credential, utr_sites) ⇒ Object
20 21 22 23 |
# File 'lib/domain/shared_credential/api.rb', line 20 def list_shared_credential_utr_sites(credential, utr_sites) site_ids = credential.sites utr_sites.select { |site| site_ids.include?(site.id) } end |
#remove_shared_credential_sites(credential, site_ids = []) ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/domain/shared_credential/api.rb', line 30 def remove_shared_credential_sites(credential, site_ids = []) to_be_removed = credential.sites & site_ids return if to_be_removed.empty? endpoint = "/shared_credentials/#{credential.id}" credential.sites -= to_be_removed put(endpoint, credential) end |
#remove_shared_credential_utr_sites(credential, utr_sites) ⇒ Object
25 26 27 28 |
# File 'lib/domain/shared_credential/api.rb', line 25 def remove_shared_credential_utr_sites(credential, utr_sites) site_ids = utr_sites.select(&:utr?).map(&:id) remove_shared_credential_sites(credential, site_ids) end |
#scan_engine_pools ⇒ Object
13 14 15 |
# File 'lib/domain/scan_engine_pool/api.rb', line 13 def scan_engine_pools @scan_engine_pools ||= _fetch_all_scan_engines_pools end |
#scan_engines_from_up_to_down(engines, previous_status) ⇒ Object
return scan engines that went from up to down given the previous status in a hash if the previous status is not known, assume it was up
31 32 33 34 35 36 37 |
# File 'lib/domain/scan_engine/api.rb', line 31 def scan_engines_from_up_to_down(engines, previous_status) downs = engines.select(&:down?).reject(&:rapid7_hosted?) downs.select do |site| status = previous_status[site.id] status.nil? ? true : status end end |
#scan_slot(utr_digits) ⇒ Object
return day of week and starts Time of scan ScanSchedule given the UTR digits
134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/domain/site/api.rb', line 134 def scan_slot(utr_digits) index = utr_digits % 25 day = index / 5 hour = index % 5 days = %w[monday tuesday friday saturday sunday] hours = [20, 22, 0, 2, 4] { day_of_week: days[day], start_time: hours[hour] } end |
#settings ⇒ Object
7 8 9 10 11 12 13 |
# File 'lib/domain/site/api.rb', line 7 def settings { ar_discovery_template_id: ENV['AR_DISCOVERY_TEMPLATE_ID'], za_discovery_template_id: ENV['ZA_DISCOVERY_TEMPLATE_ID'], za_deep_dive_scanners: ENV['ZA_DEEP_DIVE_SCANNERS'] } end |
#starts_discovery_scan(vulnerability_id:) ⇒ Object
275 276 277 278 279 280 281 |
# File 'lib/domain/site/api.rb', line 275 def starts_discovery_scan(site_id:) site = fetch_site(site_id) raise "Site ##{siteId} does not exist." if site.nil? params = {} post("/sites/#{site_id}/scans", params) end |
#toggle_utr_site_schedule(site:, enabled:) ⇒ Object
163 164 165 166 167 168 169 170 171 |
# File 'lib/domain/site/api.rb', line 163 def toggle_utr_site_schedule(site:, enabled:) site_id = site.id fetch_site_scan_schedules(site_id:) do |scan_schedule| next if scan_schedule.enabled == enabled scan_schedule.enabled = enabled update_scan_schedule(scan_schedule, site_id:) end end |
#update_report_owner(report, owner_id) ⇒ Object
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/domain/report/api.rb', line 51 def update_report_owner(report, owner_id) payload = report.to_hash.merge({ 'owner' => owner_id }) payload.delete('id') payload.delete_if { |_k, v| v.nil? } # frequency = payload['frequency'] # frequency.delete('nextRuntimes') # payload.merge { 'frequency' => frequency } endpoint = "/reports/#{report.id}" put(endpoint, payload) end |
#update_scan_schedule(scan_schedule, site_id:) ⇒ Object
60 61 62 63 64 |
# File 'lib/domain/scan_schedule/api.rb', line 60 def update_scan_schedule(scan_schedule, site_id:) id = scan_schedule.id endpoint = "/sites/#{site_id}/scan_schedules/#{id}" put(endpoint, scan_schedule) end |
#update_shared_credential_sites(credential:, site_ids: []) ⇒ Object
Add the site_id to the shared credential sites
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/domain/shared_credential/api.rb', line 65 def update_shared_credential_sites(credential:, site_ids: []) new_site_ids = site_ids - credential.sites if new_site_ids.empty? puts "#{credential.name} contains already sites #{site_ids}" return end credential.sites += new_site_ids endpoint = "/shared_credentials/#{credential.id}" put(endpoint, credential) end |
#update_xxx_report_owner(owner_id) ⇒ Object
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/domain/report/api.rb', line 62 def update_xxx_report_owner(owner_id) fetch_reports do |report| next unless report.name.starts_with?('xxx') next if report.owner == owner_id report.timezone = 'Africa/Harare' puts "Change #{report.name} owner from #{report.owner}" update_report_owner(report, owner_id) end end |
#upsert_site_shared_credentials(site_id:) ⇒ Object
252 253 254 255 256 257 258 |
# File 'lib/domain/site/api.rb', line 252 def upsert_site_shared_credentials(site_id:) site = fetch_site(site_id) raise "Site #{site_id} does not exist." if site.nil? raise "Site #{site.name} is not a UTR site" unless site.utr? add_shared_credentials(site) end |
#upsert_utr_report_schedule(report_id:) ⇒ Object
167 168 169 170 171 172 173 174 |
# File 'lib/domain/report/api.rb', line 167 def upsert_utr_report_schedule(report_id:) report = fetch_report(report_id) raise 'The report is not a valid UTR report' unless report.utr? delete_utr_report_schedules(report_id:) create_utr_report_schedule(report_id:) end |
#upsert_utr_site_schedule(site_id:) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/domain/site/api.rb', line 154 def upsert_utr_site_schedule(site_id:) site = fetch_site(site_id) raise 'The site is not a valid UTR site' unless site.utr? delete_utr_site_schedules(site_id:) create_utr_site_schedule(site_id:) end |