Skip to main content

ploit_malper/
models.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[derive(Debug, Clone, Serialize, Deserialize, Default)]
7pub struct ScanRecord {
8    pub target: String,
9    pub tool: String,
10    pub title: String,
11    pub severity: String,
12    pub port: Option<u16>,
13    pub cve: Option<String>,
14    pub service: Option<String>,
15    pub raw: Value,
16    #[serde(default, skip_serializing_if = "Vec::is_empty")]
17    pub affected_endpoints: Vec<String>,
18    /// Original finding description (never discarded, used for traceability).
19    #[serde(default, skip_serializing_if = "String::is_empty")]
20    pub detail: String,
21    /// Original finding reference link (never discarded).
22    #[serde(default, skip_serializing_if = "String::is_empty")]
23    pub reference: String,
24    /// Every CVE id discovered in title/detail/reference/raw (deduplicated).
25    #[serde(default, skip_serializing_if = "Vec::is_empty")]
26    pub cves: Vec<String>,
27    /// Normalized representation used for deduplication.
28    #[serde(default, skip_serializing_if = "String::is_empty")]
29    pub normalized_title: String,
30    /// Original raw finding titles merged into this record (traceability).
31    #[serde(default, skip_serializing_if = "Vec::is_empty")]
32    pub raw_findings: Vec<String>,
33    /// Number of scanner findings merged into this record (1 = unique).
34    #[serde(default)]
35    pub merged_count: usize,
36    #[serde(default, skip_serializing_if = "Option::is_none")]
37    pub nvd_description: Option<String>,
38    #[serde(default, skip_serializing_if = "Option::is_none")]
39    pub nvd_cvss_v3: Option<f32>,
40    #[serde(default, skip_serializing_if = "Option::is_none")]
41    pub nvd_cvss_v3_severity: Option<String>,
42    #[serde(default, skip_serializing_if = "Option::is_none")]
43    pub nvd_cvss_v2: Option<f32>,
44    #[serde(default, skip_serializing_if = "Option::is_none")]
45    pub nvd_published: Option<String>,
46    #[serde(default, skip_serializing_if = "Option::is_none")]
47    pub nvd_last_modified: Option<String>,
48    #[serde(default, skip_serializing_if = "Vec::is_empty")]
49    pub nvd_weaknesses: Vec<String>,
50    #[serde(default, skip_serializing_if = "Vec::is_empty")]
51    pub nvd_references: Vec<String>,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct DedupResult {
56    pub unique_count: usize,
57    pub removed_count: usize,
58    pub records: Vec<ScanRecord>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct DedupStats {
63    pub total: usize,
64    pub unique: usize,
65    pub removed: usize,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct ModuleSuggestion {
70    pub service_banner: String,
71    pub suggested_module: String,
72    pub confidence: String,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct PayloadRecipe {
77    pub platform: String,
78    pub architecture: String,
79    pub lhost: String,
80    pub lport: u16,
81    pub format: String,
82    pub output_path: String,
83    pub encoder: Option<String>,
84    pub iterations: Option<u32>,
85    pub command: String,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct NVDCVEInfo {
90    pub cve_id: String,
91    pub description: String,
92    pub cvss_v3_score: Option<f32>,
93    pub cvss_v3_severity: Option<String>,
94    pub cvss_v2_score: Option<f32>,
95    pub published: String,
96    pub last_modified: String,
97    pub weaknesses: Vec<String>,
98    pub references: Vec<String>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct MSFWorkspaceInfo {
103    pub name: String,
104    pub scope: String,
105    pub host_count: u64,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct MSFHostInfo {
110    pub address: String,
111    pub os_name: String,
112    pub os_flavor: String,
113    pub state: String,
114    pub notes_count: u64,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct MSFLoginResult {
119    pub success: bool,
120    pub token: String,
121    pub error: String,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct MSFWorkspacesResult {
126    pub workspaces: Vec<MSFWorkspaceInfo>,
127    pub error: String,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct MSFHostsResult {
132    pub hosts: Vec<MSFHostInfo>,
133    pub error: String,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct MSFHostCheckResult {
138    pub exists: bool,
139    pub error: String,
140}
141
142/// A vulnerability grouped across multiple affected endpoints.
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct FindingGroup {
145    pub title: String,
146    pub severity: String,
147    pub count: usize,
148    pub target: String,
149    pub affected_endpoints: Vec<String>,
150    pub cves: Vec<String>,
151    pub ports: Vec<String>,
152    pub tools: Vec<String>,
153    /// Intelligence family the records collapsed into (e.g. "Missing Security Headers").
154    pub family: String,
155    /// Specific sub-items for the family (e.g. the individual missing headers).
156    pub details: Vec<String>,
157    /// Original scanner evidence lines (raw findings) for traceability.
158    pub evidence: Vec<String>,
159}
160
161/// High-level executive summary of a scan.
162#[derive(Debug, Clone, Serialize, Deserialize, Default)]
163pub struct ScanSummary {
164    pub host: String,
165    pub server: Option<String>,
166    pub framework: Option<String>,
167    pub severity_counts: BTreeMap<String, usize>,
168    pub top_risks: Vec<String>,
169}
170
171/// Weighted overall risk score with a rendered bar and justification.
172#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct RiskScore {
174    pub score: u32,
175    pub bar: String,
176    pub reasons: Vec<String>,
177}
178
179/// Metasploit suggestions grouped by purpose.
180#[derive(Debug, Clone, Serialize, Deserialize, Default)]
181pub struct ModuleCategories {
182    pub enumeration: Vec<ModuleSuggestion>,
183    pub validation: Vec<ModuleSuggestion>,
184    pub exploitation: Vec<ModuleSuggestion>,
185    pub manual_notes: Vec<String>,
186}
187
188/// A single MITRE ATT&CK tactic with matching techniques and evidence.
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct MitreTactic {
191    pub tactic: String,
192    pub techniques: Vec<String>,
193    pub findings: Vec<String>,
194}
195
196/// Additional CVE intelligence beyond raw NVD data.
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct CVEExtraInfo {
199    pub epss: Option<f32>,
200    pub in_kev: bool,
201    pub public_exploit: bool,
202    pub metasploit_modules: Vec<String>,
203}
204
205/// An endpoint flagged by the scanner as a potential injection point.
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct InjectableEndpoint {
208    /// Affected host (e.g. the host URL or IP the scanner associated it with).
209    pub target: String,
210    /// The injectable endpoint itself (URL including query parameters).
211    pub endpoint: String,
212}
213
214/// Parsed VulnMalper scan: normalized findings plus injectable endpoints.
215#[derive(Debug, Clone, Serialize, Deserialize, Default)]
216pub struct ParsedScan {
217    pub records: Vec<ScanRecord>,
218    pub injectable_endpoints: Vec<InjectableEndpoint>,
219}
220
221/// A Metasploit module recommendation with exploit-intelligence metadata.
222#[derive(Debug, Clone, Serialize, Deserialize)]
223pub struct MSFModule {
224    pub name: String,
225    /// CVE this module maps to, if any.
226    pub cve: Option<String>,
227    /// Rank: excellent / great / good / normal / average / low / manual.
228    pub rank: String,
229    /// Disclosure date (YYYY-MM-DD) or unknown.
230    pub disclosure_date: String,
231    /// Supported platforms.
232    pub platforms: Vec<String>,
233    /// Required options the operator must fill in.
234    pub required_options: Vec<String>,
235}
236
237/// Why no Metasploit module is available for a given CVE.
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct MSFNoModuleReason {
240    pub cve: String,
241    pub reason: String,
242}
243
244/// Exploitability assessment derived from evidence in the scan.
245#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct ExploitabilityInfo {
247    /// Overall rating: Informational / Low / Moderate / High / Very High.
248    pub rating: String,
249    /// Numeric 0-100.
250    pub score: u32,
251    /// CVEs with known public exploits or KEV listing.
252    pub exploitable_cves: Vec<String>,
253    /// Injectable endpoint count.
254    pub injectable_count: usize,
255    /// Human-readable evidence trail.
256    pub reasons: Vec<String>,
257}