Refactored AttackTechnique methods to use @classmethod and minor improvenets in UI
This commit is contained in:
parent
676eca6f87
commit
8505ad0ca8
|
@ -16,7 +16,7 @@ class T1075(AttackTechnique):
|
|||
{'lm_hash': {'$ne': ''}}]}}}
|
||||
|
||||
# Gets data about successful PTH logins
|
||||
query = [{'$match': {'telem_type': 'exploit',
|
||||
query = [{'$match': {'telem_category': 'exploit',
|
||||
'data.attempts': {'$not': {'$size': 0},
|
||||
'$elemMatch': {'$and': [{'$or': [{'ntlm_hash': {'$ne': ''}},
|
||||
{'lm_hash': {'$ne': ''}}]},
|
||||
|
@ -35,9 +35,9 @@ class T1075(AttackTechnique):
|
|||
successful_logins = list(mongo.db.telemetry.aggregate(T1075.query))
|
||||
data.update({'successful_logins': successful_logins})
|
||||
if successful_logins:
|
||||
data.update({'message': T1075.used_msg, 'status': ScanStatus.USED.name})
|
||||
data.update(T1075.get_message_and_status(ScanStatus.USED))
|
||||
elif mongo.db.telemetry.count_documents(T1075.login_attempt_query):
|
||||
data.update({'message': T1075.scanned_msg, 'status': ScanStatus.SCANNED.name})
|
||||
data.update(T1075.get_message_and_status(ScanStatus.SCANNED))
|
||||
else:
|
||||
data.update({'message': T1075.unscanned_msg, 'status': ScanStatus.UNSCANNED.name})
|
||||
data.update(T1075.get_message_and_status(ScanStatus.UNSCANNED))
|
||||
return data
|
||||
|
|
|
@ -35,11 +35,11 @@ class T1110(AttackTechnique):
|
|||
result['successful_creds'].append(T1110.parse_creds(attempt))
|
||||
|
||||
if succeeded:
|
||||
data = T1110.get_message_and_status(T1110, ScanStatus.USED)
|
||||
data = T1110.get_message_and_status(ScanStatus.USED)
|
||||
elif attempts:
|
||||
data = T1110.get_message_and_status(T1110, ScanStatus.SCANNED)
|
||||
data = T1110.get_message_and_status(ScanStatus.SCANNED)
|
||||
else:
|
||||
data = T1110.get_message_and_status(T1110, ScanStatus.UNSCANNED)
|
||||
data = T1110.get_message_and_status(ScanStatus.UNSCANNED)
|
||||
|
||||
# Remove data with no successful brute force attempts
|
||||
attempts = [attempt for attempt in attempts if attempt['attempts']]
|
||||
|
|
|
@ -12,7 +12,7 @@ class T1197(AttackTechnique):
|
|||
|
||||
@staticmethod
|
||||
def get_report_data():
|
||||
data = T1197.get_tech_base_data(T1197)
|
||||
data = T1197.get_tech_base_data()
|
||||
bits_results = mongo.db.attack_results.aggregate([{'$match': {'technique': T1197.tech_id}},
|
||||
{'$group': {'_id': {'ip_addr': '$machine.ip_addr', 'usage': '$usage'},
|
||||
'ip_addr': {'$first': '$machine.ip_addr'},
|
||||
|
|
|
@ -47,51 +47,60 @@ class AttackTechnique(object):
|
|||
pass
|
||||
|
||||
@staticmethod
|
||||
def technique_status(technique):
|
||||
def technique_status(tech_id):
|
||||
"""
|
||||
Gets the status of a certain attack technique.
|
||||
:param technique: technique's id.
|
||||
:param tech_id: ID of attack technique, for e.g. T1110
|
||||
:return: ScanStatus Enum object
|
||||
"""
|
||||
if mongo.db.attack_results.find_one({'status': ScanStatus.USED.value, 'technique': technique}):
|
||||
if mongo.db.attack_results.find_one({'status': ScanStatus.USED.value, 'technique': tech_id}):
|
||||
return ScanStatus.USED
|
||||
elif mongo.db.attack_results.find_one({'status': ScanStatus.SCANNED.value, 'technique': technique}):
|
||||
elif mongo.db.attack_results.find_one({'status': ScanStatus.SCANNED.value, 'technique': tech_id}):
|
||||
return ScanStatus.SCANNED
|
||||
else:
|
||||
return ScanStatus.UNSCANNED
|
||||
|
||||
@staticmethod
|
||||
def get_message_and_status(technique, status):
|
||||
return {'message': technique.get_message_by_status(technique, status), 'status': status.name}
|
||||
|
||||
@staticmethod
|
||||
def get_message_by_status(technique, status):
|
||||
if status == ScanStatus.UNSCANNED:
|
||||
return technique.unscanned_msg
|
||||
elif status == ScanStatus.SCANNED:
|
||||
return technique.scanned_msg
|
||||
else:
|
||||
return technique.used_msg
|
||||
|
||||
@staticmethod
|
||||
def technique_title(technique):
|
||||
@classmethod
|
||||
def get_message_and_status(cls, status):
|
||||
"""
|
||||
:param technique: Technique's id. E.g. T1110
|
||||
Returns a dict with attack technique's message and status.
|
||||
:param status: Enum type value from common/attack_utils.py
|
||||
:return: Dict with message and status
|
||||
"""
|
||||
return {'message': cls.get_message_by_status(status), 'status': status.name}
|
||||
|
||||
@classmethod
|
||||
def get_message_by_status(cls, status):
|
||||
"""
|
||||
Picks a message to return based on status.
|
||||
:param status: Enum type value from common/attack_utils.py
|
||||
:return: message string
|
||||
"""
|
||||
if status == ScanStatus.UNSCANNED:
|
||||
return cls.unscanned_msg
|
||||
elif status == ScanStatus.SCANNED:
|
||||
return cls.scanned_msg
|
||||
else:
|
||||
return cls.used_msg
|
||||
|
||||
@staticmethod
|
||||
def technique_title(tech_id):
|
||||
"""
|
||||
:param tech_id: Technique's id. E.g. T1110
|
||||
:return: techniques title. E.g. "T1110 Brute force"
|
||||
"""
|
||||
return AttackConfig.get_technique(technique)['title']
|
||||
return AttackConfig.get_technique(tech_id)['title']
|
||||
|
||||
@staticmethod
|
||||
def get_tech_base_data(technique):
|
||||
@classmethod
|
||||
def get_tech_base_data(cls):
|
||||
"""
|
||||
Gathers basic attack technique data into a dict.
|
||||
:param technique: Technique's id. E.g. T1110
|
||||
:return: dict E.g. {'message': 'Brute force used', 'status': 'Used', 'title': 'T1110 Brute force'}
|
||||
"""
|
||||
data = {}
|
||||
status = AttackTechnique.technique_status(technique.tech_id)
|
||||
title = AttackTechnique.technique_title(technique.tech_id)
|
||||
status = AttackTechnique.technique_status(cls.tech_id)
|
||||
title = AttackTechnique.technique_title(cls.tech_id)
|
||||
data.update({'status': status.name,
|
||||
'title': title,
|
||||
'message': technique.get_message_by_status(technique, status)})
|
||||
'message': cls.get_message_by_status(status)})
|
||||
return data
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
|
||||
export function RenderMachine(val){
|
||||
export function renderMachine(val){
|
||||
return (
|
||||
<span>{val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")}</span>
|
||||
)
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
import React from 'react';
|
||||
import '../../../styles/Collapse.scss'
|
||||
import ReactTable from "react-table";
|
||||
import { RenderMachine } from "./Helpers"
|
||||
import { renderMachine } from "./Helpers"
|
||||
|
||||
|
||||
class T1075 extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props.data.successful_logins.forEach((login) => {
|
||||
if(login.attempts[0].ntlm_hash !== ""){
|
||||
login.attempts[0].hashType = 'NTLM';
|
||||
} else if(login.attempts[0].lm_hash !== ""){
|
||||
login.attempts[0].hashType = 'LM';
|
||||
}
|
||||
})
|
||||
this.props.data.successful_logins.forEach((login) => this.setLoginHashType(login))
|
||||
}
|
||||
|
||||
setLoginHashType(login){
|
||||
if(login.attempts[0].ntlm_hash !== ""){
|
||||
login.attempts[0].hashType = 'NTLM';
|
||||
} else if(login.attempts[0].lm_hash !== ""){
|
||||
login.attempts[0].hashType = 'LM';
|
||||
}
|
||||
}
|
||||
|
||||
static getHashColumns() {
|
||||
return ([{
|
||||
columns: [
|
||||
{Header: 'Machine', id: 'machine', accessor: x => RenderMachine(x.machine), style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine), style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Username', id: 'attempts', accessor: x => x.attempts[0].user, style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Hash type', id: 'credentials', accessor: x => x.attempts[0].hashType, style: { 'whiteSpace': 'unset' }},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import '../../../styles/Collapse.scss'
|
||||
import ReactTable from "react-table";
|
||||
import { RenderMachine } from "./Helpers"
|
||||
import { renderMachine } from "./Helpers"
|
||||
|
||||
|
||||
class T1110 extends React.Component {
|
||||
|
@ -13,7 +13,7 @@ class T1110 extends React.Component {
|
|||
static getServiceColumns() {
|
||||
return ([{
|
||||
columns: [
|
||||
{Header: 'Machine', id: 'machine', accessor: x => RenderMachine(x.machine),
|
||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
||||
style: { 'whiteSpace': 'unset' }, width: 160},
|
||||
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }, width: 100},
|
||||
{Header: 'Started', id: 'started', accessor: x => x.info.started, style: { 'whiteSpace': 'unset' }},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import '../../../styles/Collapse.scss'
|
||||
import ReactTable from "react-table";
|
||||
import { RenderMachine } from "./Helpers"
|
||||
import { renderMachine } from "./Helpers"
|
||||
|
||||
|
||||
class T1210 extends React.Component {
|
||||
|
@ -9,7 +9,7 @@ class T1210 extends React.Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
this.columns = [ {Header: 'Machine',
|
||||
id: 'machine', accessor: x => RenderMachine(x),
|
||||
id: 'machine', accessor: x => renderMachine(x),
|
||||
style: { 'whiteSpace': 'unset' },
|
||||
width: 200},
|
||||
{Header: 'Time',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import '../../../styles/Collapse.scss'
|
||||
import ReactTable from "react-table";
|
||||
import { RenderMachine } from "./Helpers"
|
||||
import { renderMachine } from "./Helpers"
|
||||
|
||||
|
||||
class T1210 extends React.Component {
|
||||
|
@ -13,7 +13,7 @@ class T1210 extends React.Component {
|
|||
static getScanColumns() {
|
||||
return ([{
|
||||
columns: [
|
||||
{Header: 'Machine', id: 'machine', accessor: x => RenderMachine(x.machine),
|
||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
||||
style: { 'whiteSpace': 'unset' }, width: 200},
|
||||
{Header: 'Time', id: 'time', accessor: x => x.time, style: { 'whiteSpace': 'unset' }, width: 170},
|
||||
{Header: 'Port', id: 'port', accessor: x =>x.service.port, style: { 'whiteSpace': 'unset' }},
|
||||
|
@ -24,7 +24,7 @@ class T1210 extends React.Component {
|
|||
static getExploitColumns() {
|
||||
return ([{
|
||||
columns: [
|
||||
{Header: 'Machine', id: 'machine', accessor: x => RenderMachine(x.machine),
|
||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine),
|
||||
style: { 'whiteSpace': 'unset' }, width: 200},
|
||||
{Header: 'Time', id: 'time', accessor: x => x.time, style: { 'whiteSpace': 'unset' }, width: 170},
|
||||
{Header: 'Port/url', id: 'port', accessor: x =>this.renderEndpoint(x.service), style: { 'whiteSpace': 'unset' }},
|
||||
|
|
Loading…
Reference in New Issue