From 7ea3633a1184ba0a128434bc78a2aacb379899d4 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Tue, 1 Jun 2021 18:10:10 +0200 Subject: [PATCH 01/22] change endpoint and adapt component in mitre --- .../components/techniques/techniques.tsx | 40 ++++++++++++++++--- public/components/overview/mitre/mitre.tsx | 16 ++------ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 5373e76776..6d8ec2ebed 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -56,6 +56,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { hideAlerts: boolean, actionsOpen: string, filteredTechniques: boolean | [string] + mitreTechniques: [], isSearching: boolean } @@ -70,6 +71,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { hideAlerts: false, actionsOpen: "", filteredTechniques: false, + mitreTechniques: [], isSearching: false } this.onChangeFlyout.bind(this); @@ -77,6 +79,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { async componentDidMount(){ this._isMount = true; + this.getMitreTechniques() } shouldComponentUpdate(nextProps, nextState) { @@ -177,29 +180,56 @@ export const Techniques = withWindowSize(class Techniques extends Component { } } + async getMitreTechniques () { + const data = await WzRequest.apiReq('GET', '/mitre/techniques', {}).then(res => res).catch(err => mitreTechniques); + const result = (((data || {}).data || {}).data || {}).affected_items; + this.setState({ mitreTechniques: result }) + } + + buildObjTechniques(techniques){ + const techniquesIDs = [] + techniques.forEach(element => { + const mitreObj = this.state.mitreTechniques.filter(item => item.id === element) + if(mitreObj.length != 0){ + const mitreID = mitreObj[0].references.filter(item => item.source === "mitre-attack")[0].external_id + techniquesIDs.push(mitreID) + } + }); + return techniquesIDs + } + + findTechniqueName(techniqueID){ + let name = "" + this.state.mitreTechniques.map(item => { + if(item.references.filter(item => item.source === "mitre-attack")[0].external_id === techniqueID){ + name = item.name + } + }) + return name + } + renderFacet() { const { tacticsObject } = this.props; const { techniquesCount } = this.state; let tacticsToRender: Array = []; - const currentTechniques = Object.keys(tacticsObject).map(tacticsKey => ({tactic: tacticsKey, techniques: tacticsObject[tacticsKey]})) + const currentTechniques = Object.keys(tacticsObject).map(tacticsKey => ({tactic: tacticsKey, techniques: this.buildObjTechniques(tacticsObject[tacticsKey].techniques)})) .filter(tactic => this.props.selectedTactics[tactic.tactic]) .map(tactic => tactic.techniques) .flat() .filter((techniqueID, index, array) => array.indexOf(techniqueID) === index); - tacticsToRender = currentTechniques .filter(techniqueID => this.state.filteredTechniques ? this.state.filteredTechniques.includes(techniqueID) : techniqueID) .map(techniqueID => { return { id: techniqueID, - label: `${techniqueID} - ${mitreTechniques[techniqueID].name}`, + label: `${techniqueID} - ${this.findTechniqueName(techniqueID)}`, quantity: (techniquesCount.find(item => item.key === techniqueID) || {}).doc_count || 0 } }) .filter(technique => this.state.hideAlerts ? technique.quantity !== 0 : true); const tacticsToRenderOrdered = tacticsToRender.sort((a, b) => b.quantity - a.quantity).map( (item,idx) => { - const tooltipContent = `View details of ${mitreTechniques[item.id].name} (${item.id})`; + const tooltipContent = `View details of ${this.findTechniqueName(item.id)} (${item.id})`; const toolTipAnchorClass = "wz-display-inline-grid" + (this.state.hover=== item.id ? " wz-mitre-width" : " "); return( - {item.id} - {mitreTechniques[item.id].name} + {item.id} - {this.findTechniqueName(item.id)} diff --git a/public/components/overview/mitre/mitre.tsx b/public/components/overview/mitre/mitre.tsx index 71fdbbf884..9c932e7245 100644 --- a/public/components/overview/mitre/mitre.tsx +++ b/public/components/overview/mitre/mitre.tsx @@ -116,22 +116,12 @@ export class Mitre extends Component { async buildTacticsObject() { try { - const data = await WzRequest.apiReq('GET', '/mitre', { - params: { - select: "phase_name" - } - }); + const data = await WzRequest.apiReq('GET', '/mitre/tactics', {}); const result = (((data || {}).data || {}).data || {}).affected_items; const tacticsObject = {}; result && result.forEach(item => { - const {id, phase_name} = item; - phase_name.forEach( (tactic) => { - if(!tacticsObject[tactic]){ - tacticsObject[tactic] = []; - } - tacticsObject[tactic].push(id); - }) - }); + tacticsObject[item.references[0].external_id] = item; + }); this._isMount && this.setState({tacticsObject, isLoading: false}); } catch(err) { this.setState({ isLoading: false }); From d809f346e8e5cde9f0028b11d364c730a0839e7e Mon Sep 17 00:00:00 2001 From: eze9252 Date: Fri, 4 Jun 2021 11:44:21 +0200 Subject: [PATCH 02/22] fix flyout --- package.json | 2 +- .../flyout-technique/flyout-technique.tsx | 110 +++---- .../components/techniques/techniques.tsx | 41 ++- public/components/overview/mitre/lib/index.ts | 2 - .../overview/mitre/lib/mitre_techniques.ts | 268 ------------------ public/components/overview/mitre/mitre.tsx | 2 +- 6 files changed, 53 insertions(+), 372 deletions(-) delete mode 100644 public/components/overview/mitre/lib/mitre_techniques.ts diff --git a/package.json b/package.json index 4576383c4c..2c7f5df059 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wazuh", - "version": "4.3.0", + "version": "4.2.0", "revision": "4201-10", "code": "4201-10", "kibana": { diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index dfda83fe2e..10f1d9ed20 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -56,6 +56,7 @@ export class FlyoutTechnique extends Component { props!: { currentTechniqueData: any currentTechnique: string + tacticsObject: any } filterManager: FilterManager; @@ -118,9 +119,9 @@ export class FlyoutTechnique extends Component { try{ this.setState({loading: true, techniqueData: {}}); const { currentTechnique } = this.props; - const result = await WzRequest.apiReq('GET', '/mitre', { + const result = await WzRequest.apiReq('GET', '/mitre/techniques', { params: { - q: `id=${currentTechnique}` + q: `references.external_id=${currentTechnique}` } }); const rawData = (((result || {}).data || {}).data || {}).affected_items @@ -130,36 +131,38 @@ export class FlyoutTechnique extends Component { } } + findTacticName(tactics){ + const { tacticsObject } = this.props; + const tacticsObj = [] + tactics.forEach(element => { + const tactic = Object.keys(tacticsObject).map(tacticsKey => tacticsObject[tacticsKey]).find(obj => obj.id === element) + tacticsObj.push({ id:tactic.references[0].external_id, name: tactic.name}) + }); + return tacticsObj + } + formatTechniqueData (rawData) { - const { platform_name, phase_name} = rawData; - const { name, description, x_mitre_version: version, x_mitre_data_sources, external_references } = rawData.json; + const { tactics, name, mitre_version } = rawData; + const tacticsObj = this.findTacticName(tactics) - const replaced_external_references = []; - let index_replaced_external_references = 0; - let last_citation_string = ''; - const descriptionWithCitations = external_references.reduce((accum, reference) => { - return accum - .replace(new RegExp(`\\(Citation: ${reference.source_name}\\)`,'g'), (token) => { - if(last_citation_string !== token){ - index_replaced_external_references++; - replaced_external_references.push({...reference, index: index_replaced_external_references}); - last_citation_string = token; - } - return `[${String(index_replaced_external_references)}]`; - }) - }, description); - this.setState({techniqueData: { name, description: descriptionWithCitations, phase_name, platform_name, version, x_mitre_data_sources, external_references, replaced_external_references }, loading: false }) + this.setState({techniqueData: { name, mitre_version, tacticsObj }, loading: false }) } - getArrayFormatted(arrayText) { - try { - const stringText = arrayText.toString(); - const splitString = stringText.split(','); - const resultString = splitString.join(', '); - return resultString; - } catch (err) { - return arrayText; - } + getArrayFormatted(arrObj) { + try { + arrObj.map(obj => { + return ( + + {obj.name} + + ) + }) + } + catch{ + return "" + } } renderHeader() { @@ -184,6 +187,7 @@ export class FlyoutTechnique extends Component { renderBody() { const { currentTechnique } = this.props; const { techniqueData } = this.state; + console.log(techniqueData) const implicitFilters=[{ 'rule.mitre.id': currentTechnique}, this.clusterFilter ]; if(this.props.implicitFilters){ this.props.implicitFilters.forEach( item => @@ -212,52 +216,14 @@ export class FlyoutTechnique extends Component { }, { title: 'Tactic', - description: this.getArrayFormatted( - techniqueData.phase_name - ) - }, - { - title: 'Platform', - description: this.getArrayFormatted( - techniqueData.platform_name - ) - }, - { - title: 'Data sources', - description: this.getArrayFormatted( - techniqueData.x_mitre_data_sources - ) + description: "" }, { title: 'Version', - description: techniqueData.version - }, - { - title: 'Description', - description: formattedDescription - }, + description: techniqueData.mitre_version + } ]; - if(techniqueData && techniqueData.replaced_external_references && techniqueData.replaced_external_references.length > 0){ - data.push({ - title: 'References', - description: ( - - - {techniqueData.replaced_external_references.map((external_reference, external_reference_index) => ( -
- {external_reference.index}. - - {external_reference.source_name} - -
- ) - )} -
-
- ) - }) - } return ( -

- More info:{' '} - - {`MITRE ATT&CK - ${currentTechnique}`} - -

)} diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 6d8ec2ebed..441457780e 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -29,7 +29,7 @@ import { EuiLoadingSpinner, } from '@elastic/eui'; import { FlyoutTechnique } from './components/flyout-technique/'; -import { mitreTechniques, getElasticAlerts, IFilterParams } from '../../lib' +import { getElasticAlerts, IFilterParams } from '../../lib' import { ITactic } from '../../'; import { withWindowSize } from '../../../../../components/common/hocs/withWindowSize'; import { WzRequest } from '../../../../../react-services/wz-request'; @@ -187,25 +187,16 @@ export const Techniques = withWindowSize(class Techniques extends Component { } buildObjTechniques(techniques){ - const techniquesIDs = [] + const techniquesObj = [] techniques.forEach(element => { const mitreObj = this.state.mitreTechniques.filter(item => item.id === element) if(mitreObj.length != 0){ - const mitreID = mitreObj[0].references.filter(item => item.source === "mitre-attack")[0].external_id - techniquesIDs.push(mitreID) + const mitreTechniqueName = mitreObj[0].name + const mitreTechniqueID = mitreObj[0].references.filter(item => item.source === "mitre-attack")[0].external_id + mitreTechniqueID ? techniquesObj.push({ id : mitreTechniqueID, name: mitreTechniqueName}) : '' } }); - return techniquesIDs - } - - findTechniqueName(techniqueID){ - let name = "" - this.state.mitreTechniques.map(item => { - if(item.references.filter(item => item.source === "mitre-attack")[0].external_id === techniqueID){ - name = item.name - } - }) - return name + return techniquesObj } renderFacet() { @@ -218,18 +209,18 @@ export const Techniques = withWindowSize(class Techniques extends Component { .flat() .filter((techniqueID, index, array) => array.indexOf(techniqueID) === index); tacticsToRender = currentTechniques - .filter(techniqueID => this.state.filteredTechniques ? this.state.filteredTechniques.includes(techniqueID) : techniqueID) + .filter(techniqueID => this.state.filteredTechniques ? this.state.filteredTechniques.includes(techniqueID.id) : techniqueID.id) .map(techniqueID => { return { - id: techniqueID, - label: `${techniqueID} - ${this.findTechniqueName(techniqueID)}`, - quantity: (techniquesCount.find(item => item.key === techniqueID) || {}).doc_count || 0 + id: techniqueID.id, + label: `${techniqueID.id} - ${techniqueID.name}`, + quantity: (techniquesCount.find(item => item.key === techniqueID.id) || {}).doc_count || 0 } }) .filter(technique => this.state.hideAlerts ? technique.quantity !== 0 : true); const tacticsToRenderOrdered = tacticsToRender.sort((a, b) => b.quantity - a.quantity).map( (item,idx) => { - const tooltipContent = `View details of ${this.findTechniqueName(item.id)} (${item.id})`; + const tooltipContent = `View details of ${item.label} (${item.id})`; const toolTipAnchorClass = "wz-display-inline-grid" + (this.state.hover=== item.id ? " wz-mitre-width" : " "); return( - {item.id} - {this.findTechniqueName(item.id)} + {item.label} @@ -344,14 +335,13 @@ export const Techniques = withWindowSize(class Techniques extends Component { try{ if(searchValue){ this._isMount && this.setState({isSearching: true}); - const response = await WzRequest.apiReq('GET', '/mitre', { + const response = await WzRequest.apiReq('GET', '/mitre/techniques', { params: { - select: "id", search: searchValue, limit: 500 } }); - const filteredTechniques = ((((response || {}).data || {}).data).affected_items || []).map(item => item.id); + const filteredTechniques = ((((response || {}).data || {}).data).affected_items || []).map(item => item.references.filter(reference => reference.source === "mitre-attack")[0].external_id); this._isMount && this.setState({ filteredTechniques, isSearching: false }); }else{ this._isMount && this.setState({ filteredTechniques: false, isSearching: false }); @@ -435,7 +425,8 @@ export const Techniques = withWindowSize(class Techniques extends Component { openDiscover={(e,itemId) => this.openDiscover(e,itemId)} onChangeFlyout={this.onChangeFlyout} currentTechniqueData={this.state.currentTechniqueData} - currentTechnique={currentTechnique} /> + currentTechnique={currentTechnique} + tacticsObject={this.props.tacticsObject} /> } diff --git a/public/components/overview/mitre/lib/index.ts b/public/components/overview/mitre/lib/index.ts index 64e0901655..b14fdde744 100644 --- a/public/components/overview/mitre/lib/index.ts +++ b/public/components/overview/mitre/lib/index.ts @@ -11,5 +11,3 @@ */ export { IFilterParams, getElasticAlerts, getIndexPattern } from './elastic-helpers'; - -export { mitreTechniques } from './mitre_techniques'; \ No newline at end of file diff --git a/public/components/overview/mitre/lib/mitre_techniques.ts b/public/components/overview/mitre/lib/mitre_techniques.ts deleted file mode 100644 index 8b64d60aad..0000000000 --- a/public/components/overview/mitre/lib/mitre_techniques.ts +++ /dev/null @@ -1,268 +0,0 @@ -export const mitreTechniques = { - T1001: { name: "Data Obfuscation" }, - T1002: { name: "Data Compressed" }, - T1003: { name: "Credential Dumping" }, - T1004: { name: "Winlogon Helper DLL" }, - T1005: { name: "Data from Local System" }, - T1006: { name: "File System Logical Offsets" }, - T1007: { name: "System Service Discovery" }, - T1008: { name: "Fallback Channels" }, - T1009: { name: "Binary Padding" }, - T1010: { name: "Application Window Discovery" }, - T1011: { name: "Exfiltration Over Other Network Medium" }, - T1012: { name: "Query Registry" }, - T1013: { name: "Port Monitors" }, - T1014: { name: "Rootkit" }, - T1015: { name: "Accessibility Features" }, - T1016: { name: "System Network Configuration Discovery" }, - T1017: { name: "Application Deployment Software" }, - T1018: { name: "Remote System Discovery" }, - T1019: { name: "System Firmware" }, - T1020: { name: "Automated Exfiltration" }, - T1021: { name: "Remote Services" }, - T1022: { name: "Data Encrypted" }, - T1023: { name: "Shortcut Modification" }, - T1024: { name: "Custom Cryptographic Protocol" }, - T1025: { name: "Data from Removable Media" }, - T1026: { name: "Multiband Communication" }, - T1027: { name: "Obfuscated Files or Information" }, - T1028: { name: "Windows Remote Management" }, - T1029: { name: "Scheduled Transfer" }, - T1030: { name: "Data Transfer Size Limits" }, - T1031: { name: "Modify Existing Service" }, - T1032: { name: "Standard Cryptographic Protocol" }, - T1033: { name: "System Owner/User Discovery" }, - T1034: { name: "Path Interception" }, - T1035: { name: "Service Execution" }, - T1036: { name: "Masquerading" }, - T1037: { name: "Logon Scripts" }, - T1038: { name: "DLL Search Order Hijacking" }, - T1039: { name: "Data from Network Shared Drive" }, - T1040: { name: "Network Sniffing" }, - T1041: { name: "Exfiltration Over Command and Control Channel" }, - T1042: { name: "Change Default File Association" }, - T1043: { name: "Commonly Used Port" }, - T1044: { name: "File System Permissions Weakness" }, - T1045: { name: "Software Packing" }, - T1046: { name: "Network Service Scanning" }, - T1047: { name: "Windows Management Instrumentation" }, - T1048: { name: "Exfiltration Over Alternative Protocol" }, - T1049: { name: "System Network Connections Discovery" }, - T1050: { name: "New Service" }, - T1051: { name: "Shared Webroot" }, - T1052: { name: "Exfiltration Over Physical Medium" }, - T1053: { name: "Scheduled Task" }, - T1054: { name: "Indicator Blocking" }, - T1055: { name: "Process Injection" }, - T1056: { name: "Input Capture" }, - T1057: { name: "Process Discovery" }, - T1058: { name: "Service Registry Permissions Weakness" }, - T1059: { name: "Command-Line Interface" }, - T1060: { name: "Registry Run Keys / Startup Folder" }, - T1061: { name: "Graphical User Interface" }, - T1062: { name: "Hypervisor" }, - T1063: { name: "Security Software Discovery" }, - T1064: { name: "Scripting" }, - T1065: { name: "Uncommonly Used Port" }, - T1066: { name: "Indicator Removal from Tools" }, - T1067: { name: "Bootkit" }, - T1068: { name: "Exploitation for Privilege Escalation" }, - T1069: { name: "Permission Groups Discovery" }, - T1070: { name: "Indicator Removal on Host" }, - T1071: { name: "Standard Application Layer Protocol" }, - T1072: { name: "Third-party Software" }, - T1073: { name: "DLL Side-Loading" }, - T1074: { name: "Data Staged" }, - T1075: { name: "Pass the Hash" }, - T1076: { name: "Remote Desktop Protocol" }, - T1077: { name: "Windows Admin Shares" }, - T1078: { name: "Valid Accounts" }, - T1079: { name: "Multilayer Encryption" }, - T1080: { name: "Taint Shared Content" }, - T1081: { name: "Credentials in Files" }, - T1082: { name: "System Information Discovery" }, - T1083: { name: "File and Directory Discovery" }, - T1084: { name: "Windows Management Instrumentation Event Subscription" }, - T1085: { name: "Rundll32" }, - T1086: { name: "PowerShell" }, - T1087: { name: "Account Discovery" }, - T1088: { name: "Bypass User Account Control" }, - T1089: { name: "Disabling Security Tools" }, - T1090: { name: "Connection Proxy" }, - T1091: { name: "Replication Through Removable Media" }, - T1092: { name: "Communication Through Removable Media" }, - T1093: { name: "Process Hollowing" }, - T1094: { name: "Custom Command and Control Protocol" }, - T1095: { name: "Standard Non-Application Layer Protocol" }, - T1096: { name: "NTFS File Attributes" }, - T1097: { name: "Pass the Ticket" }, - T1098: { name: "Account Manipulation" }, - T1099: { name: "Timestomp" }, - T1100: { name: "Web Shell" }, - T1101: { name: "Security Support Provider" }, - T1102: { name: "Web Service" }, - T1103: { name: "AppInit DLLs" }, - T1104: { name: "Multi-Stage Channels" }, - T1105: { name: "Remote File Copy" }, - T1106: { name: "Execution through API" }, - T1107: { name: "File Deletion" }, - T1108: { name: "Redundant Access" }, - T1109: { name: "Component Firmware" }, - T1110: { name: "Brute Force" }, - T1111: { name: "Two-Factor Authentication Interception" }, - T1112: { name: "Modify Registry" }, - T1113: { name: "Screen Capture" }, - T1114: { name: "Email Collection" }, - T1115: { name: "Clipboard Data" }, - T1116: { name: "Code Signing" }, - T1117: { name: "Regsvr32" }, - T1118: { name: "InstallUtil" }, - T1119: { name: "Automated Collection" }, - T1120: { name: "Peripheral Device Discovery" }, - T1121: { name: "Regsvcs/Regasm" }, - T1122: { name: "Component Object Model Hijacking" }, - T1123: { name: "Audio Capture" }, - T1124: { name: "System Time Discovery" }, - T1125: { name: "Video Capture" }, - T1126: { name: "Network Share Connection Removal" }, - T1127: { name: "Trusted Developer Utilities" }, - T1128: { name: "Netsh Helper DLL" }, - T1129: { name: "Execution through Module Load" }, - T1130: { name: "Install Root Certificate" }, - T1131: { name: "Authentication Package" }, - T1132: { name: "Data Encoding" }, - T1133: { name: "External Remote Services" }, - T1134: { name: "Access Token Manipulation" }, - T1135: { name: "Network Share Discovery" }, - T1136: { name: "Create Account" }, - T1137: { name: "Office Application Startup" }, - T1138: { name: "Application Shimming" }, - T1139: { name: "Bash History" }, - T1140: { name: "Deobfuscate/Decode Files or Information" }, - T1141: { name: "Input Prompt" }, - T1142: { name: "Keychain" }, - T1143: { name: "Hidden Window" }, - T1144: { name: "Gatekeeper Bypass" }, - T1145: { name: "Private Keys" }, - T1146: { name: "Clear Command History" }, - T1147: { name: "Hidden Users" }, - T1148: { name: "HISTCONTROL" }, - T1149: { name: "LC_MAIN Hijacking" }, - T1150: { name: "Plist Modification" }, - T1151: { name: "Space after Filename" }, - T1152: { name: "Launchctl" }, - T1153: { name: "Source" }, - T1154: { name: "Trap" }, - T1155: { name: "AppleScript" }, - T1156: { name: ".bash_profile and .bashrc" }, - T1157: { name: "Dylib Hijacking" }, - T1158: { name: "Hidden Files and Directories" }, - T1159: { name: "Launch Agent" }, - T1160: { name: "Launch Daemon" }, - T1161: { name: "LC_LOAD_DYLIB Addition" }, - T1162: { name: "Login Item" }, - T1163: { name: "Rc.common" }, - T1164: { name: "Re-opened Applications" }, - T1165: { name: "Startup Items" }, - T1166: { name: "Setuid and Setgid" }, - T1167: { name: "Securityd Memory" }, - T1168: { name: "Local Job Scheduling" }, - T1169: { name: "Sudo" }, - T1170: { name: "Mshta" }, - T1171: { name: "LLMNR/NBT-NS Poisoning and Relay" }, - T1172: { name: "Domain Fronting" }, - T1173: { name: "Dynamic Data Exchange" }, - T1174: { name: "Password Filter DLL" }, - T1175: { name: "Component Object Model and Distributed COM" }, - T1176: { name: "Browser Extensions" }, - T1177: { name: "LSASS Driver" }, - T1178: { name: "SID-History Injection" }, - T1179: { name: "Hooking" }, - T1180: { name: "Screensaver" }, - T1181: { name: "Extra Window Memory Injection" }, - T1182: { name: "AppCert DLLs" }, - T1183: { name: "Image File Execution Options Injection" }, - T1184: { name: "SSH Hijacking" }, - T1185: { name: "Man in the Browser" }, - T1186: { name: "Process Doppelgänging" }, - T1187: { name: "Forced Authentication" }, - T1188: { name: "Multi-hop Proxy" }, - T1189: { name: "Drive-by Compromise" }, - T1190: { name: "Exploit Public-Facing Application" }, - T1191: { name: "CMSTP" }, - T1192: { name: "Spearphishing Link" }, - T1193: { name: "Spearphishing Attachment" }, - T1194: { name: "Spearphishing via Service" }, - T1195: { name: "Supply Chain Compromise" }, - T1196: { name: "Control Panel Items" }, - T1197: { name: "BITS Jobs" }, - T1198: { name: "SIP and Trust Provider Hijacking" }, - T1199: { name: "Trusted Relationship" }, - T1200: { name: "Hardware Additions" }, - T1201: { name: "Password Policy Discovery" }, - T1202: { name: "Indirect Command Execution" }, - T1203: { name: "Exploitation for Client Execution" }, - T1204: { name: "User Execution" }, - T1205: { name: "Port Knocking" }, - T1206: { name: "Sudo Caching" }, - T1207: { name: "DCShadow" }, - T1208: { name: "Kerberoasting" }, - T1209: { name: "Time Providers" }, - T1210: { name: "Exploitation of Remote Services" }, - T1211: { name: "Exploitation for Defense Evasion" }, - T1212: { name: "Exploitation for Credential Access" }, - T1213: { name: "Data from Information Repositories" }, - T1214: { name: "Credentials in Registry" }, - T1215: { name: "Kernel Modules and Extensions" }, - T1216: { name: "Signed Script Proxy Execution" }, - T1217: { name: "Browser Bookmark Discovery" }, - T1218: { name: "Signed Binary Proxy Execution" }, - T1219: { name: "Remote Access Tools" }, - T1220: { name: "XSL Script Processing" }, - T1221: { name: "Template Injection" }, - T1222: { name: "File and Directory Permissions Modification" }, - T1223: { name: "Compiled HTML File" }, - T1480: { name: "Execution Guardrails" }, - T1482: { name: "Domain Trust Discovery" }, - T1483: { name: "Domain Generation Algorithms" }, - T1484: { name: "Group Policy Modification" }, - T1485: { name: "Data Destruction" }, - T1486: { name: "Data Encrypted for Impact" }, - T1487: { name: "Disk Structure Wipe" }, - T1488: { name: "Disk Content Wipe" }, - T1489: { name: "Service Stop" }, - T1490: { name: "Inhibit System Recovery" }, - T1491: { name: "Defacement" }, - T1492: { name: "Stored Data Manipulation" }, - T1493: { name: "Transmitted Data Manipulation" }, - T1494: { name: "Runtime Data Manipulation" }, - T1495: { name: "Firmware Corruption" }, - T1496: { name: "Resource Hijacking" }, - T1497: { name: "Virtualization/Sandbox Evasion" }, - T1498: { name: "Network Denial of Service" }, - T1499: { name: "Endpoint Denial of Service" }, - T1500: { name: "Compile After Delivery" }, - T1501: { name: "Systemd Service" }, - T1502: { name: "Parent PID Spoofing" }, - T1503: { name: "Credentials from Web Browsers" }, - T1504: { name: "PowerShell Profile" }, - T1505: { name: "Server Software Component" }, - T1506: { name: "Web Session Cookie" }, - T1514: { name: "Elevated Execution with Prompt" }, - T1518: { name: "Software Discovery" }, - T1519: { name: "Emond" }, - T1522: { name: "Cloud Instance Metadata API" }, - T1525: { name: "Implant Container Image" }, - T1526: { name: "Cloud Service Discovery" }, - T1527: { name: "Application Access Token" }, - T1528: { name: "Steal Application Access Token" }, - T1529: { name: "System Shutdown/Reboot" }, - T1530: { name: "Data from Cloud Storage Object" }, - T1531: { name: "Account Access Removal" }, - T1534: { name: "Internal Spearphishing" }, - T1535: { name: "Unused/Unsupported Cloud Regions" }, - T1536: { name: "Revert Cloud Instance" }, - T1537: { name: "Transfer Data to Cloud Account" }, - T1538: { name: "Cloud Service Dashboard" }, - T1539: { name: "Steal Web Session Cookie" } -} \ No newline at end of file diff --git a/public/components/overview/mitre/mitre.tsx b/public/components/overview/mitre/mitre.tsx index 9c932e7245..e9847d1463 100644 --- a/public/components/overview/mitre/mitre.tsx +++ b/public/components/overview/mitre/mitre.tsx @@ -120,7 +120,7 @@ export class Mitre extends Component { const result = (((data || {}).data || {}).data || {}).affected_items; const tacticsObject = {}; result && result.forEach(item => { - tacticsObject[item.references[0].external_id] = item; + tacticsObject[item.name] = item; }); this._isMount && this.setState({tacticsObject, isLoading: false}); } catch(err) { From 75774a156eacdfeaff3cd464e938f6b26693438a Mon Sep 17 00:00:00 2001 From: eze9252 Date: Mon, 7 Jun 2021 13:12:26 +0200 Subject: [PATCH 03/22] add redirect to intelligence --- .../flyout-technique/flyout-technique.tsx | 29 +++++++++++++++---- .../components/techniques/techniques.tsx | 8 +++++ .../module_mitre_intelligence.tsx | 13 ++++++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index 10f1d9ed20..b78f07144d 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -183,6 +183,18 @@ export class FlyoutTechnique extends Component { ) } + + renderTactics(tactics){ + tactics.map(tactic => { + return ( + + {tactic.id} + + ) + }) + } renderBody() { const { currentTechnique } = this.props; @@ -208,15 +220,23 @@ export class FlyoutTechnique extends Component { title: 'ID', description: ( - + content={"Open " + currentTechnique + " details in Intelligence section"}> + {this.props.openIntelligence(e,'techniques',currentTechnique);e.stopPropagation()}}> {currentTechnique} ) }, { - title: 'Tactic', - description: "" + title: 'Tactics', + description: techniqueData.tacticsObj ? techniqueData.tacticsObj.map(tactic => { return ( <> + {this.props.openIntelligence(e,'tactics',tactic.id);e.stopPropagation()}}> + {tactic.name} + + +
+ )}) : '' }, { title: 'Version', @@ -245,7 +265,6 @@ export class FlyoutTechnique extends Component { )) || (
-
)} diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 441457780e..2afed8aed1 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -37,6 +37,7 @@ import {WAZUH_ALERTS_PATTERN} from '../../../../../../common/constants'; import { AppState } from '../../../../../react-services/app-state'; import { WzFieldSearchDelay } from '../../../../common/search' import { getDataPlugin } from '../../../../../kibana-services'; +import { ModuleMitreIntelligence } from '../../../mitre_attack_intelligence' export const Techniques = withWindowSize(class Techniques extends Component { _isMount = false; @@ -302,6 +303,12 @@ export const Techniques = withWindowSize(class Techniques extends Component { this.props.onSelectedTabChanged('dashboard'); } + openIntelligence(e,redirectTo,itemId){ + sessionStorage.setItem("tabRedirect", redirectTo); + sessionStorage.setItem("idToRedirect", itemId); + this.props.onSelectedTabChanged('intelligence'); + } + /** * Adds a new filter with format { "filter_key" : "filter_value" }, e.g. {"agent.id": "001"} * @param filter @@ -423,6 +430,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { this.openDashboard(e,itemId)} openDiscover={(e,itemId) => this.openDiscover(e,itemId)} + openIntelligence={(e,redirectTo,itemId) => this.openIntelligence(e,redirectTo,itemId)} onChangeFlyout={this.onChangeFlyout} currentTechniqueData={this.state.currentTechniqueData} currentTechnique={currentTechnique} diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx index f847bebc60..e2ca3a979f 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx @@ -11,7 +11,7 @@ * Find more information about this on the LICENSE file. */ -import React, { useCallback, useState, useRef } from 'react'; +import React, { useCallback, useState, useRef, useEffect } from 'react'; import { EuiFlexGroup, EuiFlexItem, @@ -55,6 +55,17 @@ export const ModuleMitreIntelligence = () => { } , [searchTermAllResources]); + useEffect(() => { + const redirectTab = sessionStorage.getItem("tabRedirect") + const idToRedirect = sessionStorage.getItem("idToRedirect") + if(redirectTab){ + setResourceFilters([{field: 'search', value: idToRedirect}]); + setSelectedResource(redirectTab); + sessionStorage.removeItem("tabRedirect") + sessionStorage.removeItem("idToRedirect") + } + },[]); + const onSelectResource = useCallback((resourceID) => { setSelectedResource(prevSelectedResource => prevSelectedResource === resourceID ? null : resourceID); }, []); From b63b4d51aa09ca038cbbdf82b43aa218c86cfc15 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Tue, 1 Jun 2021 18:10:10 +0200 Subject: [PATCH 04/22] fix merge --- public/components/overview/mitre/mitre.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/components/overview/mitre/mitre.tsx b/public/components/overview/mitre/mitre.tsx index e9847d1463..9c932e7245 100644 --- a/public/components/overview/mitre/mitre.tsx +++ b/public/components/overview/mitre/mitre.tsx @@ -120,7 +120,7 @@ export class Mitre extends Component { const result = (((data || {}).data || {}).data || {}).affected_items; const tacticsObject = {}; result && result.forEach(item => { - tacticsObject[item.name] = item; + tacticsObject[item.references[0].external_id] = item; }); this._isMount && this.setState({tacticsObject, isLoading: false}); } catch(err) { From aad3eaa919be7b5c556531fd5dc82bc4f2631c72 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Fri, 4 Jun 2021 11:44:21 +0200 Subject: [PATCH 05/22] fix merge flyout --- public/components/overview/mitre/mitre.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/components/overview/mitre/mitre.tsx b/public/components/overview/mitre/mitre.tsx index 9c932e7245..e9847d1463 100644 --- a/public/components/overview/mitre/mitre.tsx +++ b/public/components/overview/mitre/mitre.tsx @@ -120,7 +120,7 @@ export class Mitre extends Component { const result = (((data || {}).data || {}).data || {}).affected_items; const tacticsObject = {}; result && result.forEach(item => { - tacticsObject[item.references[0].external_id] = item; + tacticsObject[item.name] = item; }); this._isMount && this.setState({tacticsObject, isLoading: false}); } catch(err) { From 5adeba6e985e0ddd7c00753f229e5487f46c1c32 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Mon, 7 Jun 2021 13:29:19 +0200 Subject: [PATCH 06/22] fix package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2c7f5df059..4576383c4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wazuh", - "version": "4.2.0", + "version": "4.3.0", "revision": "4201-10", "code": "4201-10", "kibana": { From dc6c79256944364d9f4b26cfff4055e4f4a87166 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Mon, 7 Jun 2021 18:38:12 +0200 Subject: [PATCH 07/22] fix PR comments and add intelligence section redirect --- CHANGELOG.md | 1 + .../flyout-technique/flyout-technique.tsx | 24 ++++--------------- .../techniques/components/technique/index.ts | 11 --------- .../components/technique/teqnique.tsx | 11 --------- .../components/techniques/techniques.tsx | 2 +- .../module_mitre_intelligence.tsx | 7 +++--- 6 files changed, 11 insertions(+), 45 deletions(-) delete mode 100644 public/components/overview/mitre/components/techniques/components/technique/index.ts delete mode 100644 public/components/overview/mitre/components/techniques/components/technique/teqnique.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 91f3056e8a..59d91b2a12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Changed position of Top users on Integrity Monitoring Top 5 user. [#2892](https://github.com/wazuh/wazuh-kibana-app/pull/2892) - Changed user allow_run_as way of editing. [#3080](https://github.com/wazuh/wazuh-kibana-app/pull/3080) - Rename some ossec references to Wazuh [#3046](https://github.com/wazuh/wazuh-kibana-app/pull/3046) +- Changed tactis and techniques resources [#3346](https://github.com/wazuh/wazuh-kibana-app/pull/3346) ### Fixed diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index b78f07144d..5d051d763e 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -133,12 +133,11 @@ export class FlyoutTechnique extends Component { findTacticName(tactics){ const { tacticsObject } = this.props; - const tacticsObj = [] - tactics.forEach(element => { - const tactic = Object.keys(tacticsObject).map(tacticsKey => tacticsObject[tacticsKey]).find(obj => obj.id === element) - tacticsObj.push({ id:tactic.references[0].external_id, name: tactic.name}) - }); - return tacticsObj + const getTactic = (element) => { + const tactic = Object.values(tacticsObject).find(obj => obj.id === element); + return { id:tactic.references[0].external_id, name: tactic.name}; + }; + return tactics.reduce((tacticsObj, element) => [...tacticsObj, getTactic(element)], []); } formatTechniqueData (rawData) { @@ -184,22 +183,9 @@ export class FlyoutTechnique extends Component { ) } - renderTactics(tactics){ - tactics.map(tactic => { - return ( - - {tactic.id} - - ) - }) - } - renderBody() { const { currentTechnique } = this.props; const { techniqueData } = this.state; - console.log(techniqueData) const implicitFilters=[{ 'rule.mitre.id': currentTechnique}, this.clusterFilter ]; if(this.props.implicitFilters){ this.props.implicitFilters.forEach( item => diff --git a/public/components/overview/mitre/components/techniques/components/technique/index.ts b/public/components/overview/mitre/components/techniques/components/technique/index.ts deleted file mode 100644 index 0be09f42eb..0000000000 --- a/public/components/overview/mitre/components/techniques/components/technique/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Wazuh app - Mitre alerts components - * Copyright (C) 2015-2021 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ diff --git a/public/components/overview/mitre/components/techniques/components/technique/teqnique.tsx b/public/components/overview/mitre/components/techniques/components/technique/teqnique.tsx deleted file mode 100644 index 0be09f42eb..0000000000 --- a/public/components/overview/mitre/components/techniques/components/technique/teqnique.tsx +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Wazuh app - Mitre alerts components - * Copyright (C) 2015-2021 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 2afed8aed1..a52fc94fed 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -69,7 +69,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { currentTechniqueData: {}, techniquesCount: [], currentTechnique: '', - hideAlerts: false, + hideAlerts: true, actionsOpen: "", filteredTechniques: false, mitreTechniques: [], diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx index e2ca3a979f..e47fb236e3 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx @@ -54,19 +54,20 @@ export const ModuleMitreIntelligence = () => { )).filter(searchTermAllResourcesResponse => searchTermAllResourcesResponse.results.length) } , [searchTermAllResources]); - + useEffect(() => { const redirectTab = sessionStorage.getItem("tabRedirect") const idToRedirect = sessionStorage.getItem("idToRedirect") - if(redirectTab){ - setResourceFilters([{field: 'search', value: idToRedirect}]); + if(redirectTab && idToRedirect){ setSelectedResource(redirectTab); + setResourceFilters([{field: 'search', value: idToRedirect}]); sessionStorage.removeItem("tabRedirect") sessionStorage.removeItem("idToRedirect") } },[]); const onSelectResource = useCallback((resourceID) => { + setResourceFilters([]); setSelectedResource(prevSelectedResource => prevSelectedResource === resourceID ? null : resourceID); }, []); From 38a5d6212ab2308dbf2c04d673cba92747b6c9e2 Mon Sep 17 00:00:00 2001 From: CPAlejandro Date: Mon, 7 Jun 2021 11:23:20 +0200 Subject: [PATCH 08/22] Created new Mitre flyout --- .../mitre_attack_resources.ts | 31 +++- ...itre_attack_intelligence_all_resources.tsx | 36 +++- ...elligence_all_resources_search_results.tsx | 3 +- ...ule_mitre_attack_intelligence_resource.tsx | 63 +------ ...re_attack_intelligence_resource_flyout.tsx | 169 ++++++++++++++++++ 5 files changed, 244 insertions(+), 58 deletions(-) create mode 100644 public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx diff --git a/public/components/overview/mitre_attack_intelligence/mitre_attack_resources.ts b/public/components/overview/mitre_attack_intelligence/mitre_attack_resources.ts index 04b7014742..ad570a9ee6 100644 --- a/public/components/overview/mitre_attack_intelligence/mitre_attack_resources.ts +++ b/public/components/overview/mitre_attack_intelligence/mitre_attack_resources.ts @@ -13,6 +13,7 @@ import { WzRequest } from '../../../react-services'; import { Markdown } from '../../common/util'; +import { formatUIDate } from '../../../react-services'; const getMitreAttackIntelligenceSuggestions = (endpoint: string, field: string) => async (input: string) => { try{ @@ -83,7 +84,35 @@ function buildResource(label: string, labelResource: string){ ) : '', truncateText: true } - ] + ], + mitreFlyoutHeaderProperties: [ + { + label: 'ID', + id: 'references.external_id', + }, + { + label: 'Name', + id: 'name' + }, + { + label: 'Created Time', + id: 'created_time', + render: (value) => value ? ( + formatUIDate(value) + ) : '' + }, + { + label: 'Modified Time', + id: 'modified_time', + render: (value) => value ? ( + formatUIDate(value) + ) : '' + }, + { + label: 'Version', + id: 'mitre_version' + }, + ], } }; diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx index c8002cfab8..d75080cf7c 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx @@ -11,7 +11,7 @@ * Find more information about this on the LICENSE file. */ -import React from 'react'; +import React, {useCallback, useState} from 'react'; import { EuiTitle, EuiSpacer @@ -19,13 +19,45 @@ import { import { withGuard } from'../../../components/common/hocs'; import { ModuleMitreAttackIntelligenceAllResourcesWelcome } from './module_mitre_attack_intelligence_all_resources_welcome'; import { ModuleMitreAttackIntelligenceAllResourcesSearchResults } from './module_mitre_attack_intelligence_all_resources_search_results'; +import { ModuleMitreAttackIntelligenceFlyout } from './module_mitre_attack_intelligence_resource_flyout'; export const ModuleMitreAttackIntelligenceAllResources = withGuard(({didSearch}) => !didSearch, ModuleMitreAttackIntelligenceAllResourcesWelcome)(({ results, loading }) => { + const [isDetailsOpen, setIsDetailsOpen] = useState(false); + const [details, setDetails] = useState(null); + + const mapResponseItem = (item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id}); + + const rowProps = useCallback((item) => { + setDetails(mapResponseItem(item)); + setIsDetailsOpen(true); + },[]); + + const rowPropsFlyout = useCallback((item) => ({ + // 'data-test-subj': `row-${file}`, + onClick: () => { + setDetails(item); + setIsDetailsOpen(true); + }, + }), []); + + const closeFlyout = useCallback(() => { + setDetails(null); + setIsDetailsOpen(false); + },[]); + return ( <>

Search results

- + + + {details && isDetailsOpen && ( + closeFlyout()} + tableProps={rowPropsFlyout} + /> + )} ) }); diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources_search_results.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources_search_results.tsx index f8058ef9cd..29fd004763 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources_search_results.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources_search_results.tsx @@ -28,7 +28,7 @@ const LoadingProgress = () => ( ); -export const ModuleMitreAttackIntelligenceAllResourcesSearchResults = withGuard(({loading}) => loading, LoadingProgress)(({ results, setResourceFilters }) => { +export const ModuleMitreAttackIntelligenceAllResourcesSearchResults = withGuard(({loading}) => loading, LoadingProgress)(({ results, setResourceFilters, rowProps }) => { const thereAreResults = results && results.length > 0; return thereAreResults ? results.map(item => ( @@ -49,6 +49,7 @@ export const ModuleMitreAttackIntelligenceAllResourcesSearchResults = withGuard( {item.results.map((result, resultIndex) => ( rowProps(result)} > {result[item.fieldName]} diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx index 3550847472..4c2553191b 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx @@ -13,8 +13,9 @@ import React, { useCallback, useState } from 'react'; import { TableWzAPI } from '../../../components/common/tables'; +import { ModuleMitreAttackIntelligenceFlyout } from './module_mitre_attack_intelligence_resource_flyout'; -export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggestions, apiEndpoint, tableColumns, detailsProperties, initialSortingField = 'name', resourceFilters }) => { +export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggestions, apiEndpoint, tableColumns, initialSortingField = 'name', resourceFilters }) => { const [isDetailsOpen, setIsDetailsOpen] = useState(false); const [details, setDetails] = useState(null); @@ -46,59 +47,13 @@ export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggesti mapResponseItem={(item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id})} filters={resourceFilters} /> - {/* {details && isDetailsOpen && ( - - - - -

Details

-
-
- - - {detailsProperties.map(detailProperty => ( - -
{detailProperty.label}
- {details[detailProperty.id]} -
- ))} -
- - -
Description
- {details.description} -
-
- - - {this.state.totalHits || 0} hits} - buttonContent='Techniques' - paddingSize='none' - initialIsOpen={true}> - ({technique}))} - columns={[{field: 'technique', name: 'Technique'}]} - /> - - - -
-
-
- ) - } */} + {details && isDetailsOpen && ( + closeFlyout()} + tableProps={rowProps} + /> + )} ) } diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx new file mode 100644 index 0000000000..6b3e1a13de --- /dev/null +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx @@ -0,0 +1,169 @@ +/* + * Wazuh app - React component for showing the Mitre Att&ck intelligence flyout. + * + * Copyright (C) 2015-2021 Wazuh, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Find more information about this on the LICENSE file. + */ + +import React , {useState, useEffect, useRef} from 'react'; +import { WzRequest } from '../../../react-services'; +import { MitreAttackResources } from './mitre_attack_resources'; + +import { + EuiBasicTableColumn, + EuiButtonIcon, + EuiFlyout, + EuiFlyoutHeader, + EuiOverlayMask, + EuiTitle, + EuiText, + EuiFlexGroup, + EuiFlyoutBody, + EuiFlexItem, + EuiAccordion, + SortDirection, + EuiInMemoryTable, + } from '@elastic/eui'; + import { Markdown } from '../../common/util/markdown' +import { EuiButton } from '@elastic/eui/src/components/button/button'; + + const GetFlyoutSubtable = ({name, array, props}) => { + const [isLoading, setIsLoading] = useState(true); + const [data, setData] = useState([]); + + useEffect(() => { + getValues(); + }, []); + useEffect(() => { + getValues(); + }, [array]); + + const getValues = async () => { + setIsLoading(true); + // We extract the ids from the subtable and count them in a string for the call that will extract the info + let namesContatenated = ['']; + let contador = 0; + array.forEach((element) => { + //The character limit of a request is 8190, if the characters of our request exceed 8100, we divide said call into several to avoid errors + if(namesContatenated[contador].length + element.length >= 8100) + contador++; + namesContatenated[contador] += element; + namesContatenated[contador] += ','; + }); + // We make the call to extract the necessary information from the subtable + try{ + namesContatenated.forEach(async (nameConcatenated) => { + const data = await WzRequest.apiReq('GET', `/mitre/${name}?${name.slice(-1) === 's' ? name.substring(0, name.length-1) : name}_ids=${nameConcatenated}`, {}); + setData(((((data || {}).data || {}).data || {}).affected_items || []).map((item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id}))); + }); + } + catch (error){ + console.log("Error in Mitre Flyout due to: ", error); + } + setIsLoading(false); + } + + const columns: EuiBasicTableColumn[] = [ + { + field: 'references.external_id', + name: 'ID', + sortable: true, + }, + { + field: 'name', + name: 'Name', + sortable: true, + }, + { + field: 'description', + name: 'Description', + sortable: true, + render: (item) => item ? : '', + truncateText: true + + }, + ]; + + return ( + {this.state.totalHits || 0} hits} + buttonContent={name.charAt(0).toUpperCase() + name.slice(1)} + paddingSize='none' + initialIsOpen={true}> + + + ); + } + + // run this function from an event handler or an effect to execute scroll + + export const ModuleMitreAttackIntelligenceFlyout = ({details, closeFlyout, tableProps}) => { + const startReference = useRef(null); + startReference.current?.scrollIntoView(); + + return ( + + + + +

Details

+
+
+ +
+ + {MitreAttackResources[0].mitreFlyoutHeaderProperties.map(detailProperty => ( + +
{detailProperty.label}
+ {detailProperty.render ? detailProperty.render(details[detailProperty.id]) : details[detailProperty.id]} +
+ ))} +
+
+ + +
Description
+ { details.description ? : ''} +
+
+ + + {MitreAttackResources.filter((item) => details[item.id]).map((item) => + + )} + + +
+
+
+ ) + }; + From 57cb78fb035e43a5feecbcd679d24ea55cf8bc3f Mon Sep 17 00:00:00 2001 From: CPAlejandro Date: Mon, 7 Jun 2021 11:49:22 +0200 Subject: [PATCH 09/22] Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59d91b2a12..ad80cabb46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to the Wazuh app project will be documented in this file. +## Wazuh v4.3.0 - Kibana 7.10.2 , 7.11.2 - Revision 4301 + +### Added + +- Create the detail section for Mitre Intelligence resources. [#3344](https://github.com/wazuh/wazuh-kibana-app/pull/3344) + ## Wazuh v4.2.0 - Kibana 7.10.2 , 7.11.2 - Revision 4201 ### Added From acec18110e4bcb7a88f9beeaa6760ad95099de4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20David=20Guti=C3=A9rrez?= Date: Mon, 7 Jun 2021 12:16:38 +0200 Subject: [PATCH 10/22] fix comments PR --- .../flyout-technique/flyout-technique.tsx | 17 ----------------- .../mitre/components/techniques/techniques.tsx | 10 +++++----- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index 5d051d763e..2ad4654693 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -146,23 +146,6 @@ export class FlyoutTechnique extends Component { this.setState({techniqueData: { name, mitre_version, tacticsObj }, loading: false }) } - - getArrayFormatted(arrObj) { - try { - arrObj.map(obj => { - return ( - - {obj.name} - - ) - }) - } - catch{ - return "" - } - } renderHeader() { const { techniqueData } = this.state; diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index a52fc94fed..5bfc16c35d 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -69,7 +69,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { currentTechniqueData: {}, techniquesCount: [], currentTechnique: '', - hideAlerts: true, + hideAlerts: false, actionsOpen: "", filteredTechniques: false, mitreTechniques: [], @@ -190,11 +190,11 @@ export const Techniques = withWindowSize(class Techniques extends Component { buildObjTechniques(techniques){ const techniquesObj = [] techniques.forEach(element => { - const mitreObj = this.state.mitreTechniques.filter(item => item.id === element) + const mitreObj = this.state.mitreTechniques.filter(item => item.id === element); if(mitreObj.length != 0){ - const mitreTechniqueName = mitreObj[0].name - const mitreTechniqueID = mitreObj[0].references.filter(item => item.source === "mitre-attack")[0].external_id - mitreTechniqueID ? techniquesObj.push({ id : mitreTechniqueID, name: mitreTechniqueName}) : '' + const mitreTechniqueName = mitreObj[0].name; + const mitreTechniqueID = mitreObj[0].references.filter(item => item.source === "mitre-attack")[0].external_id; + mitreTechniqueID ? techniquesObj.push({ id : mitreTechniqueID, name: mitreTechniqueName}) : ''; } }); return techniquesObj From 80fcf26eb90e27bd0a3c20e5f05b5e7450f82153 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Wed, 9 Jun 2021 13:52:34 +0200 Subject: [PATCH 11/22] add redirect values in query params --- .../components/techniques/techniques.tsx | 1 + ...ule_mitre_attack_intelligence_resource.tsx | 36 +++++++++++++++++-- .../module_mitre_intelligence.tsx | 9 ++--- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 5bfc16c35d..ebc4d849e5 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -307,6 +307,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { sessionStorage.setItem("tabRedirect", redirectTo); sessionStorage.setItem("idToRedirect", itemId); this.props.onSelectedTabChanged('intelligence'); + window.location.href = window.location+`&tabRedirect=${redirectTo}&idToRedirect=${itemId}` } /** diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx index 4c2553191b..51ce60fcee 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx @@ -11,14 +11,44 @@ * Find more information about this on the LICENSE file. */ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useState, useEffect } from 'react'; import { TableWzAPI } from '../../../components/common/tables'; import { ModuleMitreAttackIntelligenceFlyout } from './module_mitre_attack_intelligence_resource_flyout'; +import { WzRequest } from '../../../react-services'; + +export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggestions, apiEndpoint, tableColumns, initialSortingField, resourceFilters }) => { -export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggestions, apiEndpoint, tableColumns, initialSortingField = 'name', resourceFilters }) => { const [isDetailsOpen, setIsDetailsOpen] = useState(false); const [details, setDetails] = useState(null); + useEffect(() => { + const urlParams = new URLSearchParams(location.href); + const redirectTab = urlParams.get('tabRedirect'); + const idToRedirect = urlParams.get("idToRedirect") + if(redirectTab && idToRedirect){ + const endpoint = `/mitre/${redirectTab}?q=references.external_id=${idToRedirect}`; + getMitreItemToRedirect(endpoint) + urlParams.delete('tabRedirect') + urlParams.delete('idToRedirect') + window.history.pushState({},document.title,'#/overview/?tab=mitre') + } + },[]); + + + const getMitreItemToRedirect = (endpoint) => { + WzRequest.apiReq('GET', endpoint, {}).then(res => { + const data = res?.data?.data.affected_items + .map(item => ({ + ...item, + ['references.external_id']: item?.references?.find(reference => reference.source === 'mitre-attack')?.external_id + })) + setIsDetailsOpen(true) + setDetails(data[0]) + }).catch(err => { + {} + }); + }; + const rowProps = useCallback((item) => ({ // 'data-test-subj': `row-${file}`, onClick: () => { @@ -44,7 +74,7 @@ export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggesti endpoint={apiEndpoint} tableProps={{rowProps}} tablePageSizeOptions={[10]} - mapResponseItem={(item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id})} + mapResponseItem={(item) => ({...item, ['references.external_id']: item?.references?.find(reference => reference.source === 'mitre-attack')?.external_id})} filters={resourceFilters} /> {details && isDetailsOpen && ( diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx index e47fb236e3..5a316cc62a 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx @@ -56,13 +56,10 @@ export const ModuleMitreIntelligence = () => { , [searchTermAllResources]); useEffect(() => { - const redirectTab = sessionStorage.getItem("tabRedirect") - const idToRedirect = sessionStorage.getItem("idToRedirect") - if(redirectTab && idToRedirect){ + const urlParams = new URLSearchParams(location.href); + const redirectTab = urlParams.get('tabRedirect'); + if(redirectTab){ setSelectedResource(redirectTab); - setResourceFilters([{field: 'search', value: idToRedirect}]); - sessionStorage.removeItem("tabRedirect") - sessionStorage.removeItem("idToRedirect") } },[]); From 8c2f505ac80dc42d65f7c1ba5aa4c107963ba56f Mon Sep 17 00:00:00 2001 From: eze9252 Date: Wed, 9 Jun 2021 13:58:51 +0200 Subject: [PATCH 12/22] apply prettier --- .../flyout-technique/flyout-technique.tsx | 33 ++++++++++++++----- .../module_mitre_intelligence.tsx | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index 2ad4654693..3f850b1c48 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -197,15 +197,30 @@ export class FlyoutTechnique extends Component { }, { title: 'Tactics', - description: techniqueData.tacticsObj ? techniqueData.tacticsObj.map(tactic => { return ( <> - {this.props.openIntelligence(e,'tactics',tactic.id);e.stopPropagation()}}> - {tactic.name} - - -
- )}) : '' + description: techniqueData.tacticsObj + ? techniqueData.tacticsObj.map((tactic) => { + return ( + <> + + { + this.props.openIntelligence(e, "tactics", tactic.id); + e.stopPropagation(); + }} + > + {tactic.name} + + +
+ + ); + }) + : "" }, { title: 'Version', diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx index 5a316cc62a..438c7a1573 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_intelligence.tsx @@ -58,7 +58,7 @@ export const ModuleMitreIntelligence = () => { useEffect(() => { const urlParams = new URLSearchParams(location.href); const redirectTab = urlParams.get('tabRedirect'); - if(redirectTab){ + if (redirectTab) { setSelectedResource(redirectTab); } },[]); From 4546afc0afb8278af552c31fbbe2470a125cdbde Mon Sep 17 00:00:00 2001 From: CPAlejandro Date: Wed, 9 Jun 2021 12:54:38 +0200 Subject: [PATCH 13/22] Resolving comments and upgrading code --- ...itre_attack_intelligence_all_resources.tsx | 2 +- ...ule_mitre_attack_intelligence_resource.tsx | 3 +- ...re_attack_intelligence_resource_flyout.tsx | 169 ------------------ .../resource_detail_flyout.tsx | 107 +++++++++++ .../resource_detail_references_table.tsx | 105 +++++++++++ 5 files changed, 215 insertions(+), 171 deletions(-) delete mode 100644 public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx create mode 100644 public/components/overview/mitre_attack_intelligence/resource_detail_flyout.tsx create mode 100644 public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx index d75080cf7c..8e64aacdb2 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx @@ -19,7 +19,7 @@ import { import { withGuard } from'../../../components/common/hocs'; import { ModuleMitreAttackIntelligenceAllResourcesWelcome } from './module_mitre_attack_intelligence_all_resources_welcome'; import { ModuleMitreAttackIntelligenceAllResourcesSearchResults } from './module_mitre_attack_intelligence_all_resources_search_results'; -import { ModuleMitreAttackIntelligenceFlyout } from './module_mitre_attack_intelligence_resource_flyout'; +import { ModuleMitreAttackIntelligenceFlyout } from './resource_detail_flyout'; export const ModuleMitreAttackIntelligenceAllResources = withGuard(({didSearch}) => !didSearch, ModuleMitreAttackIntelligenceAllResourcesWelcome)(({ results, loading }) => { const [isDetailsOpen, setIsDetailsOpen] = useState(false); diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx index 51ce60fcee..1806725ffe 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx @@ -13,8 +13,9 @@ import React, { useCallback, useState, useEffect } from 'react'; import { TableWzAPI } from '../../../components/common/tables'; -import { ModuleMitreAttackIntelligenceFlyout } from './module_mitre_attack_intelligence_resource_flyout'; import { WzRequest } from '../../../react-services'; +import { ModuleMitreAttackIntelligenceFlyout } from './resource_detail_flyout'; + export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggestions, apiEndpoint, tableColumns, initialSortingField, resourceFilters }) => { diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx deleted file mode 100644 index 6b3e1a13de..0000000000 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource_flyout.tsx +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Wazuh app - React component for showing the Mitre Att&ck intelligence flyout. - * - * Copyright (C) 2015-2021 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ - -import React , {useState, useEffect, useRef} from 'react'; -import { WzRequest } from '../../../react-services'; -import { MitreAttackResources } from './mitre_attack_resources'; - -import { - EuiBasicTableColumn, - EuiButtonIcon, - EuiFlyout, - EuiFlyoutHeader, - EuiOverlayMask, - EuiTitle, - EuiText, - EuiFlexGroup, - EuiFlyoutBody, - EuiFlexItem, - EuiAccordion, - SortDirection, - EuiInMemoryTable, - } from '@elastic/eui'; - import { Markdown } from '../../common/util/markdown' -import { EuiButton } from '@elastic/eui/src/components/button/button'; - - const GetFlyoutSubtable = ({name, array, props}) => { - const [isLoading, setIsLoading] = useState(true); - const [data, setData] = useState([]); - - useEffect(() => { - getValues(); - }, []); - useEffect(() => { - getValues(); - }, [array]); - - const getValues = async () => { - setIsLoading(true); - // We extract the ids from the subtable and count them in a string for the call that will extract the info - let namesContatenated = ['']; - let contador = 0; - array.forEach((element) => { - //The character limit of a request is 8190, if the characters of our request exceed 8100, we divide said call into several to avoid errors - if(namesContatenated[contador].length + element.length >= 8100) - contador++; - namesContatenated[contador] += element; - namesContatenated[contador] += ','; - }); - // We make the call to extract the necessary information from the subtable - try{ - namesContatenated.forEach(async (nameConcatenated) => { - const data = await WzRequest.apiReq('GET', `/mitre/${name}?${name.slice(-1) === 's' ? name.substring(0, name.length-1) : name}_ids=${nameConcatenated}`, {}); - setData(((((data || {}).data || {}).data || {}).affected_items || []).map((item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id}))); - }); - } - catch (error){ - console.log("Error in Mitre Flyout due to: ", error); - } - setIsLoading(false); - } - - const columns: EuiBasicTableColumn[] = [ - { - field: 'references.external_id', - name: 'ID', - sortable: true, - }, - { - field: 'name', - name: 'Name', - sortable: true, - }, - { - field: 'description', - name: 'Description', - sortable: true, - render: (item) => item ? : '', - truncateText: true - - }, - ]; - - return ( - {this.state.totalHits || 0} hits} - buttonContent={name.charAt(0).toUpperCase() + name.slice(1)} - paddingSize='none' - initialIsOpen={true}> - - - ); - } - - // run this function from an event handler or an effect to execute scroll - - export const ModuleMitreAttackIntelligenceFlyout = ({details, closeFlyout, tableProps}) => { - const startReference = useRef(null); - startReference.current?.scrollIntoView(); - - return ( - - - - -

Details

-
-
- -
- - {MitreAttackResources[0].mitreFlyoutHeaderProperties.map(detailProperty => ( - -
{detailProperty.label}
- {detailProperty.render ? detailProperty.render(details[detailProperty.id]) : details[detailProperty.id]} -
- ))} -
-
- - -
Description
- { details.description ? : ''} -
-
- - - {MitreAttackResources.filter((item) => details[item.id]).map((item) => - - )} - - -
-
-
- ) - }; - diff --git a/public/components/overview/mitre_attack_intelligence/resource_detail_flyout.tsx b/public/components/overview/mitre_attack_intelligence/resource_detail_flyout.tsx new file mode 100644 index 0000000000..1da95f9243 --- /dev/null +++ b/public/components/overview/mitre_attack_intelligence/resource_detail_flyout.tsx @@ -0,0 +1,107 @@ +/* + * Wazuh app - React component for showing the Mitre Att&ck intelligence flyout. + * + * Copyright (C) 2015-2021 Wazuh, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Find more information about this on the LICENSE file. + */ + +import React , {useRef} from 'react'; +import { MitreAttackResources } from './mitre_attack_resources'; +import { ReferencesTable } from './resource_detail_references_table'; + +import { + EuiFlyout, + EuiFlyoutHeader, + EuiOverlayMask, + EuiTitle, + EuiText, + EuiFlexGroup, + EuiFlyoutBody, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; +import { Markdown } from '../../common/util/markdown'; +import { FieldDetails } from 'src/plugins/discover/public/application/components/sidebar/types'; + +type tablePropsType = (item) => {onClick: () => void}; +type closeFlyoutType = () => {onClick: () => void}; + +interface DetailFlyoutType { + details: FieldDetails, + closeFlyout: closeFlyoutType, + tableProps: tablePropsType, +} + +export const ModuleMitreAttackIntelligenceFlyout = ({details, closeFlyout, tableProps}: DetailFlyoutType) => { + const startReference = useRef(null); + + return ( + + + + +

Details

+
+
+ +
+ + {MitreAttackResources[0].mitreFlyoutHeaderProperties.map(detailProperty => ( + +
+ + {detailProperty.label} + +
+ + {detailProperty.render ? detailProperty.render(details[detailProperty.id]) : details[detailProperty.id]} + +
+ ))} +
+
+ + +
+ + Description + +
+ + { details.description ? : ''} + +
+
+ + + {MitreAttackResources.filter((item) => details[item.id]).map((item) => + <> + { startReference.current?.scrollIntoView()}} + /> + + + )} + + +
+
+
+ ) +}; + diff --git a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx new file mode 100644 index 0000000000..edc7c068a1 --- /dev/null +++ b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx @@ -0,0 +1,105 @@ +/* + * Wazuh app - React component for showing the Mitre Att&ck intelligence flyout tables. + * + * Copyright (C) 2015-2021 Wazuh, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Find more information about this on the LICENSE file. + */ + +import React , {useState, useEffect} from 'react'; +import { WzRequest } from '../../../react-services'; +import { + EuiBasicTableColumn, + EuiAccordion, + SortDirection, + EuiInMemoryTable, +} from '@elastic/eui'; +import { Markdown } from '../../common/util/markdown'; + +type tablePropsType = (item) => {onClick: () => void}; +type backToTopType = () => void; + +interface referencesTableType { + referencesName: string, + referencesArray: Array, + tableProps: tablePropsType, + backToTop: backToTopType +} + +export const ReferencesTable = ({referencesName, referencesArray, tableProps, backToTop} : referencesTableType) => { + const [isLoading, setIsLoading] = useState(true); + const [data, setData] = useState([]); + useEffect(() => { + getValues(); + backToTop(); + }, [referencesArray]); + + const getValues = async () => { + setIsLoading(true); + // We extract the ids from the references tables and count them in a string for the call that will extract the info + const maxLength = 8100; + const namesConcatenated = referencesArray.reduce((namesArray = [''], element) => { + namesArray[namesArray.length -1].length >= maxLength && namesArray.push(''); + namesArray[namesArray.length -1] += `${namesArray[namesArray.length -1].length > 0 ? ',' :''}${element}`; + return namesArray; + }, ['']); + + // We make the call to extract the necessary information from the references tables + try{ + const data = await Promise.all(namesConcatenated.map(async (nameConcatenated) => { + const queryResult = await WzRequest.apiReq('GET', `/mitre/${referencesName}?${referencesName.slice(-1) === 's' ? referencesName.substring(0, referencesName.length-1) : referencesName}_ids=${nameConcatenated}`, {}); + return ((((queryResult || {}).data || {}).data || {}).affected_items || []).map((item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id})); + })); + setData(data.flat()); + } + catch (error){ + return Promise.reject(error); + } + setIsLoading(false); + } + + const columns: EuiBasicTableColumn[] = [ + { + field: 'references.external_id', + name: 'ID', + sortable: true, + }, + { + field: 'name', + name: 'Name', + sortable: true, + }, + { + field: 'description', + name: 'Description', + sortable: true, + render: (item) => item ? : '', + truncateText: true + }, + ]; + + return ( + + + + ); +} + From a3f5b42e8ad6d2be8e5be3079394aea7d45e3a5a Mon Sep 17 00:00:00 2001 From: CPAlejandro Date: Wed, 9 Jun 2021 17:53:30 +0200 Subject: [PATCH 14/22] Applying comments upgrades to references table --- .../resource_detail_references_table.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx index edc7c068a1..59f497425e 100644 --- a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx +++ b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx @@ -32,7 +32,7 @@ interface referencesTableType { } export const ReferencesTable = ({referencesName, referencesArray, tableProps, backToTop} : referencesTableType) => { - const [isLoading, setIsLoading] = useState(true); + const [isLoading, setIsLoading] = useState(true); const [data, setData] = useState([]); useEffect(() => { getValues(); @@ -52,7 +52,7 @@ export const ReferencesTable = ({referencesName, referencesArray, tableProps, ba // We make the call to extract the necessary information from the references tables try{ const data = await Promise.all(namesConcatenated.map(async (nameConcatenated) => { - const queryResult = await WzRequest.apiReq('GET', `/mitre/${referencesName}?${referencesName.slice(-1) === 's' ? referencesName.substring(0, referencesName.length-1) : referencesName}_ids=${nameConcatenated}`, {}); + const queryResult = await WzRequest.apiReq('GET', `/mitre/${referencesName}?${referencesName.replace(/s\s*$/, '')}_ids=${nameConcatenated}`, {}); return ((((queryResult || {}).data || {}).data || {}).affected_items || []).map((item) => ({...item, ['references.external_id']: item.references.find(reference => reference.source === 'mitre-attack')?.external_id})); })); setData(data.flat()); From c47e246b5531fb2707acde42d242e5dcc4f4b7ab Mon Sep 17 00:00:00 2001 From: CPAlejandro Date: Wed, 9 Jun 2021 18:20:23 +0200 Subject: [PATCH 15/22] Applying more upgrade comments --- .../resource_detail_references_table.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx index 59f497425e..01dbb428fb 100644 --- a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx +++ b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx @@ -58,6 +58,7 @@ export const ReferencesTable = ({referencesName, referencesArray, tableProps, ba setData(data.flat()); } catch (error){ + setIsLoading(false); return Promise.reject(error); } setIsLoading(false); @@ -90,7 +91,8 @@ export const ReferencesTable = ({referencesName, referencesArray, tableProps, ba className='events-accordion' buttonContent={referencesName.charAt(0).toUpperCase() + referencesName.slice(1)} paddingSize='none' - initialIsOpen={true}> + initialIsOpen={true} + > Date: Thu, 10 Jun 2021 09:58:42 +0200 Subject: [PATCH 16/22] fix(mitre_intelligence): Remove the Promise.reject in resource details flyout --- .../resource_detail_references_table.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx index 01dbb428fb..29e3de85fa 100644 --- a/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx +++ b/public/components/overview/mitre_attack_intelligence/resource_detail_references_table.tsx @@ -57,10 +57,7 @@ export const ReferencesTable = ({referencesName, referencesArray, tableProps, ba })); setData(data.flat()); } - catch (error){ - setIsLoading(false); - return Promise.reject(error); - } + catch (error){}; setIsLoading(false); } From 8ad0be8d5f1a36b65de967a7e8902d9f58b7c57f Mon Sep 17 00:00:00 2001 From: eze9252 Date: Thu, 10 Jun 2021 11:22:15 +0200 Subject: [PATCH 17/22] clear comments and imports --- .../overview/mitre/components/techniques/techniques.tsx | 1 - .../module_mitre_attack_intelligence_all_resources.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index ebc4d849e5..2e0a5224c8 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -37,7 +37,6 @@ import {WAZUH_ALERTS_PATTERN} from '../../../../../../common/constants'; import { AppState } from '../../../../../react-services/app-state'; import { WzFieldSearchDelay } from '../../../../common/search' import { getDataPlugin } from '../../../../../kibana-services'; -import { ModuleMitreIntelligence } from '../../../mitre_attack_intelligence' export const Techniques = withWindowSize(class Techniques extends Component { _isMount = false; diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx index 8e64aacdb2..0966e0868c 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_all_resources.tsx @@ -33,7 +33,6 @@ export const ModuleMitreAttackIntelligenceAllResources = withGuard(({didSearch}) },[]); const rowPropsFlyout = useCallback((item) => ({ - // 'data-test-subj': `row-${file}`, onClick: () => { setDetails(item); setIsDetailsOpen(true); From 1a0c446b475e37891d60468666fd5303ff0effb6 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Thu, 10 Jun 2021 13:05:58 +0200 Subject: [PATCH 18/22] fix error handler techniques --- .../components/techniques/techniques.tsx | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 2e0a5224c8..a18dcee312 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -36,7 +36,7 @@ import { WzRequest } from '../../../../../react-services/wz-request'; import {WAZUH_ALERTS_PATTERN} from '../../../../../../common/constants'; import { AppState } from '../../../../../react-services/app-state'; import { WzFieldSearchDelay } from '../../../../common/search' -import { getDataPlugin } from '../../../../../kibana-services'; +import { getDataPlugin, getToasts } from '../../../../../kibana-services'; export const Techniques = withWindowSize(class Techniques extends Component { _isMount = false; @@ -105,6 +105,15 @@ export const Techniques = withWindowSize(class Techniques extends Component { this._isMount = false; } + showToast(color: string, title: string = '', text: string = '', time: number = 3000) { + getToasts().add({ + color: color, + title: title, + text: text, + toastLifeTimeMs: time, + }); + }; + async getTechniquesCount() { try{ const {indexPattern, filters} = this.props; @@ -181,9 +190,21 @@ export const Techniques = withWindowSize(class Techniques extends Component { } async getMitreTechniques () { - const data = await WzRequest.apiReq('GET', '/mitre/techniques', {}).then(res => res).catch(err => mitreTechniques); - const result = (((data || {}).data || {}).data || {}).affected_items; - this.setState({ mitreTechniques: result }) + const params = { + limit: 1000, + }; + const data = await WzRequest.apiReq("GET", "/mitre/techniques", { params }) + .then((res) => (((res || {}).data || {}).data || {}).affected_items) + .catch((err) => { + this.showToast( + 'danger', + 'Error', + `Mitre techniques could not be fetched: ${err}`, + 3000 + ); + return [] + }); + this.setState({ mitreTechniques: data }) } buildObjTechniques(techniques){ @@ -202,6 +223,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { renderFacet() { const { tacticsObject } = this.props; const { techniquesCount } = this.state; + let hash = {}; let tacticsToRender: Array = []; const currentTechniques = Object.keys(tacticsObject).map(tacticsKey => ({tactic: tacticsKey, techniques: this.buildObjTechniques(tacticsObject[tacticsKey].techniques)})) .filter(tactic => this.props.selectedTactics[tactic.tactic]) @@ -209,12 +231,12 @@ export const Techniques = withWindowSize(class Techniques extends Component { .flat() .filter((techniqueID, index, array) => array.indexOf(techniqueID) === index); tacticsToRender = currentTechniques - .filter(techniqueID => this.state.filteredTechniques ? this.state.filteredTechniques.includes(techniqueID.id) : techniqueID.id) - .map(techniqueID => { + .filter(technique => this.state.filteredTechniques ? this.state.filteredTechniques.includes(technique.id) : technique.id && hash[technique.id] ? false : hash[technique.id] = true) + .map(technique => { return { - id: techniqueID.id, - label: `${techniqueID.id} - ${techniqueID.name}`, - quantity: (techniquesCount.find(item => item.key === techniqueID.id) || {}).doc_count || 0 + id: technique.id, + label: `${technique.id} - ${technique.name}`, + quantity: (techniquesCount.find(item => item.key === technique.id) || {}).doc_count || 0 } }) .filter(technique => this.state.hideAlerts ? technique.quantity !== 0 : true); From f9f37fe446f84ad7e4da67585bf802ba0d857c46 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Thu, 10 Jun 2021 13:08:51 +0200 Subject: [PATCH 19/22] delete session storage --- .../overview/mitre/components/techniques/techniques.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index a18dcee312..142d3a7489 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -325,8 +325,6 @@ export const Techniques = withWindowSize(class Techniques extends Component { } openIntelligence(e,redirectTo,itemId){ - sessionStorage.setItem("tabRedirect", redirectTo); - sessionStorage.setItem("idToRedirect", itemId); this.props.onSelectedTabChanged('intelligence'); window.location.href = window.location+`&tabRedirect=${redirectTo}&idToRedirect=${itemId}` } From 57381b3408b5b6234a64b000c7f99a56c67a01e6 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Thu, 10 Jun 2021 17:14:45 +0200 Subject: [PATCH 20/22] delete files and fix get techniques data --- .../components/search-bar-tecniques/index.ts | 11 ------- .../search-bar-techniques.tsx | 11 ------- .../components/techniques/techniques.tsx | 31 +++++++++++++------ 3 files changed, 22 insertions(+), 31 deletions(-) delete mode 100644 public/components/overview/mitre/components/techniques/components/search-bar-tecniques/index.ts delete mode 100644 public/components/overview/mitre/components/techniques/components/search-bar-tecniques/search-bar-techniques.tsx diff --git a/public/components/overview/mitre/components/techniques/components/search-bar-tecniques/index.ts b/public/components/overview/mitre/components/techniques/components/search-bar-tecniques/index.ts deleted file mode 100644 index 0be09f42eb..0000000000 --- a/public/components/overview/mitre/components/techniques/components/search-bar-tecniques/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Wazuh app - Mitre alerts components - * Copyright (C) 2015-2021 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ diff --git a/public/components/overview/mitre/components/techniques/components/search-bar-tecniques/search-bar-techniques.tsx b/public/components/overview/mitre/components/techniques/components/search-bar-tecniques/search-bar-techniques.tsx deleted file mode 100644 index 0be09f42eb..0000000000 --- a/public/components/overview/mitre/components/techniques/components/search-bar-tecniques/search-bar-techniques.tsx +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Wazuh app - Mitre alerts components - * Copyright (C) 2015-2021 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 142d3a7489..fa8bc47a35 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -79,7 +79,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { async componentDidMount(){ this._isMount = true; - this.getMitreTechniques() + this.buildMitreTechniquesFromApi() } shouldComponentUpdate(nextProps, nextState) { @@ -189,12 +189,9 @@ export const Techniques = withWindowSize(class Techniques extends Component { } } - async getMitreTechniques () { - const params = { - limit: 1000, - }; - const data = await WzRequest.apiReq("GET", "/mitre/techniques", { params }) - .then((res) => (((res || {}).data || {}).data || {}).affected_items) + async getMitreTechniques (params) { + return await WzRequest.apiReq("GET", "/mitre/techniques", { params: params }) + .then((res) => res) .catch((err) => { this.showToast( 'danger', @@ -202,9 +199,25 @@ export const Techniques = withWindowSize(class Techniques extends Component { `Mitre techniques could not be fetched: ${err}`, 3000 ); - return [] + [] }); - this.setState({ mitreTechniques: data }) + } + + async buildMitreTechniquesFromApi () { + const params = { limit: 500 }; + const output = await this.getMitreTechniques(params) + const totalItems = (((output || {}).data || {}).data || {}).total_affected_items; + let mitreTechniques = []; + if (totalItems && output.data && output.data.data && totalItems > 500) { + params.offset = 0; + mitreTechniques.push(...output.data.data.affected_items); + while (mitreTechniques.length < totalItems && params.offset < totalItems) { + params.offset += params.limit; + const tmpData = await this.getMitreTechniques(params) + mitreTechniques.push(...tmpData.data.data.affected_items); + } + } + this.setState({ mitreTechniques: mitreTechniques }) } buildObjTechniques(techniques){ From 9a53d0573a5d2b1a7b78d65f7adce932566a44b3 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Fri, 11 Jun 2021 12:00:22 +0200 Subject: [PATCH 21/22] fix redirect flyout to rules --- .../common/modules/discover/discover.tsx | 3 ++- .../flyout-technique/flyout-technique.tsx | 2 +- .../components/techniques/techniques.tsx | 4 +-- .../management/ruleset/rule-info.js | 27 +++++++++++++++---- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/public/components/common/modules/discover/discover.tsx b/public/components/common/modules/discover/discover.tsx index 0d99e5d902..0ea22f7626 100644 --- a/public/components/common/modules/discover/discover.tsx +++ b/public/components/common/modules/discover/discover.tsx @@ -96,6 +96,7 @@ export const Discover = compose( query?: { language: "kuery" | "lucene", query: string } type?: any, updateTotalHits: Function, + openIntelligence: Function, includeFilters?: string, initialColumns: string[], shareFilterManager: FilterManager, @@ -430,7 +431,7 @@ export const Discover = compose( width = '15%'; } if (item === 'rule.mitre.id') { - link = (ev, x) => { this.setState({ showMitreFlyout: true, selectedTechnique: x }) }; + link = (ev, x, e) => this.props.openIntelligence(e,'techniques',x); } if(arrayCompilance.indexOf(item) !== -1) { width = '30%'; diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index 3f850b1c48..feaa388876 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -283,7 +283,7 @@ export class FlyoutTechnique extends Component { initialIsOpen={true}> - this.updateTotalHits(total)}/> + this.updateTotalHits(total)} openIntelligence={(e,redirectTo,itemId) => this.props.openIntelligence(e,redirectTo,itemId)}/>
diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index fa8bc47a35..1390a4d7f4 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -190,6 +190,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { } async getMitreTechniques (params) { + this.setState({ isSearching: true }) return await WzRequest.apiReq("GET", "/mitre/techniques", { params: params }) .then((res) => res) .catch((err) => { @@ -217,7 +218,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { mitreTechniques.push(...tmpData.data.data.affected_items); } } - this.setState({ mitreTechniques: mitreTechniques }) + this.setState({ mitreTechniques: mitreTechniques, isSearching: false }) } buildObjTechniques(techniques){ @@ -253,7 +254,6 @@ export const Techniques = withWindowSize(class Techniques extends Component { } }) .filter(technique => this.state.hideAlerts ? technique.quantity !== 0 : true); - const tacticsToRenderOrdered = tacticsToRender.sort((a, b) => b.quantity - a.quantity).map( (item,idx) => { const tooltipContent = `View details of ${item.label} (${item.id})`; const toolTipAnchorClass = "wz-display-inline-grid" + (this.state.hover=== item.id ? " wz-mitre-width" : " "); diff --git a/public/controllers/management/components/management/ruleset/rule-info.js b/public/controllers/management/components/management/ruleset/rule-info.js index ae1088c2e9..b53668524d 100644 --- a/public/controllers/management/components/management/ruleset/rule-info.js +++ b/public/controllers/management/components/management/ruleset/rule-info.js @@ -371,6 +371,23 @@ class WzRuleInfo extends Component { ); } + async getTacticsNames(tactics){ + try{ + let tacticsObj = [] + const data = await WzRequest.apiReq('GET', '/mitre/tactics', { + params: { + tactic_ids: tactics.toString() + } + }) + const formattedData = (((((data || {}).data).data || {}).affected_items || []) || {}); + formattedData && formattedData.forEach(item => { + tacticsObj.push(item.name); + }); + return tacticsObj; + }catch(error){ + return [] + } + } async addMitreInformation(compliance, currentRuleId){ try{ @@ -378,16 +395,16 @@ class WzRuleInfo extends Component { const mitreName = []; const mitreIds = []; const mitreTactics = await Promise.all(compliance.map(async (i) => { - const data = await WzRequest.apiReq('GET', '/mitre', { + const data = await WzRequest.apiReq('GET', '/mitre/techniques', { params: { - q: `id=${i}` + q: `references.external_id=${i}` } }); const formattedData = (((((data || {}).data).data || {}).affected_items || [])[0] || {}); - const techniques = formattedData.phase_name || []; - mitreName.push(formattedData.json.name); + const tactics = this.getTacticsNames(formattedData.tactics) || []; + mitreName.push(formattedData.name); mitreIds.push(i); - return techniques; + return tactics; })); if(mitreTactics.length){ let removeDuplicates = (arr) => arr.filter((v,i) => arr.indexOf(v) === i) From b030b2b6d9680263969e53461dc908403bddd1e2 Mon Sep 17 00:00:00 2001 From: eze9252 Date: Mon, 14 Jun 2021 17:22:38 +0200 Subject: [PATCH 22/22] fix comments PR --- .../flyout-technique/flyout-technique.tsx | 8 ++--- .../components/techniques/techniques.tsx | 16 ++++----- ...ule_mitre_attack_intelligence_resource.tsx | 36 ++++++++++--------- .../management/ruleset/rule-info.js | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx index feaa388876..f943a401f6 100644 --- a/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx +++ b/public/components/overview/mitre/components/techniques/components/flyout-technique/flyout-technique.tsx @@ -133,18 +133,16 @@ export class FlyoutTechnique extends Component { findTacticName(tactics){ const { tacticsObject } = this.props; - const getTactic = (element) => { + return tactics.map((element) => { const tactic = Object.values(tacticsObject).find(obj => obj.id === element); return { id:tactic.references[0].external_id, name: tactic.name}; - }; - return tactics.reduce((tacticsObj, element) => [...tacticsObj, getTactic(element)], []); + }); } formatTechniqueData (rawData) { const { tactics, name, mitre_version } = rawData; const tacticsObj = this.findTacticName(tactics) - - this.setState({techniqueData: { name, mitre_version, tacticsObj }, loading: false }) + this.setState({techniqueData: { name, mitre_version, tacticsObj }, loading: false }); } renderHeader() { diff --git a/public/components/overview/mitre/components/techniques/techniques.tsx b/public/components/overview/mitre/components/techniques/techniques.tsx index 1390a4d7f4..da288913a1 100644 --- a/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/public/components/overview/mitre/components/techniques/techniques.tsx @@ -29,13 +29,13 @@ import { EuiLoadingSpinner, } from '@elastic/eui'; import { FlyoutTechnique } from './components/flyout-technique/'; -import { getElasticAlerts, IFilterParams } from '../../lib' +import { getElasticAlerts, IFilterParams } from '../../lib'; import { ITactic } from '../../'; import { withWindowSize } from '../../../../../components/common/hocs/withWindowSize'; import { WzRequest } from '../../../../../react-services/wz-request'; import {WAZUH_ALERTS_PATTERN} from '../../../../../../common/constants'; import { AppState } from '../../../../../react-services/app-state'; -import { WzFieldSearchDelay } from '../../../../common/search' +import { WzFieldSearchDelay } from '../../../../common/search'; import { getDataPlugin, getToasts } from '../../../../../kibana-services'; export const Techniques = withWindowSize(class Techniques extends Component { @@ -79,7 +79,7 @@ export const Techniques = withWindowSize(class Techniques extends Component { async componentDidMount(){ this._isMount = true; - this.buildMitreTechniquesFromApi() + await this.buildMitreTechniquesFromApi() } shouldComponentUpdate(nextProps, nextState) { @@ -209,9 +209,9 @@ export const Techniques = withWindowSize(class Techniques extends Component { const output = await this.getMitreTechniques(params) const totalItems = (((output || {}).data || {}).data || {}).total_affected_items; let mitreTechniques = []; + mitreTechniques.push(...output.data.data.affected_items); if (totalItems && output.data && output.data.data && totalItems > 500) { params.offset = 0; - mitreTechniques.push(...output.data.data.affected_items); while (mitreTechniques.length < totalItems && params.offset < totalItems) { params.offset += params.limit; const tmpData = await this.getMitreTechniques(params) @@ -224,10 +224,10 @@ export const Techniques = withWindowSize(class Techniques extends Component { buildObjTechniques(techniques){ const techniquesObj = [] techniques.forEach(element => { - const mitreObj = this.state.mitreTechniques.filter(item => item.id === element); - if(mitreObj.length != 0){ - const mitreTechniqueName = mitreObj[0].name; - const mitreTechniqueID = mitreObj[0].references.filter(item => item.source === "mitre-attack")[0].external_id; + const mitreObj = this.state.mitreTechniques.find(item => item.id === element); + if(mitreObj){ + const mitreTechniqueName = mitreObj.name; + const mitreTechniqueID = mitreObj.references.find(item => item.source === "mitre-attack").external_id; mitreTechniqueID ? techniquesObj.push({ id : mitreTechniqueID, name: mitreTechniqueName}) : ''; } }); diff --git a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx index 1806725ffe..dadd1184dd 100644 --- a/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx +++ b/public/components/overview/mitre_attack_intelligence/module_mitre_attack_intelligence_resource.tsx @@ -25,31 +25,33 @@ export const ModuleMitreAttackIntelligenceResource = ({ label, searchBarSuggesti useEffect(() => { const urlParams = new URLSearchParams(location.href); const redirectTab = urlParams.get('tabRedirect'); - const idToRedirect = urlParams.get("idToRedirect") + const idToRedirect = urlParams.get("idToRedirect"); if(redirectTab && idToRedirect){ const endpoint = `/mitre/${redirectTab}?q=references.external_id=${idToRedirect}`; - getMitreItemToRedirect(endpoint) - urlParams.delete('tabRedirect') - urlParams.delete('idToRedirect') + getMitreItemToRedirect(endpoint); + urlParams.delete('tabRedirect'); + urlParams.delete('idToRedirect'); window.history.pushState({},document.title,'#/overview/?tab=mitre') } },[]); - const getMitreItemToRedirect = (endpoint) => { - WzRequest.apiReq('GET', endpoint, {}).then(res => { - const data = res?.data?.data.affected_items - .map(item => ({ - ...item, - ['references.external_id']: item?.references?.find(reference => reference.source === 'mitre-attack')?.external_id - })) - setIsDetailsOpen(true) - setDetails(data[0]) - }).catch(err => { - {} - }); + const getMitreItemToRedirect = async (endpoint) => { + try { + const res = await WzRequest.apiReq("GET", endpoint, {}); + const data = res?.data?.data.affected_items.map((item) => ({ + ...item, + ["references.external_id"]: item?.references?.find( + (reference) => reference.source === "mitre-attack" + )?.external_id, + })); + setIsDetailsOpen(true); + setDetails(data[0]); + } catch { + return {}; + } }; - + const rowProps = useCallback((item) => ({ // 'data-test-subj': `row-${file}`, onClick: () => { diff --git a/public/controllers/management/components/management/ruleset/rule-info.js b/public/controllers/management/components/management/ruleset/rule-info.js index b53668524d..29725ed52f 100644 --- a/public/controllers/management/components/management/ruleset/rule-info.js +++ b/public/controllers/management/components/management/ruleset/rule-info.js @@ -385,7 +385,7 @@ class WzRuleInfo extends Component { }); return tacticsObj; }catch(error){ - return [] + return []; } }