Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
cn-kali-team committed Nov 23, 2023
1 parent f0be07d commit f059c7a
Show file tree
Hide file tree
Showing 19 changed files with 703 additions and 427 deletions.
2 changes: 1 addition & 1 deletion cpe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! The CPE Dictionary hosted and maintained at NIST may be used by nongovernmental organizations on a voluntary basis and is not subject to copyright in the United States. Attribution would, however, be appreciated by NIST.
//!
#![doc(html_root_url = "https://emo-car.github.io/nvd-rs/cpe")]
#![doc(html_root_url = "https://emo-crab.github.io/nvd-rs/cpe")]
// Package wfn provides a representation, bindings and matching of the Well-Formed CPE names as per
// https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7695.pdf and
// https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7696.pdf
Expand Down
5 changes: 4 additions & 1 deletion cve/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ serde = { version = "1", features = ["derive"] }
chrono = { version = "0.4", default-features = false, features = ["serde"] }
cpe = { path = "../cpe" }
cvss = { path = "../cvss" }
thiserror = "1.0"
thiserror = "1.0"

[dev-dependencies]
serde_json = "1.0"
24 changes: 24 additions & 0 deletions cve/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use crate::{date_format, DescriptionData};
use crate::impact::ImpactMetrics;

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all(deserialize = "camelCase"), deny_unknown_fields)]
pub struct CVE {
pub id: String,
pub source_identifier: String,
#[serde(with = "date_format")]
pub published_date: NaiveDateTime,
// 最后修改时间
#[serde(with = "date_format")]
pub last_modified_date: NaiveDateTime,
pub vuln_status: VulnStatus,
pub descriptions: Vec<DescriptionData>,
pub metrics: ImpactMetrics,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum VulnStatus {
Analyzed
}
70 changes: 62 additions & 8 deletions cve/src/impact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,66 @@ use serde::{Deserialize, Serialize};
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all(deserialize = "camelCase"), deny_unknown_fields)]
pub struct Impact {
// TODO: Implement V1?
// cvssV2 过期
#[serde(skip_serializing_if = "Option::is_none")]
pub base_metric_v2: Option<ImpactMetricV2>,
// cvssV3
pub base_metric_v3: Option<ImpactMetricV3>,
// TODO: Implement V4?
pub struct ImpactMetrics {
// TODO: Implement V1?
// cvssV2 过期
#[serde(skip_serializing_if = "Option::is_none")]
pub base_metric_v2: Option<ImpactMetricV2>,
// cvssV3
pub base_metric_v3: Option<ImpactMetricV3>,
// TODO: Implement V4?
}


#[cfg(test)]
mod tests {
use crate::impact::ImpactMetrics;

#[test]
fn cvss_v3() {
let j = r#"{
"baseMetricV3": {
"cvssV3": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"attackVector": "LOCAL",
"attackComplexity": "LOW",
"privilegesRequired": "HIGH",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH",
"baseScore": 6.7,
"baseSeverity": "MEDIUM"
},
"exploitabilityScore": 0.8,
"impactScore": 5.9
}}"#;
let i: ImpactMetrics = serde_json::from_str(&j).unwrap();
println!("{:?}", i);
}
#[test]
fn test_cvss_v3(){
let j2 = r#"{"baseMetricV3":{
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"availabilityImpact": "HIGH",
"baseScore": 7.5,
"baseSeverity": "HIGH"
},
"exploitabilityScore": 3.9,
"impactScore": 3.6
}}"#;
let i2: ImpactMetrics = serde_json::from_str(&j2).unwrap();
println!("{:?}", i2);
}
}
171 changes: 27 additions & 144 deletions cve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,158 +8,41 @@
//!
//! <https://nvd.nist.gov/vuln/vulnerability-detail-pages>
#![doc(html_root_url = "https://emo-car.github.io/nvd-rs/cve")]
pub mod configurations;
pub mod error;
pub mod impact;
#![doc(html_root_url = "https://emo-crab.github.io/nvd-rs/cve")]

use crate::configurations::Configurations;
use crate::impact::Impact;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
// https://nvd.nist.gov/general/News/JSON-1-1-Vulnerability-Feed-Release
// https://github.com/CVEProject/cve-schema
// https://raw.gitmirror.com/CVEProject/cve-schema/master/schema/v4.0/DRAFT-JSON-file-format-v4.md
// https://www.cve.org/Downloads
// https://github.com/CVEProject/cvelist

