Skip to content

Commit

Permalink
Adds CISA KEV managed enrichment table (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
rileydakota committed Jul 5, 2023
1 parent 3f8bb9a commit 27938d0
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
41 changes: 41 additions & 0 deletions data/managed/enrichment/cisa_kev/enrichment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
enrichment_type: dynamic
write_mode: overwrite

transform: |
.event.kind = "enrichment"
.event.category = ["vulnerability"]
.vulnerability.category = [del(.json.product), del(.json.vendorProject)]
.vulnerability.classification = "CVSS"
.vulnerability.description = del(.json.shortDescription)
.vulnerability.enumeration = "CVE"
.vulnerability.id = del(.json.cveID)
.cisa_kev.dateAdded = del(.json.dateAdded)
.cisa_kev.requiredAction = del(.json.requiredAction)
.cisa_kev.dueDate = del(.json.dueDate)
.cisa_kev.notes = del(.json.notes)
schema:
ecs_field_names:
- ecs.version
- event.kind
- event.category
- vulnerability.category
- vulnerability.classification
- vulnerability.description
- vulnerability.enumeration
- vulnerability.id

fields:
- name: cisa_kev
type:
type: struct
fields:
- name: dateAdded
type: string
- name: requiredAction
type: string
- name: dueDate
type: string
- name: notes
type: string
1 change: 1 addition & 0 deletions infra/lib/enrichment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const MANAGED_ENRICHMENT_PREFIX_MAP: Record<string, string> = {
"abusech_malwarebazaar": "abusech_malwarebazaar",
"abusech_threatfox": "abusech_threatfox",
"otx": "otx",
"cisa_kev": "cisa_kev"
}

export class EnrichmentTable extends Construct {
Expand Down
3 changes: 3 additions & 0 deletions infra/lib/log-puller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ export const PULLER_LOG_SOURCE_TYPES: string[] = [
"enrich_abusech_malwarebazaar",
"enrich_abusech_threatfox",
"enrich_otx",
"enrich_cisa_kev"
];
/** Some puller log sources don't need secrets. */
const NO_SECRET_LOG_SOURCES: string[] = [
"aws_inspector",
"enrich_abusech_urlhaus",
"enrich_abusech_malwarebazaar",
"enrich_abusech_threatfox",
"enrich_cisa_kev"
];

const LOG_SOURCE_RATES: Record<string, cdk.Duration> = {
Expand All @@ -52,6 +54,7 @@ const LOG_SOURCE_RATES: Record<string, cdk.Duration> = {
enrich_abusech_malwarebazaar: cdk.Duration.hours(1),
enrich_abusech_threatfox: cdk.Duration.hours(1),
enrich_otx: cdk.Duration.minutes(5),
enrich_cisa_kev: cdk.Duration.hours(1)
};

const LOG_SOURCE_PLACEHOLDER_MAP: Record<string, string> = {
Expand Down
58 changes: 58 additions & 0 deletions lib/rust/log_puller/src/pullers/cisa_kev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use anyhow::{anyhow, Context as AnyhowContext, Error, Result};
use async_trait::async_trait;
use chrono::{DateTime, FixedOffset};
use log::{debug, error, info};
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
io::{Read, Write},
};

use super::{PullLogs, PullLogsContext};

#[derive(Clone)]
pub struct CisaKevPuller;


const CISA_KEV_URL: &str = "https://www.cisa.gov/sites/default/files/csv/known_exploited_vulnerabilities.csv";
const CISA_KEV_HEADERS: [&str; 9] = [
"cveID",
"vendorProject",
"product",
"vulnerabilityName",
"dateAdded",
"shortDescription",
"requiredAction",
"dueDate",
"notes",
];

#[async_trait]
impl PullLogs for CisaKevPuller {
async fn pull_logs(
self,
client: reqwest::Client,
ctx: &PullLogsContext,
start_dt: DateTime<FixedOffset>,
end_dt: DateTime<FixedOffset>,
) -> Result<Vec<u8>> {
info!("Pulling CISA KEV...");
let resp = client.get(CISA_KEV_URL).send().await?.text().await?;

let mut json_bytes = vec![];

let mut csv_reader = csv::ReaderBuilder::new()
.comment(Some(b'#'))
.from_reader(resp.as_bytes());

//csv_reader.set_headers(csv::StringRecord::from(CISA_KEV_HEADERS.to_vec()));
for result in csv_reader.deserialize() {
let record: HashMap<String, String> = result?;
let bytes = serde_json::to_vec(&record)?;
json_bytes.write(bytes.as_slice())?;
json_bytes.write(b"\n")?;
}

return Ok(json_bytes);
}
}
6 changes: 6 additions & 0 deletions lib/rust/log_puller/src/pullers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod okta;
mod onepassword;
mod otx;
mod snyk;
mod cisa_kev;

#[derive(Clone)]
pub struct PullerCache {
Expand Down Expand Up @@ -205,6 +206,7 @@ pub enum LogSource {
OnePasswordPuller(onepassword::OnePasswordPuller),
Otx(otx::OtxPuller),
Snyk(snyk::SnykPuller),
CisaKevPuller(cisa_kev::CisaKevPuller),
AbuseChUrlhausPuller(abusech::AbuseChUrlhausPuller),
AbuseChMalwareBazaarPuller(abusech::AbuseChMalwareBazaarPuller),
AbuseChThreatfoxPuller(abusech::AbuseChThreatfoxPuller),
Expand Down Expand Up @@ -239,6 +241,9 @@ impl LogSource {
"abusech_threatfox" => Some(LogSource::AbuseChThreatfoxPuller(
abusech::AbuseChThreatfoxPuller {},
)),
"cisa_kev" => Some(LogSource::CisaKevPuller(
cisa_kev::CisaKevPuller {},
)),
_ => None,
}
}
Expand All @@ -256,6 +261,7 @@ impl LogSource {
LogSource::AbuseChUrlhausPuller(_) => "abusech_urlhaus",
LogSource::AbuseChMalwareBazaarPuller(_) => "abusech_malwarebazaar",
LogSource::AbuseChThreatfoxPuller(_) => "abusech_threatfox",
LogSource::CisaKevPuller(_) => "cisa_kev"
}
}
}

0 comments on commit 27938d0

Please sign in to comment.