added support for cisa known exploits json feed

This commit is contained in:
Brendan McDevitt 2022-04-26 23:56:35 -05:00
parent fe415b0c13
commit db1ef2e01a
11 changed files with 126 additions and 1 deletions

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class CisaKnownExploitsController < ApplicationController
def index
@cisa_known_exploits = CisaKnownExploit.all
render json: @cisa_known_exploits.to_json
end
def show
@cisa_known_exploit = CisaKnownExploit.find(params[:cve_id])
render json: @cisa_known_exploit.to_json
end
end

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class CisaKnownExploit < ActiveRecord::Base
def self.find_by_id(id)
find_by(cve_id: id)
end
def self.from_year(year)
where('cve_id LIKE ?', "CVE-#{year}-%")
end
end

View file

@ -0,0 +1 @@
<h1>CisaKnownExploits#index</h1>

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
require '/data_importer/lib/importers/cisa_known_exploit_importer'
class CisaKnownExploitImporterWorker
include Faktory::Job
def perform(*args)
puts "Hello, I am #{jid} with args #{args}"
CisaKnownExploitImporter.new.import
end
end

View file

@ -60,3 +60,9 @@ jobs:
retries: 1
queue: default
priority: 5
- job: CisaKnownExploitImporterWorker
args: []
schedule: "@every 6h00m00s"
retries: 1
queue: default
priority: 5

View file

@ -0,0 +1,13 @@
class CreateCisaKnownExploits < ActiveRecord::Migration[7.0]
def change
create_table :cisa_known_exploits do |t|
t.string :title
t.string :catalog_version
t.date :date_released
t.index :date_released, unique: true
t.integer :count
t.jsonb :vulnerabilities
t.timestamps
end
end
end

View file

@ -10,10 +10,21 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_04_19_203353) do
ActiveRecord::Schema[7.0].define(version: 2022_04_27_043126) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "cisa_known_exploits", force: :cascade do |t|
t.string "title"
t.string "catalog_version"
t.date "date_released"
t.integer "count"
t.jsonb "vulnerabilities"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["date_released"], name: "index_cisa_known_exploits_on_date_released", unique: true
end
create_table "cnas", force: :cascade do |t|
t.string "short_name"
t.string "cna_id"

View file

@ -18,6 +18,7 @@ require '/data_importer/lib/importers/cna_importer'
require '/data_importer/lib/importers/github_advisory_importer'
require '/data_importer/lib/importers/github_user_importer'
require '/data_importer/lib/importers/gsd_importer.rb'
require '/data_importer/lib/importers/cisa_known_exploit_importer.rb'
def line_sep
puts '----------' * 12
@ -30,6 +31,7 @@ def perform
import_trickest_poc_cves
import_inthewild_cve_exploits
import_cvemon_cves
import_cisa_known_exploits
import_cpes
import_cnas
import_github_advisories
@ -71,6 +73,11 @@ def import_inthewild_cve_exploits
InthewildCveExploitImporter.new.import
end
def import_cisa_known_exploits
line_sep
CisaKnownExploitImporter.new.import
end
def import_trickest_poc_cves
line_sep
TrickestPocCveImporter.new.import

View file

@ -0,0 +1,35 @@
# frozen_string_literal: true
require '/data_importer/lib/json_helper'
class CisaKnownExploitImporter
attr_accessor :feed_url
EXPECTED_KEYS = %i[
title
catalog_version
date_released
count
vulnerabilities
].freeze
EMPTY_HASH = EXPECTED_KEYS.map { |k| [k, nil] }.to_h.freeze
def initialize
@feed_url = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json'
end
def get_and_transform_json
json = JsonHelper.read_json_from_url(feed_url)
json_transformed = JsonHelper.deep_transform_keys(json)
#json_transformed.map { |h| h.slice(*EXPECTED_KEYS).reverse_merge(EMPTY_HASH) }
end
def import
puts "Now starting import Cisa Known Exploits for #{feed_url}."
puts '----------' * 12
cisa_known_exploits = [ get_and_transform_json ]
CisaKnownExploit.upsert_all(cisa_known_exploits, unique_by: :date_released)
end
end

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'rest-client'
class JsonHelper
def self.deep_transform_keys(json_hash)
@ -17,4 +18,19 @@ class JsonHelper
s.gsub("`\u0000`", "null_byte")
end
def self.read_json_from_file(filename)
JSON.parse(File.read(filename), symbolize_names: true)
end
def self.read_json_from_url(url)
r = RestClient::Request.execute(
:method => :get,
:url => url
)
if r.code == 200
JSON.parse(r.body, symobilize_names: true)
else
puts "Http Code: #{r.code}"
end
end
end