forked from p15670423/monkey
Refactoring T1197 to display time and use tables
This commit is contained in:
parent
8ee7a06769
commit
1eac9856c4
|
@ -9,5 +9,5 @@ class ScanStatus(Enum):
|
|||
# Technique was attempted and succeeded
|
||||
USED = 2
|
||||
|
||||
|
||||
BITS_UPLOAD_STRING = {"usage": "Bits job was used to upload monkey to a remote system."}
|
||||
# Dict that describes what BITS job was used for
|
||||
BITS_UPLOAD_STRING = {"usage": "BITS job was used to upload monkey to a remote system."}
|
||||
|
|
|
@ -3,6 +3,7 @@ import requests
|
|||
import json
|
||||
from infection_monkey.control import ControlClient
|
||||
import logging
|
||||
import datetime
|
||||
|
||||
__author__ = "VakarisZ"
|
||||
|
||||
|
@ -20,7 +21,7 @@ class AttackTelem(object):
|
|||
"""
|
||||
self.technique = technique
|
||||
self.result = status
|
||||
self.data = {'status': status, 'id': GUID}
|
||||
self.data = {'status': status, 'id': GUID, 'time': AttackTelem.get_current_time_string()}
|
||||
if data:
|
||||
self.data.update(data)
|
||||
|
||||
|
@ -39,3 +40,13 @@ class AttackTelem(object):
|
|||
except Exception as exc:
|
||||
LOG.warn("Error connecting to control server %s: %s",
|
||||
WormConfiguration.current_server, exc)
|
||||
|
||||
@staticmethod
|
||||
def get_current_time_string():
|
||||
time = datetime.datetime.now()
|
||||
return "%s-%s-%s %s:%s:%s" % (time.date().year,
|
||||
time.date().month,
|
||||
time.date().day,
|
||||
time.time().hour,
|
||||
time.time().minute,
|
||||
time.time().second)
|
||||
|
|
|
@ -14,5 +14,5 @@ class VictimHostTelem(AttackTelem):
|
|||
:param data: Other data relevant to the attack technique
|
||||
"""
|
||||
super(VictimHostTelem, self).__init__(technique, status, data)
|
||||
victim_host = {'hostname': machine.domain_name, 'ip': machine.ip_addr}
|
||||
victim_host = {'domain_name': machine.domain_name, 'ip_addr': machine.ip_addr}
|
||||
self.data.update({'machine': victim_host})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logging
|
||||
from cc.services.attack.technique_reports import T1210
|
||||
from cc.services.attack.technique_reports import T1210, T1197
|
||||
from cc.services.attack.attack_telem import get_latest_telem
|
||||
from cc.services.attack.attack_config import get_technique_values
|
||||
from cc.database import mongo
|
||||
|
@ -9,7 +9,8 @@ __author__ = "VakarisZ"
|
|||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
TECHNIQUES = {'T1210': T1210}
|
||||
TECHNIQUES = {'T1210': T1210,
|
||||
'T1197': T1197}
|
||||
|
||||
REPORT_NAME = 'new_report'
|
||||
|
||||
|
@ -44,7 +45,7 @@ class AttackReportService:
|
|||
if AttackReportService.is_report_generated():
|
||||
telem_time = get_latest_telem()
|
||||
latest_report = mongo.db.attack_report.find_one({'name': REPORT_NAME})
|
||||
if telem_time and telem_time['timestamp'] == latest_report['meta']['timestamp']:
|
||||
if telem_time and latest_report['meta'] and telem_time['time'] == latest_report['meta']['time']:
|
||||
return latest_report
|
||||
return AttackReportService.generate_new_report()
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ SCHEMA = {
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"T1197": {
|
||||
"title": "T1197 Bits jobs",
|
||||
"title": "T1197 BITS jobs",
|
||||
"type": "bool",
|
||||
"value": True,
|
||||
"necessary": True,
|
||||
|
|
|
@ -18,7 +18,7 @@ def set_results(technique, data):
|
|||
"""
|
||||
data.update({'technique': technique})
|
||||
mongo.db.attack_results.insert(data)
|
||||
mongo.db.attack_results.update({'name': 'latest'}, {'name': 'latest', 'timestamp': time()}, upsert=True)
|
||||
mongo.db.attack_results.update({'name': 'latest'}, {'name': 'latest', 'time': data['time']}, upsert=True)
|
||||
|
||||
|
||||
def get_latest_telem():
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from monkey_island.cc.services.attack.technique_reports.technique_service import *
|
||||
from cc.services.report import ReportService
|
||||
from cc.database import mongo
|
||||
|
||||
__author__ = "VakarisZ"
|
||||
|
||||
|
@ -13,6 +13,13 @@ MESSAGES = {
|
|||
|
||||
def get_report_data():
|
||||
data = get_tech_base_data(TECHNIQUE, MESSAGES)
|
||||
|
||||
data.update()
|
||||
bits_results = mongo.db.attack_results.aggregate([{'$match': {'technique': TECHNIQUE}},
|
||||
{'$group': {'_id': {'ip_addr': '$machine.ip_addr', 'usage': '$usage'},
|
||||
'ip_addr': {'$first': '$machine.ip_addr'},
|
||||
'domain_name': {'$first': '$machine.domain_name'},
|
||||
'usage': {'$first': '$usage'},
|
||||
'time': {'$first': '$time'}}
|
||||
}])
|
||||
bits_results = list(bits_results)
|
||||
data.update({'bits_jobs': bits_results})
|
||||
return data
|
||||
|
|
|
@ -6,6 +6,11 @@ __author__ = "VakarisZ"
|
|||
|
||||
|
||||
def technique_status(technique):
|
||||
"""
|
||||
Gets status of certain attack technique. If
|
||||
:param technique:
|
||||
:return:
|
||||
"""
|
||||
if mongo.db.attack_results.find_one({'status': ScanStatus.USED.value, 'technique': technique}):
|
||||
return ScanStatus.USED
|
||||
elif mongo.db.attack_results.find_one({'status': ScanStatus.SCANNED.value, 'technique': technique}):
|
||||
|
|
|
@ -1,60 +1,43 @@
|
|||
import React from 'react';
|
||||
import '../../styles/Collapse.scss'
|
||||
import {Link} from "react-router-dom";
|
||||
import ReactTable from "react-table";
|
||||
|
||||
let renderArray = function(val) {
|
||||
return <span>{val.map(x => <span key={x.toString()}>{x} </span>)}</span>;
|
||||
};
|
||||
|
||||
|
||||
let renderMachine = function (val, index, exploited=false) {
|
||||
let renderMachine = function (val) {
|
||||
return (
|
||||
<div key={index}>
|
||||
{renderArray(val.ip_addresses)}
|
||||
{(val.domain_name ? " (".concat(val.domain_name, ")") : " (".concat(val.label, ")"))} :
|
||||
{exploited ? renderArray(val.exploits) : renderArray(val.services)}
|
||||
</div>
|
||||
<span>{val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")}</span>
|
||||
)
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
columns: [
|
||||
{Header: 'Machine', id: 'machine', accessor: x => renderMachine(x), style: { 'whiteSpace': 'unset' }, width: 200},
|
||||
{Header: 'Time', id: 'time', accessor: x => x.time, style: { 'whiteSpace': 'unset' }, width: 170},
|
||||
{Header: 'Usage', id: 'usage', accessor: x => x.usage, style: { 'whiteSpace': 'unset' }}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
class T1210 extends React.Component {
|
||||
|
||||
renderScannedMachines = (machines) => {
|
||||
let content = [];
|
||||
for (let i = 0; i < machines.length; i++ ){
|
||||
if (machines[i].services.length !== 0){
|
||||
content.push(renderMachine(machines[i], i))
|
||||
}
|
||||
}
|
||||
return <div>{content}</div>;
|
||||
};
|
||||
|
||||
renderExploitedMachines = (machines) => {
|
||||
let content = [];
|
||||
for (let i = 0; i < machines.length; i++ ){
|
||||
if (machines[i].exploits.length !== 0){
|
||||
content.push(renderMachine(machines[i], i, true))
|
||||
}
|
||||
}
|
||||
return <div>{content}</div>;
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log(this.props);
|
||||
return (
|
||||
<div>
|
||||
<div>{this.props.data.message}</div>
|
||||
<div>Found services: </div>
|
||||
{this.renderScannedMachines(this.props.data.scanned_machines)}
|
||||
<div>Successful exploiters:</div>
|
||||
{this.renderExploitedMachines(this.props.data.exploited_machines)}
|
||||
<div className="attack-report footer-text">
|
||||
To get more info about scanned and exploited machines view <Link to="/report">standard report.</Link>
|
||||
<div className="data-table-container">
|
||||
<div>
|
||||
<div>{this.props.data.message}</div>
|
||||
{this.props.data.bits_jobs.length > 0 ? <div>BITS jobs were used in these machines: </div> : ''}
|
||||
</div>
|
||||
<br/>
|
||||
<ReactTable
|
||||
columns={columns}
|
||||
data={this.props.data.bits_jobs}
|
||||
showPagination={false}
|
||||
defaultPageSize={this.props.data.bits_jobs.length}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ class T1210 extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
console.log(this.props);
|
||||
return (
|
||||
<div>
|
||||
<div>{this.props.data.message}</div>
|
||||
|
|
|
@ -5,10 +5,12 @@ import {edgeGroupToColor, options} from 'components/map/MapOptions';
|
|||
import AuthComponent from '../AuthComponent';
|
||||
import Collapse from '@kunukn/react-collapse';
|
||||
import T1210 from '../attack/T1210';
|
||||
import T1197 from '../attack/T1197';
|
||||
import '../../styles/Collapse.scss'
|
||||
|
||||
const tech_components = {
|
||||
'T1210': T1210
|
||||
'T1210': T1210,
|
||||
'T1197': T1197
|
||||
};
|
||||
|
||||
const classNames = require('classnames');
|
||||
|
@ -21,7 +23,7 @@ class AttackReportPageComponent extends AuthComponent {
|
|||
report: false,
|
||||
allMonkeysAreDead: false,
|
||||
runStarted: true,
|
||||
index: 1
|
||||
collapseOpen: ''
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -54,8 +56,8 @@ class AttackReportPageComponent extends AuthComponent {
|
|||
}
|
||||
}
|
||||
|
||||
onToggle = index =>
|
||||
this.setState(state => ({ index: state.index === index ? null : index }));
|
||||
onToggle = technique =>
|
||||
this.setState(state => ({ collapseOpen: state.collapseOpen === technique ? null : technique }));
|
||||
|
||||
getTechniqueCollapse(tech_id){
|
||||
switch (this.state.report[tech_id].status) {
|
||||
|
@ -70,21 +72,21 @@ class AttackReportPageComponent extends AuthComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={classNames("collapse-item", { "item--active": this.state.index === 1 })}>
|
||||
<button className={classNames("btn-collapse", className)} onClick={() => this.onToggle(1)}>
|
||||
<div key={tech_id} className={classNames("collapse-item", { "item--active": this.state.collapseOpen === tech_id })}>
|
||||
<button className={classNames("btn-collapse", className)} onClick={() => this.onToggle(tech_id)}>
|
||||
<span>{this.state.report[tech_id].title}</span>
|
||||
<span>
|
||||
<i className={classNames("fa", this.state.index === 1 ? "fa-chevron-down" : "fa-chevron-up")}></i>
|
||||
<i className={classNames("fa", this.state.collapseOpen === tech_id ? "fa-chevron-down" : "fa-chevron-up")}></i>
|
||||
</span>
|
||||
</button>
|
||||
<Collapse
|
||||
className="collapse-comp"
|
||||
isOpen={this.state.index === 1}
|
||||
isOpen={this.state.collapseOpen === tech_id}
|
||||
onChange={({ collapseState }) => {
|
||||
this.setState({ item1: collapseState });
|
||||
this.setState({ tech_id: collapseState });
|
||||
}}
|
||||
onInit={({ collapseState }) => {
|
||||
this.setState({ item1: collapseState });
|
||||
this.setState({ tech_id: collapseState });
|
||||
}}
|
||||
render={collapseState => this.createTechniqueContent(collapseState, tech_id)}/>
|
||||
</div>
|
||||
|
@ -101,9 +103,10 @@ class AttackReportPageComponent extends AuthComponent {
|
|||
}
|
||||
|
||||
generateReportContent(){
|
||||
let content = '';
|
||||
let content = [];
|
||||
console.log(this.state.report);
|
||||
Object.keys(this.state.report).forEach((tech_id) => {
|
||||
content = this.getTechniqueCollapse(tech_id)
|
||||
content.push(this.getTechniqueCollapse(tech_id))
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
|
|
Loading…
Reference in New Issue