/// These objects can in turn contain more objects, arrays, strings and so on. The reason for this is so that each top level object type can contain self-identifying data such as CVE_Data_version. Most objects can in turn contains virtually any other object. In general, if you traverse into the nested tree of objects you should not encounter any chains that contains more than one instance of a given object container. Simply put you should not for example encounter a chain such as: root, CVE_affects, CVE_configuration, CVE_workaround, CVE_configuration. Please note that this rule may be subject to change as we get new container types and use cases.
#[derive(Debug, Deserialize, Serialize)]
#[allow(non_snake_case)]
#[serde(deny_unknown_fields)]
pub struct CVEContainer {
/// This string identifies what kind of data is held in this JSON file. This is mandatory and designed to prevent problems with attempting to detect what kind of file this is. Valid values for this string are CVE, CNA, CVEMENTOR.
pub CVE_data_type: String,
/// This string identifies what data format is used in this JSON file. This is mandatory and designed to prevent problems with attempting to detect what format of data is used. Valid values for this string are MITRE, it can also be user defined (e.g. for internal use).
pub CVE_data_format: String,
/// This identifies which version of the data format is in use. This is mandatory and designed to prevent problems with attempting to detect what format of data is used.
pub CVE_data_version: String,
/// numberOfCVEs
pub CVE_data_numberOfCVEs: String,
/// last update time for this entry
pub CVE_data_timestamp: String,
/// There are several special string values that can exist at the root level of the CVE ID JSON data, and one special one, the CVE_data_version, which can exist in the root or within any container.
pub CVE_Items: Vec<CVEItem>,
}
pub mod error;
pub mod v4;
pub mod api;
pub mod impact;

// 单个CVE信息
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all(deserialize = "camelCase"), deny_unknown_fields)]
#[allow(clippy::upper_case_acronyms)]
pub struct CVEItem {
// CVE 信息
pub cve: CVE,
// 影响
pub impact: Impact,
// 配置
pub configurations: Configurations,
// 公开时间
#[serde(with = "date_format")]
pub published_date: NaiveDateTime,
// 最后修改时间
#[serde(with = "date_format")]
pub last_modified_date: NaiveDateTime,
}
mod date_format {
use chrono::NaiveDateTime;
use serde::{self, Deserialize, Deserializer, Serializer};

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct CVE {
/// This string identifies what kind of data is held in this JSON file. This is mandatory and designed to prevent problems with attempting to detect what kind of file this is. Valid values for this string are CVE, CNA, CVEMENTOR.
pub data_type: String,
/// This string identifies what data format is used in this JSON file. This is mandatory and designed to prevent problems with attempting to detect what format of data is used. Valid values for this string are MITRE, it can also be user defined (e.g. for internal use).
pub data_format: String,
/// This identifies which version of the data format is in use. This is mandatory and designed to prevent problems with attempting to detect what format of data is used.
pub data_version: String,
/// CVE_data_meta
#[serde(rename(deserialize = "CVE_data_meta"))]
pub meta: Meta,
// 参考
pub references: References,
// 描述
pub description: Description,
// 问题类型 关联:CWE
#[serde(rename(deserialize = "problemtype"))]
pub problem_type: ProblemType,
}
/// These URLs are supplemental information relevant to the vulnerability, which include details that may not be present in the CVE Description. References are given resource tags such as third-party advisory, vendor advisory, technical paper, press/media, VDB entries, etc. These tags can help users quickly categorize the type of information each reference contains. References for a CVE are provided through the CVE list, the NVD does not have direct control over them. If you have concerns with existing CVE references or find other publicly available information that would be useful, then you can submit a request using the form at <https://cveform.mitre.org/> for the CVE Assignment Team to review.
///
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct References {
pub reference_data: Vec<Reference>,
}
const FORMAT: &str = "%Y-%m-%dT%H:%MZ";

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct Reference {
pub url: String,
pub name: String,
pub refsource: String,
pub tags: Vec<String>,
}
pub fn serialize<S>(date: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = date.to_string();
serializer.serialize_str(&s)
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct Description {
pub description_data: Vec<DescriptionData>,
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveDateTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
}
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct DescriptionData {
pub lang: String,
pub value: String,
}
/// This is metadata about the CVE ID such as the CVE ID, who requested it, who assigned it, when it was requested, when it was assigned, the current state (PUBLIC, REJECT, etc.) and so on.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct Meta {
/// CVE-YEAR-NNNNNNN - the CVE ID in the format listed in <http://cve.mitre.org/cve/identifiers/syntaxchange.html#new>
#[serde(rename(deserialize = "ID"))]
pub id: String,
/// Assigner ID - the assigner of the CVE (email address)
#[serde(rename(deserialize = "ASSIGNER"))]
pub assigner: String,
}
/// This is problem type information (e.g. CWE identifier).
///
/// Must contain: At least one entry, can be text, OWASP, CWE, please note that while only one is required you can use more than one (or indeed all three) as long as they are correct.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct ProblemType {
#[serde(rename = "problemtype_data")]
pub problem_type_data: Vec<ProblemTypeDataItem>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct ProblemTypeDataItem {
pub description: Vec<ProblemTypeDescription>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct ProblemTypeDescription {
pub lang: String,
pub value: String,
}

mod date_format {
use chrono::NaiveDateTime;
use serde::{self, Deserialize, Deserializer, Serializer};

const FORMAT: &str = "%Y-%m-%dT%H:%MZ";

pub fn serialize<S>(date: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = date.to_string();
serializer.serialize_str(&s)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveDateTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
}
}
pub lang: String,
pub value: String,
}
2 changes: 1 addition & 1 deletion cve/src/configurations.rs → cve/src/v4/configurations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl Configurations {
pub struct Node {
// 逻辑操作符
pub operator: Operator,
// 字节点
// 子节点
pub children: Vec<Node>,
// CPE 匹配列表
pub cpe_match: Vec<Match>,
Expand Down
Loading

0 comments on commit f059c7a

Please sign in to comment.