CN-1391 fix: Detection列表按新版设计更新接口和样式
This commit is contained in:
@@ -60,12 +60,13 @@
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.row__content {
|
||||
.row__content, .row__content1 {
|
||||
display: flex;
|
||||
//color: #3976CB;
|
||||
color: #046ECA;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
|
||||
&.row__content--link {
|
||||
font-style: italic;
|
||||
@@ -87,6 +88,17 @@
|
||||
font-style: italic;
|
||||
color: #1890FF;
|
||||
}
|
||||
|
||||
.row__content__icon {
|
||||
font-size: 14px;
|
||||
margin-right: 5px;
|
||||
color: #1890FF;
|
||||
}
|
||||
|
||||
.row__content__svg {
|
||||
font-size: 14px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,13 +227,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.row__tag {
|
||||
.row__tag, .row__tag__level {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 4px;
|
||||
//color: white;
|
||||
}
|
||||
.row__tag__level {
|
||||
height: 16px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.performance-event-remark {
|
||||
font-family: NotoSansSChineseRegular;
|
||||
|
||||
@@ -1234,7 +1234,8 @@ export default class Parser {
|
||||
// 不区分大小写,用this.columnList里的label
|
||||
arr.forEach(item => {
|
||||
if (str.toLowerCase().indexOf(item.toLowerCase()) > -1) {
|
||||
str = str.replace(new RegExp(item, 'gi'), item)
|
||||
// todo 记录一下此处取消了转小写转换,后续搜索验证
|
||||
// str = str.replace(new RegExp(item, 'gi'), item)
|
||||
if (!operatorList.some(ite => str.includes(ite)) && str.toLowerCase() !== item.toLowerCase()) {
|
||||
str = this.checkFormatByStr(str)
|
||||
}
|
||||
|
||||
353
src/mock/detectionList.js
Normal file
353
src/mock/detectionList.js
Normal file
@@ -0,0 +1,353 @@
|
||||
import Mock from 'mockjs'
|
||||
|
||||
const urlAndVersion = BASE_CONFIG.baseUrl + BASE_CONFIG.apiVersion
|
||||
const openMock = true
|
||||
if (openMock) {
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/list.*'), 'get', function (requestObj) {
|
||||
const result = []
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const obj = {
|
||||
eventId: 1212,
|
||||
eventType: 'Anonymity',
|
||||
eventName: 'Tor',
|
||||
eventKey: '2,1.1.1,12.2.2.2',
|
||||
ruleId: 2,
|
||||
ruleType: 'indicator_match',
|
||||
isBuiltin: 1,
|
||||
severity: 'critical',
|
||||
offenderIp: '1.1.1.1',
|
||||
victimIp: '2.2.2.2',
|
||||
domain: '*.vioee.com',
|
||||
app: 'vio',
|
||||
startTime: 1697092617,
|
||||
endTime: 1697092777,
|
||||
durationS: 30000,
|
||||
matchTimes: 1,
|
||||
status: 1,
|
||||
eventInfo: "{\'knowledge_id\': 123, \'name\': \'example_ioc_malware\', \'ioc_type\': \'domain\', \'ioc_value\': \'iocentity.com\'}",
|
||||
eventInfoObj: {
|
||||
knowledge_id: 123,
|
||||
name: 'example_ioc_malware',
|
||||
ioc_type: 'domain',
|
||||
ioc_value: 'iocentity.com'
|
||||
}
|
||||
}
|
||||
if (i % 2 === 0) {
|
||||
obj.status = 0
|
||||
}
|
||||
result.push(obj)
|
||||
}
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/severity/timedistribution.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
statTime: 1697523900,
|
||||
severity: 'critical',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
statTime: 1697524200,
|
||||
severity: 'high',
|
||||
count: 31
|
||||
},
|
||||
{
|
||||
statTime: 1697524500,
|
||||
severity: 'info',
|
||||
count: 21
|
||||
},
|
||||
{
|
||||
statTime: 1697524800,
|
||||
severity: 'low',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
statTime: 1697525100,
|
||||
severity: 'medium',
|
||||
count: 32
|
||||
},
|
||||
{
|
||||
statTime: 1697525400,
|
||||
severity: 'critical',
|
||||
count: 22
|
||||
},
|
||||
{
|
||||
statTime: 1697525700,
|
||||
severity: 'critical',
|
||||
count: 23
|
||||
},
|
||||
{
|
||||
statTime: 1697526000,
|
||||
severity: 'critical',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
statTime: 1697526300,
|
||||
severity: 'critical',
|
||||
count: 21
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/severity/statistics.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
severity: 'critical',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
severity: 'high',
|
||||
count: 31
|
||||
},
|
||||
{
|
||||
severity: 'info',
|
||||
count: 21
|
||||
},
|
||||
{
|
||||
severity: 'low',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
severity: 'medium',
|
||||
count: 32
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/event-type/statistics.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
eventType: 'Anonymity',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
eventType: 'Command and Control',
|
||||
count: 31
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/offender-ip/statistics.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
offenderIp: '221.7.1.20',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
offenderIp: '58.247.118.253',
|
||||
count: 31
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/victim-ip/statistics.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
victimIp: '21.77.1.201',
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
victimIp: '58.47.118.153',
|
||||
count: 31
|
||||
},
|
||||
{
|
||||
victimIp: '22.47.223.57',
|
||||
count: 43
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/status/statistics.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
status: 1,
|
||||
count: 25
|
||||
},
|
||||
{
|
||||
status: 0,
|
||||
count: 31
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/ip/relation/event.*'), 'get', function (requestObj) {
|
||||
const result = [
|
||||
{
|
||||
eventId: 10010,
|
||||
severity: 'high',
|
||||
eventType: 'Command and Control',
|
||||
offenderIp: '1.1.1.1',
|
||||
victimIp: '2.2.2.2',
|
||||
startTime: 1697092617
|
||||
}
|
||||
]
|
||||
|
||||
const data = {
|
||||
resultType: 'table',
|
||||
result: result
|
||||
}
|
||||
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: data
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/count.*'), 'get', function (requestObj) {
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: {
|
||||
resultType: 'single',
|
||||
result: 123
|
||||
}
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/entity/detail/ip.*'), 'get', function (requestObj) {
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: {
|
||||
asn: {
|
||||
id: 2,
|
||||
asn: '14061',
|
||||
organization: 'DIGITALOCEAN-ASN - DigitalOcean, LLC, US'
|
||||
},
|
||||
malware: {
|
||||
threatType: 'command and control',
|
||||
malwareName: 'IcedID',
|
||||
malwareAlias: 'BokBot,IceID',
|
||||
mitreAttackDescription: '[IcedID](https://attack.mitre.org/software/S0483) is a modular banking malware designed to steal financial information that has been observed in the wild since at least 2017. [IcedID](https://attack.mitre.org/software/S0483) has been downloaded by [Emotet](https://attack.mitre.org/software/S0367) in multiple campaigns.(Citation: IBM IcedID November 2017)(Citation: Juniper IcedID June 2020)',
|
||||
mitreAttackPlatforms: 'Windows',
|
||||
mitreAttackTechniques: '[""Asymmetric Cryptography(T1573.002)"",""Asynchronous Procedure Call(T1055.004)"",""Browser Session Hijacking(T1185)"",""Domain Account(T1087.002)"",""Ingress Tool Transfer(T1105)"",""Malicious File(T1204.002)"",""Msiexec(T1218.007)"",""Native API(T1106)"",""Obfuscated Files or Information(T1027)"",""Permission Groups Discovery(T1069)"",""Registry Run Keys / Startup Folder(T1547.001)"",""Scheduled Task(T1053.005)"",""Software Packing(T1027.002)"",""Spearphishing Attachment(T1566.001)"",""Steganography(T1027.003)"",""System Information Discovery(T1082)"",""Visual Basic(T1059.005)"",""Web Protocols(T1071.001)"",""Windows Management Instrumentation(T1047)""]',
|
||||
mitreAttackGroups: '[""TA551(G0127)""]',
|
||||
confidenceLevel: 'high',
|
||||
reference: ''
|
||||
},
|
||||
location: {
|
||||
continent: 'North America',
|
||||
country: 'United States',
|
||||
province: 'New York',
|
||||
city: '',
|
||||
lngwgs: '-74.006',
|
||||
latwgs: '40.713',
|
||||
isp: 'dba Omsoft',
|
||||
owner: 'tie net'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/entity/detail/domain.*'), 'get', function (requestObj) {
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: {
|
||||
malware: {
|
||||
threatType: 'command and control',
|
||||
malwareName: 'IcedID',
|
||||
malwareAlias: 'BokBot,IceID',
|
||||
mitreAttackDescription: '[IcedID](https://attack.mitre.org/software/S0483) is a modular banking malware designed to steal financial information that has been observed in the wild since at least 2017. [IcedID](https://attack.mitre.org/software/S0483) has been downloaded by [Emotet](https://attack.mitre.org/software/S0367) in multiple campaigns.(Citation: IBM IcedID November 2017)(Citation: Juniper IcedID June 2020)',
|
||||
mitreAttackPlatforms: 'Windows',
|
||||
mitreAttackTechniques: '[""Asymmetric Cryptography(T1573.002)"",""Asynchronous Procedure Call(T1055.004)"",""Browser Session Hijacking(T1185)"",""Domain Account(T1087.002)"",""Ingress Tool Transfer(T1105)"",""Malicious File(T1204.002)"",""Msiexec(T1218.007)"",""Native API(T1106)"",""Obfuscated Files or Information(T1027)"",""Permission Groups Discovery(T1069)"",""Registry Run Keys / Startup Folder(T1547.001)"",""Scheduled Task(T1053.005)"",""Software Packing(T1027.002)"",""Spearphishing Attachment(T1566.001)"",""Steganography(T1027.003)"",""System Information Discovery(T1082)"",""Visual Basic(T1059.005)"",""Web Protocols(T1071.001)"",""Windows Management Instrumentation(T1047)""]',
|
||||
mitreAttackGroups: '[""TA551(G0127)""]',
|
||||
confidenceLevel: 'high',
|
||||
reference: ''
|
||||
},
|
||||
category: {
|
||||
categoryName: '门户网站',
|
||||
categoryGroup: '互联网',
|
||||
reputationLevel: 'high'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Mock.mock(new RegExp(urlAndVersion + '/detection/security/entity/detail/app.*'), 'get', function (requestObj) {
|
||||
return {
|
||||
msg: 'OK',
|
||||
code: 200,
|
||||
data: {
|
||||
category: {
|
||||
appName: 'QQ',
|
||||
appId: 333,
|
||||
appCategory: '娱乐',
|
||||
appSubcategory: '聊天',
|
||||
appRisk: 'low',
|
||||
appDescription: '聊天社交软件',
|
||||
appLongname: 'Tencent qq',
|
||||
appTechnology: 'socket',
|
||||
appCompany: 'tencent',
|
||||
appCompanyCategory: '互联网'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -3,3 +3,4 @@ import './linkMonitor'
|
||||
import './dns'
|
||||
import './entity'
|
||||
import './detection'
|
||||
import './detectionList'
|
||||
|
||||
@@ -123,7 +123,20 @@ export const api = {
|
||||
listBasic: '/interface/detection/security/list/basic',
|
||||
listCount: '/interface/detection/security/list/count',
|
||||
overviewBasic: '/interface/detection/security/detail/overview/basic',
|
||||
overviewEvent: '/interface/detection/security/detail/overview/event'
|
||||
overviewEvent: '/interface/detection/security/detail/overview/event',
|
||||
securityList: apiVersion + '/detection/security/list', // 安全事件列表
|
||||
timeDistribution: apiVersion + '/detection/security/severity/timedistribution', // 事件严重等级分布(顶部柱状图)
|
||||
severityStatistics: apiVersion + '/detection/security/severity/statistics', // 事件严重等级统计(左侧filter事件严重等级和饼图)
|
||||
statusStatistics: apiVersion + '/detection/security/status/statistics', // 事件状态统计
|
||||
eventTypeStatistics: apiVersion + '/detection/security/event-type/statistics', // 事件类型统计
|
||||
offenderIpStatistics: apiVersion + '/detection/security/offender-ip/statistics', // 攻击者IP统计
|
||||
victimIpStatistics: apiVersion + '/detection/security/victim-ip/statistics', // 受害者IP统计
|
||||
relationEvent: apiVersion + '/detection/security/ip/relation/event', // IP相关近期事件
|
||||
securityCount: apiVersion + '/detection/security/count', // 安全事件总数
|
||||
detail: apiVersion + '/detection/security/entity/detail', // 安全事件实体详情,后面得加上实体类型
|
||||
ipDetail: apiVersion + '/detection/security/entity/detail/ip', // 安全事件实体详情ip响应
|
||||
domainDetail: apiVersion + '/detection/security/entity/detail/domain', // 安全事件实体详情domain响应
|
||||
appDetail: apiVersion + '/detection/security/entity/detail/app' // 安全事件实体详情app响应
|
||||
},
|
||||
performanceEvent: {
|
||||
eventSeverityTrend: '/interface/detection/performance/filter/severityTrend',
|
||||
|
||||
@@ -334,11 +334,91 @@ export const columnList1 = [
|
||||
}
|
||||
}
|
||||
]
|
||||
const securityEvent = [
|
||||
{
|
||||
name: 'event_type',
|
||||
type: 'string',
|
||||
label: 'event_type',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'event_name',
|
||||
type: 'string',
|
||||
label: 'event_name',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'severity',
|
||||
type: 'string',
|
||||
label: 'severity',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'offender_ip',
|
||||
type: 'string',
|
||||
label: 'offender Ip',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'victim_ip',
|
||||
type: 'string',
|
||||
label: 'victim Ip',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'domain',
|
||||
type: 'string',
|
||||
label: 'domain',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'app',
|
||||
type: 'string',
|
||||
label: 'app',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in,like'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
let schemaEntityExplore = localStorage.getItem(storageKey.schemaEntityExplore)
|
||||
schemaEntityExplore = schemaEntityExplore ? JSON.parse(schemaEntityExplore).entityMetadata.searchColumns : columnList1
|
||||
const schema = localStorage.getItem(storageKey.schemaEntityExplore)
|
||||
const schemaEntityExplore = schema ? JSON.parse(schema).entityMetadata.searchColumns : columnList1
|
||||
export const columnList = schemaEntityExplore
|
||||
|
||||
let securityEventMetadata = securityEvent
|
||||
if (schema) {
|
||||
if (JSON.parse(schema).securityEventMetadata) {
|
||||
securityEventMetadata = JSON.parse(schema).securityEventMetadata.searchColumns
|
||||
}
|
||||
}
|
||||
export const schemaDetectionSecurity = securityEventMetadata
|
||||
|
||||
export const operatorList = ['=', '!=', /* '>', '<', '>=', '<=', */'IN', 'NOT IN', 'LIKE', 'NOT LIKE']
|
||||
export const connectionList = [
|
||||
{
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
<loading :loading="loading"></loading>
|
||||
<div class="detection-list__content">
|
||||
<div class="detection-list--list">
|
||||
<div class="no-data" v-if="noData">{{ $t('npm.noData') }}</div>
|
||||
<div class="no-data" v-if="myListData.length===0">{{ $t('npm.noData') }}</div>
|
||||
<div v-if="!isCollapse" @click="collapse" class="cn-detection__shadow new-cn-detection__shadow"></div>
|
||||
<detection-row
|
||||
style="margin-bottom: 10px"
|
||||
class="detection-border"
|
||||
v-for="(data, index) in listData"
|
||||
v-for="(data, index) in myListData"
|
||||
:detection="data"
|
||||
:page-type="pageType"
|
||||
:timeFilter="timeFilter"
|
||||
@@ -26,6 +26,8 @@
|
||||
<script>
|
||||
import DetectionRow from '@/views/detections/DetectionRow'
|
||||
import Loading from '@/components/common/Loading'
|
||||
import axios from 'axios'
|
||||
import { api } from '@/utils/api'
|
||||
export default {
|
||||
name: 'DetectionList',
|
||||
components: {
|
||||
@@ -49,7 +51,8 @@ export default {
|
||||
collapseIndex: 0,
|
||||
tableId: 'detectionList',
|
||||
listDataCopy: [],
|
||||
noData: false
|
||||
noData: true,
|
||||
myListData: [] // listData的克隆,避免因为修改listData里的malWareName而触发watch监听
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
@@ -60,6 +63,23 @@ export default {
|
||||
window.removeEventListener('mousewheel', this.handleScroll)
|
||||
},
|
||||
methods: {
|
||||
initData () {
|
||||
this.myListData = []
|
||||
this.listData.forEach((item, i) => {
|
||||
this.myListData.push(this.$_.cloneDeep(item))
|
||||
if (item.eventInfoObj) {
|
||||
axios.get(`${api.detection.securityEvent.detail}/${item.eventInfoObj.ioc_type}/resource=${item.eventInfoObj.ioc_value}`).then(res => {
|
||||
if (res.status === 200) {
|
||||
this.myListData[i].malwareName = res.data.data.malware.malwareName
|
||||
} else {
|
||||
this.myListData[i].malwareName = '-'
|
||||
}
|
||||
}).catch(e => {
|
||||
this.myListData[i].malwareName = '-'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
switchCollapse (isCollapse, index) {
|
||||
this.isCollapse = isCollapse
|
||||
this.collapseIndex = index
|
||||
@@ -84,6 +104,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
listData: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!n || n.length === 0) {
|
||||
@@ -93,6 +114,7 @@ export default {
|
||||
} else {
|
||||
clearTimeout(this.timeout)
|
||||
this.noData = false
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="cn-detection__case">
|
||||
<div class="cn-detection__icon" :style="`background-color: ${eventSeverityColor[detection.eventSecurity]}`"></div>
|
||||
<div class="cn-detection__icon" :style="`background-color: ${eventSeverityColor[detection.severity]}`"></div>
|
||||
<div class="cn-detection__row">
|
||||
<div class="cn-detection__header" v-if="pageType === detectionPageType.securityEvent">
|
||||
<span
|
||||
class="detection-event-severity-color-block"
|
||||
:style="`background-color: ${eventSeverityColor[detection.eventSeverity]}`">
|
||||
</span>
|
||||
<span class="detection-event-severity-block">{{ detection.securityType || '-' }}</span>
|
||||
<!-- <span class="detection-event-severity-block">{{ detection.securityType || '-' }}</span>-->
|
||||
<span class="detection-event-severity-block">{{ detection.eventType || '-' }}</span>
|
||||
<i class="cn-icon cn-icon-attacker" ></i>{{detection.offenderIp || '-'}}
|
||||
<div v-if="detection.domain" class="domain">{{detection.domain}}</div>
|
||||
<span class="line">-------</span>
|
||||
@@ -30,31 +31,31 @@
|
||||
<div class="cn-detection__body">
|
||||
<div class="body__basic-info">
|
||||
<div class="basic-info">
|
||||
<div class="basic-info__item" v-if="detection.eventSecurity">
|
||||
<div class="basic-info__item" v-if="detection.severity">
|
||||
<i class="cn-icon cn-icon-severity-level"></i>
|
||||
<span>{{$t('detection.list.security')}} : </span>
|
||||
<span>{{detection.eventSecurity || '-'}}</span>
|
||||
<span>{{detection.severity || '-'}}</span>
|
||||
</div>
|
||||
<div class="basic-info__item" v-if="detection.eventSeverity">
|
||||
<i class="cn-icon cn-icon-severity-level"></i>
|
||||
<span>{{$t('detections.severity')}} : </span>
|
||||
<span>{{detection.eventSeverity || '-'}}</span>
|
||||
</div>
|
||||
<div class="basic-info__item" v-if="detection.eventType">
|
||||
<i class="cn-icon cn-icon-event-type"></i>
|
||||
<span>{{$t('detections.eventType')}} : </span>
|
||||
<span>{{detection.eventType || '-'}}</span>
|
||||
</div>
|
||||
<div class="basic-info__item" v-if="detection.malwareName">
|
||||
<!-- <div class="basic-info__item" v-if="detection.eventType">-->
|
||||
<!-- <i class="cn-icon cn-icon-event-type"></i>-->
|
||||
<!-- <span>{{$t('detections.eventType')}} : </span>-->
|
||||
<!-- <span>{{detection.eventType || '-'}}</span>-->
|
||||
<!-- </div>-->
|
||||
<div class="basic-info__item" v-if="detection.eventName">
|
||||
<i class="cn-icon cn-icon-trojan"></i>
|
||||
<span>{{$t('detection.list.malwareName')}} : </span>
|
||||
<span>{{detection.malwareName || '-'}}</span>
|
||||
</div>
|
||||
<div class="basic-info__item" v-if="detection.cryptominingPool">
|
||||
<i class="cn-icon cn-icon-mining-pool"></i>
|
||||
<span>{{$t('detection.list.cryptominingPool')}} : </span>
|
||||
<span>{{detection.cryptominingPool || '-'}}</span>
|
||||
<span>{{ $_.get(detection, 'malwareName', '-') || '-' }}</span>
|
||||
</div>
|
||||
<!-- <div class="basic-info__item" v-if="detection.cryptominingPool">-->
|
||||
<!-- <i class="cn-icon cn-icon-mining-pool"></i>-->
|
||||
<!-- <span>{{$t('detection.list.cryptominingPool')}} : </span>-->
|
||||
<!-- <span>{{detection.cryptominingPool || '-'}}</span>-->
|
||||
<!-- </div>-->
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-time2"></i>
|
||||
<span>{{$t('detection.list.startTime')}} : </span>
|
||||
@@ -63,9 +64,11 @@
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-duration"></i>
|
||||
<span>{{$t('overall.duration')}} : </span>
|
||||
<span style="display: inline-block;height: 6px;width: 6px;border-radius: 50%;margin-right: 8px;"
|
||||
:style="pointColor(detection)"></span>
|
||||
<span>{{unitConvert(detection.durationMs, 'time', null, null, 0).join(' ') || '-'}}</span>
|
||||
<span>
|
||||
{{ detection.matchTimes || '-'}} {{ $t('detection.list.times') }} /
|
||||
{{unitConvert(detection.durationS, 'time', 's', null, 0).join(' ') || '-'}}
|
||||
</span>
|
||||
<div v-if="parseInt(detection.status)===0" class="margin-l-10 detection-row-active">Active</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,7 +111,7 @@
|
||||
|
||||
<script>
|
||||
import { eventSeverityColor, detectionPageType, entityType } from '@/utils/constants'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import { getMillisecond, dateFormatByAppearance } from '@/utils/date-util'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import DetectionSecurityEventOverview from '@/views/detections/overview/DetectionSecurityEventOverview'
|
||||
import DetectionPerformanceEventIpOverview from '@/views/detections/overview/DetectionPerformanceEventIpOverview'
|
||||
@@ -177,6 +180,7 @@ export default {
|
||||
methods: {
|
||||
unitConvert,
|
||||
getMillisecond,
|
||||
dateFormatByAppearance,
|
||||
/* 切换折叠状态 */
|
||||
switchCollapse () {
|
||||
this.isCollapse = !this.isCollapse
|
||||
@@ -235,3 +239,17 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.detection-row-active {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
padding: 0 7px;
|
||||
background: #E9EFE1;
|
||||
border-radius: 2px;
|
||||
font-family: NotoSansHans-Medium;
|
||||
font-size: 12px;
|
||||
color: #7E9F54;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
<advanced-search
|
||||
ref="search"
|
||||
:column-list="columnList[pageType]"
|
||||
:operator-list="operatorList"
|
||||
:connection-list="connectionList"
|
||||
:full-text="false"
|
||||
class="advanced-search--show-list"
|
||||
:full-text="true"
|
||||
:show-list="showList"
|
||||
@search="search"
|
||||
></advanced-search>
|
||||
</div>
|
||||
<div class="search-symbol-inline">
|
||||
<i class="cn-icon cn-icon-help"></i>
|
||||
</div>
|
||||
<!-- <div class="search-symbol-inline">-->
|
||||
<!-- <i class="cn-icon cn-icon-help"></i>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,6 +22,7 @@
|
||||
<script>
|
||||
import AdvancedSearch from '@/components/advancedSearch/Index'
|
||||
import { humpToLine } from '@/utils/tools'
|
||||
import { schemaDetectionSecurity } from '@/utils/static-data'
|
||||
export default {
|
||||
name: 'DetectionSearch',
|
||||
props: {
|
||||
@@ -33,74 +34,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
columnList: {
|
||||
securityEvent: [
|
||||
{
|
||||
name: 'event_severity',
|
||||
type: 'string',
|
||||
// label: 'Event severity',
|
||||
label: 'event_severity',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'security_type',
|
||||
type: 'string',
|
||||
// label: 'Security type',
|
||||
label: 'security_type',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'victim_ip',
|
||||
type: 'string',
|
||||
// label: 'Victim IP'
|
||||
label: 'victim_ip',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'victim_location_country',
|
||||
type: 'string',
|
||||
// label: 'Victim location'
|
||||
label: 'victim_location_country',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'offender_ip',
|
||||
type: 'string',
|
||||
// label: 'Offender IP'
|
||||
label: 'offender_ip',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'offender_location_country',
|
||||
type: 'string',
|
||||
// label: 'Offender location'
|
||||
label: 'offender_location_country',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
securityEvent: schemaDetectionSecurity,
|
||||
performanceEvent: [
|
||||
{
|
||||
name: 'event_severity',
|
||||
@@ -113,17 +47,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'event_type',
|
||||
type: 'string',
|
||||
// label: 'Event type'
|
||||
label: 'event_type',
|
||||
doc: {
|
||||
constraints: {
|
||||
operator_functions: '=,in'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'app_name',
|
||||
type: 'string',
|
||||
@@ -169,7 +92,8 @@ export default {
|
||||
value: 'OR',
|
||||
label: 'OR'
|
||||
}
|
||||
]
|
||||
],
|
||||
showList: true
|
||||
}
|
||||
},
|
||||
emits: ['search'],
|
||||
|
||||
@@ -54,39 +54,36 @@
|
||||
<div class="detection__list-statistics detection-border">
|
||||
<div class="statistics__severity">
|
||||
<div class="chart-header">
|
||||
<div class="chart-header__title">{{$t('detection.severity')}}</div>
|
||||
<div class="chart-header__title">{{$t('detections.severity')}}</div>
|
||||
</div>
|
||||
<template v-if="isStatisticsSeverityNoData">
|
||||
<div class="no-data chart-content" >{{ $t('npm.noData') }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="chart-content" :id="`eventSeverityPie${pageType}`">
|
||||
</div>
|
||||
<div class="chart-content" :id="`eventSeverityPie${pageType}`"></div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<div class="statistics__category">
|
||||
<div class="chart-header">
|
||||
<div class="chart-header__title">{{$t('detection.categoryProportion')}}</div>
|
||||
<div class="chart-header__title">{{$t('detections.eventType')}}</div>
|
||||
</div>
|
||||
<template v-if="isStatisticsCategoryNoData">
|
||||
<div class="no-data chart-content" >{{ $t('npm.noData') }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="chart-content" :id="`detectionCategoryPer${pageType}`">
|
||||
</div>
|
||||
<div class="chart-content" :id="`detectionCategoryPer${pageType}`"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="statistics__active-attack">
|
||||
<div class="chart-header">
|
||||
<div class="chart-header__title">{{pageType === detectionPageType.securityEvent ? $t('detection.activeAttacker') : $t('detections.activeEntity')}}</div>
|
||||
<div class="chart-header__title">{{pageType === detectionPageType.securityEvent ? $t('detection.activeOffender') : $t('detections.activeEntity')}}</div>
|
||||
</div>
|
||||
<template v-if="isStatisticsActiveAttackNoData">
|
||||
<div class="no-data chart-content" >{{ $t('npm.noData') }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="chart-content" style="padding-left: 5px;" :id="`detectionActiveAttacker${pageType}`">
|
||||
</div>
|
||||
<div class="chart-content" style="padding-left: 5px;" :id="`detectionActiveAttacker${pageType}`"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@@ -136,7 +133,7 @@ import {
|
||||
} from '@/views/detections/options/detectionOptions'
|
||||
import { api, getData } from '@/utils/api'
|
||||
import axios from 'axios'
|
||||
import { extensionEchartY, reverseSortBy } from '@/utils/tools'
|
||||
import { extensionEchartY, reverseSortBy, switchStatus } from '@/utils/tools'
|
||||
import { useRoute } from 'vue-router'
|
||||
import Loading from '@/components/common/Loading'
|
||||
import ChartTabs from '@/components/common/ChartTabs'
|
||||
@@ -160,18 +157,18 @@ export default {
|
||||
i18n: 'entities.securityEvents',
|
||||
path: '/detection/securityEvent',
|
||||
icon: 'cn-icon cn-icon-a-SecurityEvent'
|
||||
},
|
||||
}
|
||||
// {
|
||||
// i18n: 'entities.regulatoryRiskEvents',
|
||||
// path: '/detection/securityEvent',
|
||||
// icon: 'cn-icon cn-icon-a-RegulatoryRiskEvent',
|
||||
// disable: true
|
||||
// },
|
||||
{
|
||||
i18n: 'overall.performanceEvents',
|
||||
path: '/detection/performanceEvent',
|
||||
icon: 'cn-icon cn-icon-a-PerformanceEvent'
|
||||
}
|
||||
// {
|
||||
// i18n: 'overall.performanceEvents',
|
||||
// path: '/detection/performanceEvent',
|
||||
// icon: 'cn-icon cn-icon-a-PerformanceEvent'
|
||||
// }
|
||||
],
|
||||
chartInit: [],
|
||||
pageObj: {
|
||||
@@ -185,61 +182,73 @@ export default {
|
||||
filterData: {
|
||||
securityEvent: [
|
||||
{
|
||||
title: this.$t('detections.eventSeverity'),
|
||||
column: 'eventSeverity',
|
||||
title: this.$t('overall.status'),
|
||||
column: '',
|
||||
topColumn: '', // todo schema暂无标识
|
||||
collapse: false,
|
||||
value: [], // value之间是or的关系
|
||||
data: [] // 从接口动态获取,本项在获得数据后需要特殊处理左边框颜色
|
||||
},
|
||||
{
|
||||
title: this.$t('detections.securityType'),
|
||||
column: 'securityType',
|
||||
title: this.$t('detections.severity'),
|
||||
column: 'severity',
|
||||
topColumn: 'severity',
|
||||
collapse: false,
|
||||
value: [], // value之间是or的关系
|
||||
data: [] // 从接口动态获取,本项在获得数据后需要特殊处理左边框颜色
|
||||
},
|
||||
{
|
||||
title: this.$t('detections.eventType'),
|
||||
column: 'event_type',
|
||||
topColumn: 'event_type',
|
||||
collapse: false,
|
||||
value: [],
|
||||
data: [] // 从接口动态获取
|
||||
},
|
||||
{
|
||||
title: this.$t('detections.victimIp'),
|
||||
column: 'victimIp',
|
||||
column: 'victim_ip',
|
||||
topColumn: 'victim_ip',
|
||||
collapse: false,
|
||||
value: [],
|
||||
showMore: true,
|
||||
showIndex: 9,
|
||||
data: [] // 从接口动态获取
|
||||
},
|
||||
{
|
||||
title: this.$t('detections.victimLocation'),
|
||||
column: 'victimLocationCountry',
|
||||
collapse: false,
|
||||
value: [],
|
||||
showMore: false,
|
||||
showIndex: 9,
|
||||
data: [
|
||||
{
|
||||
label: 'China',
|
||||
value: 'china',
|
||||
count: 50
|
||||
}
|
||||
] // 从接口动态获取
|
||||
},
|
||||
// {
|
||||
// title: this.$t('detections.victimLocation'),
|
||||
// column: 'victimLocationCountry',
|
||||
// collapse: false,
|
||||
// value: [],
|
||||
// showMore: false,
|
||||
// showIndex: 9,
|
||||
// data: [
|
||||
// {
|
||||
// label: 'China',
|
||||
// value: 'china',
|
||||
// count: 50
|
||||
// }
|
||||
// ] // 从接口动态获取
|
||||
// },
|
||||
{
|
||||
title: this.$t('detections.offenderIp'),
|
||||
column: 'offenderIp',
|
||||
collapse: false,
|
||||
value: [],
|
||||
showMore: false,
|
||||
showIndex: 9,
|
||||
data: [] // 从接口动态获取
|
||||
},
|
||||
{
|
||||
title: this.$t('detections.offenderLocation'),
|
||||
column: 'offenderLocationCountry',
|
||||
column: 'offender_ip',
|
||||
topColumn: 'offender_ip',
|
||||
collapse: false,
|
||||
value: [],
|
||||
showMore: false,
|
||||
showIndex: 9,
|
||||
data: [] // 从接口动态获取
|
||||
}
|
||||
// {
|
||||
// title: this.$t('detections.offenderLocation'),
|
||||
// column: 'offenderLocationCountry',
|
||||
// collapse: false,
|
||||
// value: [],
|
||||
// showMore: false,
|
||||
// showIndex: 9,
|
||||
// data: [] // 从接口动态获取
|
||||
// }
|
||||
],
|
||||
performanceEvent: [
|
||||
{
|
||||
@@ -275,24 +284,31 @@ export default {
|
||||
isStatisticsCategoryNoData: false,
|
||||
isStatisticsActiveAttackNoData: false,
|
||||
loading: false,
|
||||
oldActiveEntitySearchValue: ''
|
||||
oldActiveEntitySearchValue: '',
|
||||
initFlag: true // 初始化标识,初始化时保证mounted执行
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化顶部大柱状图
|
||||
initStatusData (params) {
|
||||
getData(api.detection[this.pageType].statusStatistics, params).then(data => {
|
||||
this.filterData[this.pageType][0].data = data.map(r => ({ label: this.$t(switchStatus(r.status)), value: r.status, count: r.count }))
|
||||
})
|
||||
},
|
||||
/** 初始化顶部大柱状图 */
|
||||
initEventSeverityTrendData (params) {
|
||||
this.loading = true
|
||||
/* getData(api.detection[this.pageType].eventSeverityTrend, params).then(data => {
|
||||
// getData(api.detection[this.pageType].eventSeverityTrend, params).then(data => {
|
||||
getData(api.detection[this.pageType].timeDistribution, params).then(data => {
|
||||
this.eventSeverityData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
const dataMap = new Map()
|
||||
data.forEach(item => {
|
||||
if (item.eventSeverity) {
|
||||
if (!dataMap.has(item.eventSeverity)) {
|
||||
if (item.severity) {
|
||||
if (!dataMap.has(item.severity)) {
|
||||
const count = [[toTime(item.statTime), item.count]]
|
||||
dataMap.set(item.eventSeverity, count)
|
||||
dataMap.set(item.severity, count)
|
||||
} else {
|
||||
dataMap.get(item.eventSeverity).push([toTime(item.statTime), item.count])
|
||||
dataMap.get(item.severity).push([toTime(item.statTime), item.count])
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -354,26 +370,18 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}) */
|
||||
const timer = setTimeout(() => {
|
||||
this.loading = false
|
||||
this.isEventSeverityNoData = true
|
||||
this.isStatisticsCategoryNoData = true
|
||||
this.isStatisticsSeverityNoData = true
|
||||
this.isStatisticsActiveAttackNoData = true
|
||||
clearTimeout(timer)
|
||||
}, 150)
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化左侧事件严重等级和小饼图
|
||||
/** 初始化左侧事件严重等级和第一个小饼图 */
|
||||
initEventSeverityData (params) {
|
||||
getData(api.detection[this.pageType].eventSeverity, params).then(data => {
|
||||
// getData(api.detection[this.pageType].eventSeverity, params).then(data => {
|
||||
getData(api.detection[this.pageType].severityStatistics, params).then(data => {
|
||||
this.statisticsSeverityData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][0].data = data.map(r => ({ label: r.eventSeverity, value: r.eventSeverity, count: r.count }))
|
||||
this.filterData[this.pageType][1].data = data.map(r => ({ label: r.severity, value: r.severity, count: r.count }))
|
||||
const eventSeverityOption = this.$_.cloneDeep(pieForSeverity)
|
||||
eventSeverityOption.series[0].data = data.map(d => {
|
||||
return { value: d.count, name: d.eventSeverity, itemStyle: { color: getSeverityColor(d.eventSeverity) } }
|
||||
return { value: d.count, name: d.severity, itemStyle: { color: getSeverityColor(d.severity) } }
|
||||
})
|
||||
const chartDom = document.getElementById(`eventSeverityPie${this.pageType}`)
|
||||
let detectionChart = echarts.getInstanceByDom(chartDom)
|
||||
@@ -401,7 +409,7 @@ export default {
|
||||
getData(api.detection[this.pageType].eventType, params).then(data => {
|
||||
this.statisticsCategoryData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][1].data = data.map(r => ({
|
||||
this.filterData[this.pageType][2].data = data.map(r => ({
|
||||
label: r.eventType,
|
||||
value: r.eventType,
|
||||
count: r.count
|
||||
@@ -429,13 +437,15 @@ export default {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
/** 第二个饼图和左侧filter的eventType */
|
||||
initSecurityTypeData (params) {
|
||||
getData(api.detection[this.pageType].securityType, params).then(data => {
|
||||
// getData(api.detection[this.pageType].securityType, params).then(data => {
|
||||
getData(api.detection[this.pageType].eventTypeStatistics, params).then(data => {
|
||||
this.statisticsCategoryData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][1].data = data.map(r => ({
|
||||
label: r.securityType,
|
||||
value: r.securityType,
|
||||
this.filterData[this.pageType][2].data = data.map(r => ({
|
||||
label: r.eventType,
|
||||
value: r.eventType,
|
||||
count: r.count
|
||||
}))
|
||||
const chartDom = document.getElementById(`detectionCategoryPer${this.pageType}`)
|
||||
@@ -447,7 +457,7 @@ export default {
|
||||
this.chartInit.push(shallowRef(detectionChart))
|
||||
const securityTypeOption = this.$_.cloneDeep(pieForSeverity)
|
||||
securityTypeOption.series[0].data = data.map(d => {
|
||||
return { value: d.count, name: d.securityType, itemStyle: { color: getAttackColor(d.securityType) } }
|
||||
return { value: d.count, name: d.eventType, itemStyle: { color: getAttackColor(d.eventType) } }
|
||||
})
|
||||
detectionChart.setOption(securityTypeOption)
|
||||
|
||||
@@ -461,8 +471,10 @@ export default {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
/** 横向柱状图和左侧filter的offenderIp */
|
||||
initOffenderIpData (params) {
|
||||
getData(api.detection[this.pageType].offenderIp, params).then(data => {
|
||||
// getData(api.detection[this.pageType].offenderIp, params).then(data => {
|
||||
getData(api.detection[this.pageType].offenderIpStatistics, params).then(data => {
|
||||
this.statisticsActiveAttackData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][4].data = data.map(r => ({
|
||||
@@ -501,11 +513,12 @@ export default {
|
||||
},
|
||||
|
||||
initVictimIpData (params) {
|
||||
getData(api.detection[this.pageType].victimIp, params).then(data => {
|
||||
this.filterData[this.pageType][2].data = data.map(r => ({ label: r.victimIp, value: r.victimIp, count: r.count }))
|
||||
const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][2].data)
|
||||
this.filterData[this.pageType][2].showMore = showMore
|
||||
this.filterData[this.pageType][2].showIndex = showIndex
|
||||
// getData(api.detection[this.pageType].victimIp, params).then(data => {
|
||||
getData(api.detection[this.pageType].victimIpStatistics, params).then(data => {
|
||||
this.filterData[this.pageType][3].data = data.map(r => ({ label: r.victimIp, value: r.victimIp, count: r.count }))
|
||||
const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][3].data)
|
||||
this.filterData[this.pageType][3].showMore = showMore
|
||||
this.filterData[this.pageType][3].showIndex = showIndex
|
||||
}).catch(error => {
|
||||
console.log(error)
|
||||
})
|
||||
@@ -610,15 +623,15 @@ export default {
|
||||
showIndex: 9
|
||||
}
|
||||
},
|
||||
queryList () {
|
||||
queryList (q) {
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
q: this.q,
|
||||
resource: q,
|
||||
pageSize: this.pageObj.pageSize,
|
||||
pageNo: this.pageObj.pageNo
|
||||
}
|
||||
/* axios.get(api.detection[this.pageType].listBasic, { params }).then(response => {
|
||||
axios.get(api.detection[this.pageType].securityList, { params }).then(response => {
|
||||
if (response.status === 200) {
|
||||
this.listData = response.data.data.result
|
||||
} else {
|
||||
@@ -627,11 +640,12 @@ export default {
|
||||
this.$message.error(response.data.message)
|
||||
}
|
||||
})
|
||||
getData(api.detection[this.pageType].listCount, params).then(data => {
|
||||
// getData(api.detection[this.pageType].listCount, params).then(data => {
|
||||
getData(api.detection[this.pageType].securityCount, params).then(data => {
|
||||
this.pageObj.total = data
|
||||
}).catch(error => {
|
||||
console.log(error)
|
||||
}) */
|
||||
})
|
||||
},
|
||||
timeRefreshChange () {
|
||||
this.initNoData()
|
||||
@@ -674,8 +688,15 @@ export default {
|
||||
} else {
|
||||
this.pageObj.resetPageNo = true
|
||||
}
|
||||
this.queryFilter()
|
||||
this.queryList()
|
||||
// 参数q,避免切换页码时,地址栏参数q为空
|
||||
let urlQ = ''
|
||||
if (param.str) {
|
||||
urlQ = encodeURI(param.str)
|
||||
} else if (this.q) {
|
||||
urlQ = encodeURI(this.q)
|
||||
}
|
||||
this.queryFilter(urlQ)
|
||||
this.queryList(urlQ)
|
||||
},
|
||||
resetFilterData () {
|
||||
this.filterData.securityEvent.forEach(d => {
|
||||
@@ -685,22 +706,23 @@ export default {
|
||||
d.data = []
|
||||
})
|
||||
},
|
||||
queryFilter () {
|
||||
queryFilter (q) {
|
||||
this.resetFilterData()
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
q: this.q
|
||||
resource: q
|
||||
}
|
||||
this.listData = []
|
||||
this.initStatusData(params)
|
||||
this.initEventSeverityTrendData(params)
|
||||
// this.initEventSeverityData(params)
|
||||
this.initEventSeverityData(params)
|
||||
if (this.pageType === detectionPageType.securityEvent) {
|
||||
// this.initOffenderIpData(params)
|
||||
this.initOffenderIpData(params)
|
||||
// this.initOffenderLocationData(params)
|
||||
// this.initVictimIpData(params)
|
||||
this.initVictimIpData(params)
|
||||
// this.initVictimLocationData(params)
|
||||
// this.initSecurityTypeData(params)
|
||||
this.initSecurityTypeData(params)
|
||||
} else if (this.pageType === detectionPageType.performanceEvent) {
|
||||
// this.initActiveEntity(params)
|
||||
// this.initEventTypeData(params)
|
||||
@@ -713,7 +735,11 @@ export default {
|
||||
pageNo (val) {
|
||||
this.pageObj.pageNo = val || 1
|
||||
this.pageObj.resetPageNo = false
|
||||
this.search(this.metaList, this.q)
|
||||
// 初始化时,mounted和pageNo都会调用列表接口,且pageNo先执行,
|
||||
// 初始化保证mounted执行,后续pageNo变动则不影响接口调用
|
||||
if (!this.initFlag) {
|
||||
this.search(this.metaList, this.q)
|
||||
}
|
||||
},
|
||||
// 点击上一页箭头
|
||||
prev () {
|
||||
@@ -748,6 +774,7 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
this.queryFilter()
|
||||
this.initFlag = false
|
||||
this.queryList()
|
||||
this.debounceFunc = this.$_.debounce(this.resize, 300)
|
||||
window.addEventListener('resize', this.debounceFunc)
|
||||
|
||||
@@ -3,162 +3,148 @@
|
||||
<div class="overview__left">
|
||||
<div class="overview__title">{{ $t('overall.remark') }}</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__content">
|
||||
<template v-if="detection.securityType === 'command and control'">
|
||||
<div class="row__content1" v-if="basicInfo.malwareInfo">
|
||||
<template v-if="basicInfo.malwareInfo.threatType === 'command and control'">
|
||||
<span
|
||||
class="row__content--link"
|
||||
@click="goDetail('ip', detection.victimIp)"
|
||||
>{{ detection.victimIp }}</span>
|
||||
<span>
|
||||
{{$t('detection.commandAndControl')}}
|
||||
@click="goDetail('ip', detection.victimIp)">
|
||||
{{ detection.victimIp }}
|
||||
</span>
|
||||
<span>{{$t('detection.commandAndControl')}}</span>
|
||||
<span class="row__content--link" @click="goDetail('ip', detection.eventInfoObj.ioc_value)">
|
||||
{{ detection.eventInfoObj.ioc_value || '-' }}
|
||||
</span>
|
||||
<span class="row__content--link" @click="goDetail('ip', basicInfo.iocValue)">{{basicInfo.iocValue || '-'}}</span></template
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span
|
||||
class="row__content--link"
|
||||
@click="goDetail('ip', detection.victimIp)"
|
||||
>{{ detection.victimIp }}</span
|
||||
>
|
||||
<span>
|
||||
{{$t('detection.payloadAndDelivery')}}
|
||||
class="row__content--link"
|
||||
@click="goDetail('ip', detection.victimIp)">
|
||||
{{ detection.victimIp }}
|
||||
</span>
|
||||
<span>{{$t('detection.payloadAndDelivery')}}</span>
|
||||
<span
|
||||
class="row__content--link"
|
||||
@click="goDetail('ip', detection.eventInfoObj.ioc_value)">
|
||||
{{ detection.eventInfoObj.ioc_value }}
|
||||
</span>
|
||||
<span class="row__content--link"
|
||||
@click="goDetail('ip', basicInfo.iocValue)"
|
||||
>{{
|
||||
basicInfo.iocValue
|
||||
}}</span></template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__title">Fields</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detection.list.startTime') }}</div>
|
||||
<div class="row__content">
|
||||
{{
|
||||
basicInfo.startTime
|
||||
? dateFormatByAppearance(basicInfo.startTime)
|
||||
: '-'
|
||||
}}
|
||||
<i class="cn-icon cn-icon-time2 row__content__icon"></i>
|
||||
{{ detection.startTime ? dateFormatByAppearance(detection.startTime) : '-' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.victimIp') }}</div>
|
||||
<div class="row__content">{{ basicInfo.victimIp || '-' }}</div>
|
||||
<div class="row__content">{{ detection.victimIp || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.victimLocation') }}</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.victimLocationCountry || '-' }}
|
||||
</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'victimInfo.location.country', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.victimAsn') }}</div>
|
||||
<div class="row__content">{{ basicInfo.victimAsn || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'victimInfo.asn.asn', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.offenderIp') }}</div>
|
||||
<div class="row__content">{{ basicInfo.offenderIp || '-' }}</div>
|
||||
<div class="row__content">{{ detection.offenderIp || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.offenderLocation') }}</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.offenderLocationCountry || '-' }}
|
||||
</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'offenderInfo.location.country', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.offenderAsn') }}</div>
|
||||
<div class="row__content">{{ basicInfo.offenderAsn || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'offenderInfo.asn.asn', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('overall.domain') }}</div>
|
||||
<div class="row__content">{{ basicInfo.domain || '-' }}</div>
|
||||
<div class="row__content">{{ detection.domain || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('entities.domainCategory') }}</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.domainCategoryName || '-' }}
|
||||
</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'domainInfo.category.categoryName', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">
|
||||
{{ $t('entities.domainDetail.categoryGroup') }}
|
||||
</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.domainCategoryGroup || '-' }}
|
||||
</div>
|
||||
<div class="row__label">{{ $t('entities.domainDetail.categoryGroup') }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'domainInfo.category.categoryGroup', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('entities.reputationLevel') }}</div>
|
||||
<div class="row__content">
|
||||
<div class="row__content" v-if="$_.get(basicInfo, 'domainInfo.category.reputationLevel')">
|
||||
<div
|
||||
class="row__tag"
|
||||
:style="`background-color:${eventSeverityColor[basicInfo.domainReputationLevel]}`"
|
||||
>
|
||||
{{ basicInfo.domainReputationLevel || '-' }}
|
||||
class="row__tag row__tag__level"
|
||||
:style="`background-color:${eventSeverityColor[basicInfo.domainInfo.category.reputationLevel]}`">
|
||||
{{ basicInfo.domainInfo.category.reputationLevel }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row__content" v-else>-</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">APP</div>
|
||||
<div class="row__content">{{ basicInfo.appName || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'appInfo.category.appName', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">APP {{ $t('entities.category') }}</div>
|
||||
<div class="row__content">{{ basicInfo.appCategory || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'appInfo.category.appCategory', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">APP {{ $t('entities.subcategory') }}</div>
|
||||
<div class="row__content">{{ basicInfo.appSubcategory || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'appInfo.category.appSubcategory', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('overall.appRisk') }}</div>
|
||||
<div class="row__content">
|
||||
<div class="row__content" v-if="$_.get(basicInfo, 'appInfo.category.appRisk')">
|
||||
<div
|
||||
class="row__tag"
|
||||
:style="`background-color:${eventSeverityColor[basicInfo.appRisk]}`"
|
||||
>
|
||||
{{ basicInfo.appRisk || '-' }}
|
||||
class="row__tag row__tag__level"
|
||||
:style="`background-color:${eventSeverityColor[basicInfo.appInfo.category.appRisk]}`">
|
||||
{{ basicInfo.appInfo.category.appRisk }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row__content" v-else>-</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.malware') }}</div>
|
||||
<div class="row__content">{{ basicInfo.malwareName || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'malwareInfo.malwareName', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.malwareAlias') }}</div>
|
||||
<div class="row__content">{{ basicInfo.malwareAlias || '-' }}</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'malwareInfo.malwareAlias', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.malwareDescription') }}</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.malwareDescription || '-' }}
|
||||
</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'malwareInfo.mitreAttackDescription', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.malwarePlatforms') }}</div>
|
||||
<div class="row__content">{{ basicInfo.malwarePlatforms || '-' }}</div>
|
||||
<div class="row__content" v-if="$_.get(basicInfo, 'malwareInfo.mitreAttackPlatforms')">
|
||||
<svg class="icon item-popover-up row__content__svg" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-windows"></use>
|
||||
</svg>
|
||||
{{ basicInfo.malwareInfo.mitreAttackPlatforms }}
|
||||
</div>
|
||||
<div class="row__content" v-else>-</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.malwareTechniques') }}</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.malwareTechniques || '-' }}
|
||||
</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'malwareInfo.mitreAttackTechniques', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.malwareGroups') }}</div>
|
||||
<div class="row__content">
|
||||
{{ basicInfo.malwareGroups || '-' }}
|
||||
</div>
|
||||
<div class="row__content">{{ $_.get(basicInfo, 'malwareInfo.mitreAttackGroups', '-') || '-' }}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{ $t('detections.reference') }}</div>
|
||||
<div class="row__content row__content--link">
|
||||
{{ reference || '-' }}
|
||||
<div class="row__content row__content--link" v-if="$_.get(basicInfo, 'malwareInfo.reference')">
|
||||
{{ basicInfo.malwareInfo.reference }}
|
||||
</div>
|
||||
<div class="row__content">-</div>
|
||||
</div>
|
||||
<!-- <template v-if="detection.securityType === 'command and control' || detection.securityType === 'payload_delivery'">
|
||||
</template>-->
|
||||
</div>
|
||||
<div class="overview__right">
|
||||
<div class="overview__title">{{ $t('detections.goToVictim') }}</div>
|
||||
@@ -167,7 +153,7 @@
|
||||
<span class="row__content--span">{{ $t('detections.viewDetailOf') }}</span>
|
||||
<span
|
||||
class="row__content--link"
|
||||
@click="goDetail('ip', basicInfo.victimIp)">{{ basicInfo.victimIp }}</span>
|
||||
@click="goDetail('ip', detection.victimIp)">{{ detection.victimIp }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__title">{{ $t('detections.goToOffender') }}</div>
|
||||
@@ -176,22 +162,22 @@
|
||||
<span class="row__content--span">{{ $t('detections.viewDetailOf') }}</span>
|
||||
<span
|
||||
class="row__content--link"
|
||||
@click="goDetail('ip', basicInfo.offenderIp)"
|
||||
>{{ basicInfo.offenderIp }}</span
|
||||
@click="goDetail('ip', detection.offenderIp)"
|
||||
>{{ detection.offenderIp }}</span
|
||||
>
|
||||
<span
|
||||
class="row__content--link"
|
||||
@click="goDetail('domain', basicInfo.domain)"
|
||||
>{{ basicInfo.domain }}</span
|
||||
@click="goDetail('domain', detection.domain)"
|
||||
>{{ detection.domain }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__title">{{ $t('detections.goToHunt') }}</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__content row__content--link">
|
||||
{{ $t('detections.viewAllRelated') }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="overview__title">{{ $t('detections.goToHunt') }}</div>-->
|
||||
<!-- <div class="overview__row">-->
|
||||
<!-- <div class="row__content row__content--link">-->
|
||||
<!-- {{ $t('detections.viewAllRelated') }}-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="overview__title">
|
||||
{{ $t('detections.relatedDetections') }}
|
||||
</div>
|
||||
@@ -221,18 +207,12 @@
|
||||
<div class="timeline__severity timeline__severity--high">
|
||||
<i
|
||||
class="cn-icon cn-icon-alert-level"
|
||||
:style="`color:${eventSeverityColor[event.eventSeverity]}`"
|
||||
:style="`color:${eventSeverityColor[event.severity]}`"
|
||||
></i>
|
||||
<span>{{ event.eventSeverity }}</span>
|
||||
</div>
|
||||
<div class="timeline__security-type">
|
||||
{{ event.securityType }}
|
||||
</div>
|
||||
<div class="timeline__start-time">
|
||||
{{
|
||||
dateFormatByAppearance(event.startTime)
|
||||
}}
|
||||
<span>{{ event.severity }}</span>
|
||||
</div>
|
||||
<div class="timeline__security-type">{{ event.eventType }}</div>
|
||||
<div class="timeline__start-time">{{ dateFormatByAppearance(event.startTime) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-timeline__foot">
|
||||
@@ -240,7 +220,7 @@
|
||||
class="detection-ip"
|
||||
:class="{
|
||||
'detection-ip__current':
|
||||
[basicInfo.offenderIp, basicInfo.victimIp].indexOf(
|
||||
[detection.offenderIp, detection.victimIp].indexOf(
|
||||
event.offenderIp,
|
||||
) > -1,
|
||||
}"
|
||||
@@ -252,7 +232,7 @@
|
||||
class="detection-ip"
|
||||
:class="{
|
||||
'detection-ip__current':
|
||||
[basicInfo.offenderIp, basicInfo.victimIp].indexOf(
|
||||
[detection.offenderIp, detection.victimIp].indexOf(
|
||||
event.victimIp,
|
||||
) > -1,
|
||||
}"
|
||||
@@ -270,7 +250,7 @@
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import { api } from '@/utils/api'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import { getMillisecond, dateFormatByAppearance } from '@/utils/date-util'
|
||||
import { eventSeverityColor, unitTypes } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import _ from 'lodash'
|
||||
@@ -291,25 +271,15 @@ export default {
|
||||
formatT0 () {
|
||||
const vm = this
|
||||
return function (event) {
|
||||
const diffSeconds = event.diffSeconds
|
||||
const diffSeconds = this.detection.startTime - event.startTime
|
||||
if (diffSeconds === 0) {
|
||||
return 'T0'
|
||||
}
|
||||
const eventStartTime = event.startTime
|
||||
const entityStartTime = vm.detection.startTime
|
||||
|
||||
if (
|
||||
_.isNumber(diffSeconds) &&
|
||||
_.isNumber(eventStartTime) &&
|
||||
_.isNumber(entityStartTime)
|
||||
) {
|
||||
const suffix = unitConvert(
|
||||
diffSeconds,
|
||||
unitTypes.time,
|
||||
's',
|
||||
null,
|
||||
0
|
||||
).join('')
|
||||
if (_.isNumber(diffSeconds) && _.isNumber(eventStartTime) && _.isNumber(entityStartTime)) {
|
||||
const suffix = unitConvert(diffSeconds, unitTypes.time, 's', null, 0).join('')
|
||||
if (eventStartTime > entityStartTime) {
|
||||
return `T0+${suffix}`
|
||||
} else if (eventStartTime < entityStartTime) {
|
||||
@@ -322,58 +292,70 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getMillisecond,
|
||||
query () {
|
||||
Promise.all([this.queryBasic(), this.queryEvent()]).then((responses) => {
|
||||
responses[0].malwareTechniques = responses[0].malwareTechniques.length > 2 ? responses[0].malwareTechniques.replace('[', '').replace(']', '').split(',', 5).join(', ') : ''
|
||||
responses[0].malwareGroups = responses[0].malwareGroups.length > 2 ? responses[0].malwareGroups.replace('[', '').replace(']', '').split(',', 5).join(', ') : ''
|
||||
responses[0].malwarePlatforms = responses[0].malwarePlatforms.length > 1 ? responses[0].malwarePlatforms : ''
|
||||
responses[0].malwareDescription = responses[0].malwareDescription.length > 1 ? responses[0].malwareDescription : ''
|
||||
responses[0] && (this.basicInfo = responses[0])
|
||||
responses[1] &&
|
||||
(this.events = responses[1].sort(
|
||||
(e1, e2) => e1.startTime - e2.startTime
|
||||
))
|
||||
})
|
||||
},
|
||||
queryBasic () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
axios.get(api.detection.securityEvent.overviewBasic, {
|
||||
params: {
|
||||
eventId: this.detection.eventId,
|
||||
startTime: this.detection.startTime,
|
||||
endTime: this.detection.endTime
|
||||
dateFormatByAppearance,
|
||||
/** 初始化实体详情 */
|
||||
initEntityDetail () {
|
||||
// 为完整填充IP信息,攻击者ip、受害者ip都进行调用;
|
||||
// 根据detection的eventInfo对象的ioc_type进行判断,若为domain,malware信息从domain详情中获取,并填充domain信息
|
||||
// 若ioc_type为ip,则调用ip接口,填充malware信息
|
||||
// 最后调用app,填充app信息。经上获取完整实体详情则最少需要调用4次接口
|
||||
const offenderIPDetail = axios.get(`${api.detection.securityEvent.ipDetail}/resource=${this.detection.offenderIp}`)
|
||||
const victimIPDetail = axios.get(`${api.detection.securityEvent.ipDetail}/resource=${this.detection.victimIp}`)
|
||||
let ipDetail
|
||||
let domainDetail
|
||||
let promiseList = []
|
||||
const appDetail = axios.get(`${api.detection.securityEvent.appDetail}/resource=${this.detection.app}`)
|
||||
if (this.detection.eventInfoObj.ioc_type.toLowerCase() === 'domain') {
|
||||
domainDetail = axios.get(`${api.detection.securityEvent.domainDetail}/resource=${this.detection.eventInfoObj.ioc_value}`)
|
||||
promiseList = [offenderIPDetail, victimIPDetail, domainDetail, appDetail]
|
||||
}
|
||||
if (this.detection.eventInfoObj.ioc_type.toLowerCase() === 'ip') {
|
||||
ipDetail = axios.get(`${api.detection.securityEvent.ipDetail}/resource=${this.detection.eventInfoObj.ioc_value}`)
|
||||
domainDetail = axios.get(`${api.detection.securityEvent.domainDetail}/resource=${this.detection.domain}`)
|
||||
promiseList = [offenderIPDetail, victimIPDetail, domainDetail, appDetail, ipDetail]
|
||||
}
|
||||
|
||||
Promise.all(promiseList).then((responses) => {
|
||||
responses.forEach((res, i) => {
|
||||
if (res.status === 200) {
|
||||
if (i === 0) {
|
||||
this.basicInfo.offenderInfo = res.data.data
|
||||
}
|
||||
}).then((response) => {
|
||||
if (response.status === 200) {
|
||||
resolve(response.data.data.result[0])
|
||||
} else {
|
||||
reject(response.data)
|
||||
if (i === 1) {
|
||||
this.basicInfo.victimInfo = res.data.data
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
if (i === 2) {
|
||||
this.basicInfo.domainInfo = res.data.data
|
||||
}
|
||||
if (i === 3) {
|
||||
this.basicInfo.appInfo = res.data.data
|
||||
}
|
||||
if (i === 4) {
|
||||
this.basicInfo.malwareInfo = res.data.data.malwareInfo
|
||||
}
|
||||
} else {
|
||||
console.error(res)
|
||||
}
|
||||
})
|
||||
if (this.detection.eventInfoObj.ioc_type.toLowerCase() === 'domain') {
|
||||
this.basicInfo.malwareInfo = this.basicInfo.domainInfo.malware || {}
|
||||
}
|
||||
})
|
||||
},
|
||||
queryEvent () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
axios.get(api.detection.securityEvent.overviewEvent, {
|
||||
params: {
|
||||
startTime: this.detection.startTime,
|
||||
offenderIp: this.detection.offenderIp,
|
||||
victimIp: this.detection.victimIp
|
||||
}
|
||||
}).then((response) => {
|
||||
if (response.status === 200) {
|
||||
resolve(response.data.data.result)
|
||||
} else {
|
||||
reject(response.data)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
axios.get(api.detection.securityEvent.relationEvent, {
|
||||
params: {
|
||||
// startTime: this.detection.startTime,
|
||||
unbiasedTime: this.detection.startTime,
|
||||
offenderIp: this.detection.offenderIp,
|
||||
victimIp: this.detection.victimIp,
|
||||
biasSecond: 3600
|
||||
}
|
||||
}).then((response) => {
|
||||
if (response.status === 200) {
|
||||
this.events = response.data.data.result.sort((e1, e2) => e1.startTime - e2.startTime)
|
||||
} else {
|
||||
this.events = []
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -391,7 +373,17 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.query()
|
||||
this.initEntityDetail()
|
||||
this.queryEvent()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.row__label {
|
||||
width: 176px;
|
||||
}
|
||||
.row__content {
|
||||
width: calc(100% - 176px);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user