Merge branch 'develop' into attack_configuration

# Conflicts:
#	monkey/monkey_island/cc/app.py
#	monkey/monkey_island/cc/resources/root.py
#	monkey/monkey_island/requirements.txt
This commit is contained in:
VakarisZ 2019-04-15 13:02:01 +03:00
commit af3e1713b2
70 changed files with 2412 additions and 170 deletions

12
.gitignore vendored
View File

@ -71,3 +71,15 @@ bin
# User files
/monkey/monkey_island/cc/userUploads
# MonkeyZoo
# Network status files
MonkeyZoo/*
# Except
!MonkeyZoo/main.tf
!MonkeyZoo/variables.tf
!MonkeyZoo/README.MD
!MonkeyZoo/config.tf
!MonkeyZoo/MonkeyZooDocs.pdf

View File

@ -0,0 +1,3 @@
# MonkeyZoo
These files are used to deploy Infection Monkey's test network on GCP.<br>
For more information view docs/fullDocs.md

View File

@ -0,0 +1,206 @@
{
"basic": {
"credentials": {
"exploit_password_list": [
"`))jU7L(w}",
"3Q=(Ge(+&w]*",
"^NgDvY59~8",
"Ivrrw5zEzs",
"YbS,<tpS.2av"
],
"exploit_user_list": [
"m0nk3y"
]
}
},
"basic_network": {
"general": {
"blocked_ips": [],
"depth": 2,
"local_network_scan": false,
"subnet_scan_list": [
"10.2.2.2",
"10.2.2.3",
"10.2.2.4",
"10.2.2.5",
"10.2.2.8",
"10.2.2.9",
"10.2.1.9",
"10.2.1.10",
"10.2.2.11",
"10.2.2.12",
"10.2.2.14",
"10.2.2.15",
"10.2.2.16",
"10.2.2.18",
"10.2.2.19",
"10.2.2.20",
"10.2.2.21",
"10.2.2.23",
"10.2.2.24"
]
},
"network_analysis": {
"inaccessible_subnets": []
}
},
"cnc": {
"servers": {
"command_servers": [
"192.168.56.1:5000",
"158.129.18.132:5000"
],
"current_server": "192.168.56.1:5000",
"internet_services": [
"monkey.guardicore.com",
"www.google.com"
]
}
},
"exploits": {
"general": {
"exploiter_classes": [
"SmbExploiter",
"WmiExploiter",
"RdpExploiter",
"ShellShockExploiter",
"SambaCryExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter",
"WebLogicExploiter",
"HadoopExploiter"
],
"skip_exploit_if_file_exist": false
},
"ms08_067": {
"ms08_067_exploit_attempts": 5,
"ms08_067_remote_user_add": "Monkey_IUSER_SUPPORT",
"ms08_067_remote_user_pass": "Password1!",
"remote_user_pass": "Password1!",
"user_to_add": "Monkey_IUSER_SUPPORT"
},
"rdp_grinder": {
"rdp_use_vbs_download": true
},
"sambacry": {
"sambacry_folder_paths_to_guess": [
"/",
"/mnt",
"/tmp",
"/storage",
"/export",
"/share",
"/shares",
"/home"
],
"sambacry_shares_not_to_check": [
"IPC$",
"print$"
],
"sambacry_trigger_timeout": 5
},
"smb_service": {
"smb_download_timeout": 300,
"smb_service_name": "InfectionMonkey"
}
},
"internal": {
"classes": {
"finger_classes": [
"SMBFinger",
"SSHFinger",
"PingScanner",
"HTTPFinger",
"MySQLFinger",
"MSSQLFinger",
"ElasticFinger"
],
"scanner_class": "TcpScanner"
},
"dropper": {
"dropper_date_reference_path_linux": "/bin/sh",
"dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll",
"dropper_set_date": true,
"dropper_target_path_linux": "/tmp/monkey",
"dropper_target_path_win_32": "C:\\Windows\\monkey32.exe",
"dropper_target_path_win_64": "C:\\Windows\\monkey64.exe",
"dropper_try_move_first": true
},
"exploits": {
"exploit_lm_hash_list": [],
"exploit_ntlm_hash_list": [],
"exploit_ssh_keys": []
},
"general": {
"keep_tunnel_open_time": 60,
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
},
"kill_file": {
"kill_file_path_linux": "/var/run/monkey.not",
"kill_file_path_windows": "%windir%\\monkey.not"
},
"logging": {
"dropper_log_path_linux": "/tmp/user-1562",
"dropper_log_path_windows": "%temp%\\~df1562.tmp",
"monkey_log_path_linux": "/tmp/user-1563",
"monkey_log_path_windows": "%temp%\\~df1563.tmp",
"send_log_to_server": true
}
},
"monkey": {
"behaviour": {
"self_delete_in_cleanup": false,
"serialize_config": false,
"use_file_logging": true
},
"general": {
"alive": true,
"post_breach_actions": [
"BackdoorUser"
]
},
"life_cycle": {
"max_iterations": 1,
"retry_failed_explotation": true,
"timeout_between_iterations": 100,
"victims_max_exploit": 30,
"victims_max_find": 30
},
"system_info": {
"collect_system_info": true,
"extract_azure_creds": true,
"should_use_mimikatz": true
}
},
"network": {
"ping_scanner": {
"ping_scan_timeout": 1000
},
"tcp_scanner": {
"HTTP_PORTS": [
80,
8080,
443,
8008,
7001
],
"tcp_scan_get_banner": true,
"tcp_scan_interval": 200,
"tcp_scan_timeout": 3000,
"tcp_target_ports": [
22,
2222,
445,
135,
3389,
80,
8080,
443,
8008,
3306,
9200,
7001
]
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

View File

@ -0,0 +1,10 @@
provider "google" {
project = "test-000000"
region = "europe-west3"
zone = "europe-west3-b"
credentials = "${file("testproject-000000-0c0b000b00c0.json")}"
}
locals {
service_account_email="tester-monkeyZoo-user@testproject-000000.iam.gserviceaccount.com"
monkeyzoo_project="guardicore-22050661"
}

View File

@ -0,0 +1,76 @@
resource "google_compute_firewall" "islands-in" {
name = "islands-in"
network = "${google_compute_network.monkeyzoo.name}"
allow {
protocol = "tcp"
ports = ["22", "443", "3389", "5000"]
}
direction = "INGRESS"
priority = "65534"
target_tags = ["island"]
}
resource "google_compute_firewall" "islands-out" {
name = "islands-out"
network = "${google_compute_network.monkeyzoo.name}"
allow {
protocol = "tcp"
}
direction = "EGRESS"
priority = "65534"
target_tags = ["island"]
}
resource "google_compute_firewall" "monkeyzoo-in" {
name = "monkeyzoo-in"
network = "${google_compute_network.monkeyzoo.name}"
allow {
protocol = "all"
}
direction = "INGRESS"
priority = "65534"
source_ranges = ["10.2.2.0/24"]
}
resource "google_compute_firewall" "monkeyzoo-out" {
name = "monkeyzoo-out"
network = "${google_compute_network.monkeyzoo.name}"
allow {
protocol = "all"
}
direction = "EGRESS"
priority = "65534"
destination_ranges = ["10.2.2.0/24"]
}
resource "google_compute_firewall" "tunneling-in" {
name = "tunneling-in"
network = "${google_compute_network.tunneling.name}"
allow {
protocol = "all"
}
direction = "INGRESS"
source_ranges = ["10.2.1.0/28"]
}
resource "google_compute_firewall" "tunneling-out" {
name = "tunneling-out"
network = "${google_compute_network.tunneling.name}"
allow {
protocol = "all"
}
direction = "EGRESS"
destination_ranges = ["10.2.1.0/28"]
}

View File

@ -0,0 +1,91 @@
//Custom cloud images
data "google_compute_image" "hadoop-2" {
name = "hadoop-2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "hadoop-3" {
name = "hadoop-3"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "elastic-4" {
name = "elastic-4"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "elastic-5" {
name = "elastic-5"
project = "${local.monkeyzoo_project}"
}
/*
data "google_compute_image" "sambacry-6" {
name = "sambacry-6"
}
*/
data "google_compute_image" "shellshock-8" {
name = "shellshock-8"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "tunneling-9" {
name = "tunneling-9-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "tunneling-10" {
name = "tunneling-10-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "sshkeys-11" {
name = "sshkeys-11-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "sshkeys-12" {
name = "sshkeys-12-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "mimikatz-14" {
name = "mimikatz-14-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "mimikatz-15" {
name = "mimikatz-15"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "mssql-16" {
name = "mssql-16"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "weblogic-18" {
name = "weblogic-18"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "weblogic-19" {
name = "weblogic-19-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "smb-20" {
name = "smb-20"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "scan-21" {
name = "scan-21"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "scan-22" {
name = "scan-22"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "struts2-23" {
name = "struts2-23"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "struts2-24" {
name = "struts-24-v2"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "island-linux-250" {
name = "island-linux-250"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "island-windows-251" {
name = "island-windows-251"
project = "${local.monkeyzoo_project}"
}

View File

@ -0,0 +1,431 @@
// Local variables
locals {
default_ubuntu="${google_compute_instance_template.ubuntu16.self_link}"
default_windows="${google_compute_instance_template.windows2016.self_link}"
}
resource "google_compute_network" "monkeyzoo" {
name = "monkeyzoo"
auto_create_subnetworks = false
}
resource "google_compute_network" "tunneling" {
name = "tunneling"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "monkeyzoo-main" {
name = "monkeyzoo-main"
ip_cidr_range = "10.2.2.0/24"
network = "${google_compute_network.monkeyzoo.self_link}"
}
resource "google_compute_subnetwork" "tunneling-main" {
name = "tunneling-main"
ip_cidr_range = "10.2.1.0/28"
network = "${google_compute_network.tunneling.self_link}"
}
resource "google_compute_instance_from_template" "hadoop-2" {
name = "hadoop-2"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.hadoop-2.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.2"
}
// Add required ssh keys for hadoop service and restart it
metadata_startup_script = "[ ! -f /home/vakaris_zilius/.ssh/authorized_keys ] && sudo cat /home/vakaris_zilius/.ssh/id_rsa.pub >> /home/vakaris_zilius/.ssh/authorized_keys && sudo reboot"
}
resource "google_compute_instance_from_template" "hadoop-3" {
name = "hadoop-3"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.hadoop-3.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.3"
}
}
resource "google_compute_instance_from_template" "elastic-4" {
name = "elastic-4"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.elastic-4.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.4"
}
}
resource "google_compute_instance_from_template" "elastic-5" {
name = "elastic-5"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.elastic-5.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.5"
}
}
/* Couldn't find ubuntu packages for required samba version (too old).
resource "google_compute_instance_from_template" "sambacry-6" {
name = "sambacry-6"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.sambacry-6.self_link}"
}
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.6"
}
}
*/
/* We need custom 32 bit Ubuntu machine for this (there are no 32 bit ubuntu machines in GCP).
resource "google_compute_instance_from_template" "sambacry-7" {
name = "sambacry-7"
source_instance_template = "${local.default_ubuntu}"
boot_disk {
initialize_params {
// Add custom image to cloud
image = "ubuntu32"
}
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.7"
}
}
*/
resource "google_compute_instance_from_template" "shellshock-8" {
name = "shellshock-8"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.shellshock-8.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.8"
}
}
resource "google_compute_instance_from_template" "tunneling-9" {
name = "tunneling-9"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.tunneling-9.self_link}"
}
auto_delete = true
}
network_interface{
subnetwork="tunneling-main"
network_ip="10.2.1.9"
}
network_interface{
subnetwork="monkeyzoo-main"
network_ip="10.2.2.9"
}
}
resource "google_compute_instance_from_template" "tunneling-10" {
name = "tunneling-10"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.tunneling-10.self_link}"
}
auto_delete = true
}
network_interface{
subnetwork="tunneling-main"
network_ip="10.2.1.10"
}
}
resource "google_compute_instance_from_template" "sshkeys-11" {
name = "sshkeys-11"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.sshkeys-11.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.11"
}
}
resource "google_compute_instance_from_template" "sshkeys-12" {
name = "sshkeys-12"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.sshkeys-12.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.12"
}
}
/*
resource "google_compute_instance_from_template" "rdpgrinder-13" {
name = "rdpgrinder-13"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.rdpgrinder-13.self_link}"
}
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.13"
}
}
*/
resource "google_compute_instance_from_template" "mimikatz-14" {
name = "mimikatz-14"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.mimikatz-14.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.14"
}
}
resource "google_compute_instance_from_template" "mimikatz-15" {
name = "mimikatz-15"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.mimikatz-15.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.15"
}
}
resource "google_compute_instance_from_template" "mssql-16" {
name = "mssql-16"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.mssql-16.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.16"
}
}
/* We need to alter monkey's behavior for this to upload 32-bit monkey instead of 64-bit (not yet developed)
resource "google_compute_instance_from_template" "upgrader-17" {
name = "upgrader-17"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.upgrader-17.self_link}"
}
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.17"
access_config {
// Cheaper, non-premium routing
network_tier = "STANDARD"
}
}
}
*/
resource "google_compute_instance_from_template" "weblogic-18" {
name = "weblogic-18"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.weblogic-18.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.18"
}
}
resource "google_compute_instance_from_template" "weblogic-19" {
name = "weblogic-19"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.weblogic-19.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.19"
}
}
resource "google_compute_instance_from_template" "smb-20" {
name = "smb-20"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.smb-20.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.20"
}
}
resource "google_compute_instance_from_template" "scan-21" {
name = "scan-21"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.scan-21.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.21"
}
}
resource "google_compute_instance_from_template" "scan-22" {
name = "scan-22"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.scan-22.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.22"
}
}
resource "google_compute_instance_from_template" "struts2-23" {
name = "struts2-23"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.struts2-23.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.23"
}
}
resource "google_compute_instance_from_template" "struts2-24" {
name = "struts2-24"
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.struts2-24.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.24"
}
}
resource "google_compute_instance_from_template" "island-linux-250" {
name = "island-linux-250"
machine_type = "n1-standard-2"
tags = ["island", "linux", "ubuntu16"]
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.island-linux-250.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.250"
access_config {
// Cheaper, non-premium routing (not available in some regions)
// network_tier = "STANDARD"
}
}
}
resource "google_compute_instance_from_template" "island-windows-251" {
name = "island-windows-251"
machine_type = "n1-standard-2"
tags = ["island", "windows", "windowsserver2016"]
source_instance_template = "${local.default_windows}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.island-windows-251.self_link}"
}
auto_delete = true
}
network_interface {
subnetwork="monkeyzoo-main"
network_ip="10.2.2.251"
access_config {
// Cheaper, non-premium routing (not available in some regions)
// network_tier = "STANDARD"
}
}
}

View File

@ -0,0 +1,45 @@
resource "google_compute_instance_template" "ubuntu16" {
name = "ubuntu16"
description = "Creates ubuntu 16.04 LTS servers at europe-west3-a."
tags = ["test-machine", "ubuntu16", "linux"]
machine_type = "n1-standard-1"
can_ip_forward = false
disk {
source_image = "ubuntu-os-cloud/ubuntu-1604-lts"
}
network_interface {
subnetwork="monkeyzoo-main"
access_config {
// Cheaper, non-premium routing
network_tier = "STANDARD"
}
}
service_account {
email ="${local.service_account_email}"
scopes=["cloud-platform"]
}
}
resource "google_compute_instance_template" "windows2016" {
name = "windows2016"
description = "Creates windows 2016 core servers at europe-west3-a."
tags = ["test-machine", "windowsserver2016", "windows"]
machine_type = "n1-standard-1"
can_ip_forward = false
disk {
source_image = "windows-cloud/windows-2016"
}
network_interface {
subnetwork="monkeyzoo-main"
}
service_account {
email="${local.service_account_email}"
scopes=["cloud-platform"]
}
}

View File

@ -0,0 +1,10 @@
from enum import Enum
class ScanStatus(Enum):
# Technique wasn't scanned
UNSCANNED = 0
# Technique was attempted/scanned
SCANNED = 1
# Technique was attempted and succeeded
USED = 2

View File

@ -28,6 +28,9 @@
"dropper_target_path_win_64": "C:\\Windows\\monkey64.exe",
"dropper_target_path_linux": "/tmp/monkey",
monkey_dir_linux = '/tmp/monkey_dir',
monkey_dir_windows = r'C:\Windows\Temp\monkey_dir',
"kill_file_path_linux": "/var/run/monkey.not",
"kill_file_path_windows": "%windir%\\monkey.not",
@ -98,4 +101,8 @@
"victims_max_exploit": 7,
"victims_max_find": 30,
"post_breach_actions" : []
custom_PBA_linux_cmd = ""
custom_PBA_windows_cmd = ""
PBA_linux_filename = None
PBA_windows_filename = None
}

View File

@ -8,7 +8,8 @@ import json
import logging
import requests
from infection_monkey.exploit.web_rce import WebRCE
from infection_monkey.model import WGET_HTTP_UPLOAD, RDP_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX
from infection_monkey.model import WGET_HTTP_UPLOAD, RDP_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX,\
DOWNLOAD_TIMEOUT
from infection_monkey.network.elasticfinger import ES_PORT, ES_SERVICE
import re
@ -47,7 +48,11 @@ class ElasticGroovyExploiter(WebRCE):
def exploit(self, url, command):
command = re.sub(r"\\", r"\\\\\\\\", command)
payload = self.JAVA_CMD % command
response = requests.get(url, data=payload)
try:
response = requests.get(url, data=payload, timeout=DOWNLOAD_TIMEOUT)
except requests.ReadTimeout:
LOG.error("Elastic couldn't upload monkey, because server didn't respond to upload request.")
return False
result = self.get_results(response)
if not result:
return False
@ -79,4 +84,4 @@ class ElasticGroovyExploiter(WebRCE):
return False
except Exception as e:
LOG.error("Host's exploitability check failed due to: %s" % e)
return False
return False

View File

@ -7,7 +7,6 @@ import socket
import struct
import sys
import urllib
from difflib import get_close_matches
from impacket.dcerpc.v5 import transport, srvs
from impacket.dcerpc.v5.dcom import wmi
@ -19,7 +18,6 @@ from impacket.smbconnection import SMBConnection, SMB_DIALECT
import infection_monkey.config
import infection_monkey.monkeyfs as monkeyfs
from infection_monkey.network import local_ips
from infection_monkey.network.firewall import app as firewall
from infection_monkey.network.info import get_free_tcp_port, get_routes
from infection_monkey.transport import HTTPServer, LockedHTTPServer
@ -418,9 +416,15 @@ class HTTPTools(object):
def get_interface_to_target(dst):
if sys.platform == "win32":
ips = local_ips()
matches = get_close_matches(dst, ips)
return matches[0] if (len(matches) > 0) else ips[0]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect((dst, 1))
ip_to_dst = s.getsockname()[0]
except KeyError:
ip_to_dst = '127.0.0.1'
finally:
s.close()
return ip_to_dst
else:
# based on scapy implementation
@ -430,17 +434,17 @@ def get_interface_to_target(dst):
routes = get_routes()
dst = atol(dst)
pathes = []
paths = []
for d, m, gw, i, a in routes:
aa = atol(a)
if aa == dst:
pathes.append((0xffffffff, ("lo", a, "0.0.0.0")))
paths.append((0xffffffff, ("lo", a, "0.0.0.0")))
if (dst & m) == (d & m):
pathes.append((m, (i, a, gw)))
if not pathes:
paths.append((m, (i, a, gw)))
if not paths:
return None
pathes.sort()
ret = pathes[-1][1]
paths.sort()
ret = paths[-1][1]
return ret[1]

View File

@ -17,6 +17,8 @@ from infection_monkey.system_info import SystemInfoCollector
from infection_monkey.system_singleton import SystemSingleton
from infection_monkey.windows_upgrader import WindowsUpgrader
from infection_monkey.post_breach.post_breach_handler import PostBreach
from common.utils.attack_status_enum import ScanStatus
from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem
__author__ = 'itamar'
@ -179,9 +181,11 @@ class InfectionMonkey(object):
for exploiter in [exploiter(machine) for exploiter in self._exploiters]:
if self.try_exploiting(machine, exploiter):
host_exploited = True
VictimHostTelem('T1210', ScanStatus.USED.value, machine=machine).send()
break
if not host_exploited:
self._fail_exploitation_machines.add(machine)
VictimHostTelem('T1210', ScanStatus.SCANNED.value, machine=machine).send()
if not self._keep_running:
break

View File

@ -12,6 +12,7 @@ __author__ = 'VakarisZ'
DIR_CHANGE_WINDOWS = 'cd %s & '
DIR_CHANGE_LINUX = 'cd %s ; '
class PostBreach(object):
"""
This class handles post breach actions execution

View File

@ -72,8 +72,7 @@ b. Download our pre-built sambacry binaries
-- Mimikatz --
Mimikatz is required for the Monkey to be able to steal credentials on Windows. It's possible to either compile from sources (requires Visual Studio 2013 and up) or download the binaries from
You can either build them yourself or download pre-built binaries.
Mimikatz is required for the Monkey to be able to steal credentials on Windows. It's possible to either compile binaries from source (requires Visual Studio 2013 and up) or download them from our repository.
a. Build Mimikatz yourself
a.0. Building mimikatz requires Visual Studio 2013 and up
a.1. Clone our version of mimikatz from https://github.com/guardicore/mimikatz/tree/1.1.0
@ -84,7 +83,7 @@ a. Build Mimikatz yourself
a.3.3. The zip file should be named mk32.zip/mk64.zip accordingly.
a.3.4. Zipping with 7zip has been tested. Other zipping software may not work.
b. Download our pre-built traceroute binaries
b. Download our pre-built mimikatz binaries
b.1. Download both 32 and 64 bit zipped DLLs from https://github.com/guardicore/mimikatz/releases/tag/1.1.0
b.2. Place them under [code location]\infection_monkey\bin

View File

@ -0,0 +1 @@
__author__ = 'VakarisZ'

View File

@ -0,0 +1,41 @@
from infection_monkey.config import WormConfiguration, GUID
import requests
import json
from infection_monkey.control import ControlClient
import logging
__author__ = "VakarisZ"
LOG = logging.getLogger(__name__)
class AttackTelem(object):
def __init__(self, technique, status, data=None):
"""
Default ATT&CK telemetry constructor
:param technique: Technique ID. E.g. T111
:param status: int from ScanStatus Enum
:param data: Other data relevant to the attack technique
"""
self.technique = technique
self.result = status
self.data = {'status': status, 'id': GUID}
if data:
self.data.update(data)
def send(self):
"""
Sends telemetry to island
"""
if not WormConfiguration.current_server:
return
try:
requests.post("https://%s/api/attack/%s" % (WormConfiguration.current_server, self.technique),
data=json.dumps(self.data),
headers={'content-type': 'application/json'},
verify=False,
proxies=ControlClient.proxies)
except Exception as exc:
LOG.warn("Error connecting to control server %s: %s",
WormConfiguration.current_server, exc)

View File

@ -0,0 +1,18 @@
from infection_monkey.transport.attack_telems.base_telem import AttackTelem
__author__ = "VakarisZ"
class VictimHostTelem(AttackTelem):
def __init__(self, technique, status, machine, data=None):
"""
ATT&CK telemetry that parses and sends VictimHost's (remote machine's) data
:param technique: Technique ID. E.g. T111
:param status: int from ScanStatus Enum
:param machine: VictimHost obj from model/host.py
: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}
self.data.update({'machine': victim_host})

View File

@ -8,29 +8,31 @@ from bson.json_util import dumps
from flask import Flask, send_from_directory, make_response, Response
from werkzeug.exceptions import NotFound
from cc.auth import init_jwt
from cc.database import mongo, database
from cc.environment.environment import env
from cc.resources.client_run import ClientRun
from cc.resources.edge import Edge
from cc.resources.local_run import LocalRun
from cc.resources.log import Log
from cc.resources.island_logs import IslandLog
from cc.resources.monkey import Monkey
from cc.resources.monkey_configuration import MonkeyConfiguration
from cc.resources.island_configuration import IslandConfiguration
from cc.resources.monkey_download import MonkeyDownload
from cc.resources.netmap import NetMap
from cc.resources.node import Node
from cc.resources.remote_run import RemoteRun
from cc.resources.report import Report
from cc.resources.root import Root
from cc.resources.telemetry import Telemetry
from cc.resources.telemetry_feed import TelemetryFeed
from cc.resources.pba_file_download import PBAFileDownload
from cc.resources.pba_file_upload import FileUpload
from cc.resources.attack_config import AttackConfiguration
from cc.services.config import ConfigService
from monkey_island.cc.auth import init_jwt
from monkey_island.cc.database import mongo, database
from monkey_island.cc.environment.environment import env
from monkey_island.cc.resources.client_run import ClientRun
from monkey_island.cc.resources.edge import Edge
from monkey_island.cc.resources.local_run import LocalRun
from monkey_island.cc.resources.log import Log
from monkey_island.cc.resources.island_logs import IslandLog
from monkey_island.cc.resources.monkey import Monkey
from monkey_island.cc.resources.monkey_configuration import MonkeyConfiguration
from monkey_island.cc.resources.island_configuration import IslandConfiguration
from monkey_island.cc.resources.monkey_download import MonkeyDownload
from monkey_island.cc.resources.netmap import NetMap
from monkey_island.cc.resources.node import Node
from monkey_island.cc.resources.remote_run import RemoteRun
from monkey_island.cc.resources.report import Report
from monkey_island.cc.resources.root import Root
from monkey_island.cc.resources.telemetry import Telemetry
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
from monkey_island.cc.resources.pba_file_download import PBAFileDownload
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
from monkey_island.cc.resources.pba_file_upload import FileUpload
from monkey_island.cc.resources.attack_telem import AttackTelem
from monkey_island.cc.resources.attack_config import AttackConfiguration
__author__ = 'Barak'
@ -42,7 +44,7 @@ def serve_static_file(static_path):
if static_path.startswith('api/'):
raise NotFound()
try:
return send_from_directory(os.path.join(os.getcwd(), 'monkey_island/cc/ui/dist'), static_path)
return send_from_directory(os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/ui/dist'), static_path)
except NotFound:
# Because react uses various urls for same index page, this is probably the user's intention.
if static_path == HOME_FILE:
@ -125,5 +127,6 @@ def init_app(mongo_url):
'/api/fileUpload/<string:file_type>?restore=<string:filename>')
api.add_resource(RemoteRun, '/api/remote-monkey', '/api/remote-monkey/')
api.add_resource(AttackConfiguration, '/api/attack')
api.add_resource(AttackTelem, '/api/attack/<string:technique>')
return app

View File

@ -4,7 +4,7 @@ from flask import current_app, abort
from flask_jwt import JWT, _jwt_required, JWTError
from werkzeug.security import safe_str_cmp
from cc.environment.environment import env
from monkey_island.cc.environment.environment import env
__author__ = 'itay.mizeretz'

View File

@ -0,0 +1,5 @@
import os
__author__ = 'itay.mizeretz'
MONKEY_ISLAND_ABS_PATH = os.path.join(os.getcwd(), 'monkey_island')

View File

@ -4,12 +4,14 @@ import os
from Crypto import Random
from Crypto.Cipher import AES
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
__author__ = "itay.mizeretz"
class Encryptor:
_BLOCK_SIZE = 32
_DB_PASSWORD_FILENAME = "monkey_island/cc/mongo_key.bin"
_DB_PASSWORD_FILENAME = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/mongo_key.bin')
def __init__(self):
self._load_key()

View File

@ -1,5 +1,5 @@
import cc.auth
from cc.environment import Environment
import monkey_island.cc.auth
from monkey_island.cc.environment import Environment
from common.cloud.aws_instance import AwsInstance
from Crypto.Hash import SHA3_512
@ -21,5 +21,5 @@ class AwsEnvironment(Environment):
def get_auth_users(self):
return [
cc.auth.User(1, 'monkey', self.hash_secret(self._instance_id))
monkey_island.cc.auth.User(1, 'monkey', self.hash_secret(self._instance_id))
]

View File

@ -1,9 +1,11 @@
import json
import logging
import os
from cc.environment import standard
from cc.environment import aws
from cc.environment import password
from monkey_island.cc.environment import standard
from monkey_island.cc.environment import aws
from monkey_island.cc.environment import password
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
__author__ = 'itay.mizeretz'
@ -21,7 +23,7 @@ ENV_DICT = {
def load_server_configuration_from_file():
with open('monkey_island/cc/server_config.json', 'r') as f:
with open(os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/server_config.json'), 'r') as f:
config_content = f.read()
return json.loads(config_content)

View File

@ -1,5 +1,5 @@
from cc.environment import Environment
import cc.auth
from monkey_island.cc.environment import Environment
import monkey_island.cc.auth
__author__ = 'itay.mizeretz'
@ -8,5 +8,5 @@ class PasswordEnvironment(Environment):
def get_auth_users(self):
return [
cc.auth.User(1, self.config['user'], self.config['hash'])
monkey_island.cc.auth.User(1, self.config['user'], self.config['hash'])
]

View File

@ -1,5 +1,5 @@
import cc.auth
from cc.environment import Environment
import monkey_island.cc.auth
from monkey_island.cc.environment import Environment
__author__ = 'itay.mizeretz'
@ -11,5 +11,5 @@ class StandardEnvironment(Environment):
def get_auth_users(self):
return [
cc.auth.User(1, StandardEnvironment.NO_AUTH_CREDS, StandardEnvironment.NO_AUTH_CREDS)
monkey_island.cc.auth.User(1, StandardEnvironment.NO_AUTH_CREDS, StandardEnvironment.NO_AUTH_CREDS)
]

View File

@ -1,6 +1,6 @@
from cc.environment.environment import load_env_from_file, AWS
from cc.report_exporter_manager import ReportExporterManager
from cc.resources.aws_exporter import AWSExporter
from monkey_island.cc.environment.environment import load_env_from_file, AWS
from monkey_island.cc.report_exporter_manager import ReportExporterManager
from monkey_island.cc.resources.aws_exporter import AWSExporter
__author__ = 'maor.rayzin'

View File

@ -11,17 +11,18 @@ BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if BASE_PATH not in sys.path:
sys.path.insert(0, BASE_PATH)
from cc.island_logger import json_setup_logging
from monkey_island.cc.island_logger import json_setup_logging
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
# This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top.
json_setup_logging(default_path=os.path.join(BASE_PATH, 'cc', 'island_logger_default_config.json'),
json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'),
default_level=logging.DEBUG)
logger = logging.getLogger(__name__)
from cc.app import init_app
from cc.exporter_init import populate_exporter_list
from cc.utils import local_ip_addresses
from cc.environment.environment import env
from cc.database import is_db_server_up
from monkey_island.cc.app import init_app
from monkey_island.cc.exporter_init import populate_exporter_list
from monkey_island.cc.utils import local_ip_addresses
from monkey_island.cc.environment.environment import env
from monkey_island.cc.database import is_db_server_up
def main():
@ -37,12 +38,16 @@ def main():
populate_exporter_list()
app = init_app(mongo_url)
crt_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.crt')
key_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.key')
if env.is_debug():
app.run(host='0.0.0.0', debug=True, ssl_context=('monkey_island/cc/server.crt', 'monkey_island/cc/server.key'))
app.run(host='0.0.0.0', debug=True, ssl_context=(crt_path, key_path))
else:
http_server = HTTPServer(WSGIContainer(app),
ssl_options={'certfile': os.environ.get('SERVER_CRT', 'monkey_island/cc/server.crt'),
'keyfile': os.environ.get('SERVER_KEY', 'monkey_island/cc/server.key')})
ssl_options={'certfile': os.environ.get('SERVER_CRT', crt_path),
'keyfile': os.environ.get('SERVER_KEY', key_path)})
http_server.listen(env.get_island_port())
logger.info(
'Monkey Island Server is running on https://{}:{}'.format(local_ip_addresses()[0], env.get_island_port()))

View File

@ -0,0 +1,24 @@
import flask_restful
from flask import request
import json
from monkey_island.cc.services.attack.attack_telem import set_results
import logging
__author__ = 'VakarisZ'
LOG = logging.getLogger(__name__)
class AttackTelem(flask_restful.Resource):
"""
ATT&CK endpoint used to retrieve matrix related info from monkey
"""
def post(self, technique):
"""
Gets ATT&CK telemetry data and stores it in the database
:param technique: Technique ID, e.g. T1111
"""
data = json.loads(request.data)
set_results(technique, data)
return {}

View File

@ -4,9 +4,9 @@ from datetime import datetime
import boto3
from botocore.exceptions import UnknownServiceError
from cc.resources.exporter import Exporter
from cc.services.config import ConfigService
from cc.environment.environment import load_server_configuration_from_file
from monkey_island.cc.resources.exporter import Exporter
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.environment.environment import load_server_configuration_from_file
from common.cloud.aws_instance import AwsInstance
__author__ = 'maor.rayzin'

View File

@ -2,7 +2,7 @@ import logging
from flask import request, jsonify
import flask_restful
from cc.services.node import NodeService
from monkey_island.cc.services.node import NodeService
__author__ = 'itay.mizeretz'

View File

@ -1,7 +1,7 @@
from flask import request
import flask_restful
from cc.services.edge import EdgeService
from monkey_island.cc.services.edge import EdgeService
__author__ = 'Barak'

View File

@ -3,8 +3,8 @@ import json
import flask_restful
from flask import request, jsonify, abort
from cc.auth import jwt_required
from cc.services.config import ConfigService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.config import ConfigService
class IslandConfiguration(flask_restful.Resource):

View File

@ -2,8 +2,8 @@ import logging
import flask_restful
from cc.auth import jwt_required
from cc.services.island_logs import IslandLogService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.island_logs import IslandLogService
__author__ = "Maor.Rayzin"

View File

@ -6,16 +6,18 @@ import sys
from flask import request, jsonify, make_response
import flask_restful
from cc.environment.environment import env
from cc.resources.monkey_download import get_monkey_executable
from cc.services.node import NodeService
from cc.utils import local_ip_addresses
from monkey_island.cc.environment.environment import env
from monkey_island.cc.resources.monkey_download import get_monkey_executable
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.utils import local_ip_addresses
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
__author__ = 'Barak'
import logging
logger = logging.getLogger(__name__)
def run_local_monkey():
import platform
import subprocess
@ -26,8 +28,8 @@ def run_local_monkey():
if not result:
return False, "OS Type not found"
monkey_path = os.path.join(os.getcwd(), 'monkey_island', 'cc', 'binaries', result['filename'])
target_path = os.path.join(os.getcwd(), 'monkey_island', result['filename'])
monkey_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'binaries', result['filename'])
target_path = os.path.join(MONKEY_ISLAND_ABS_PATH, result['filename'])
# copy the executable to temp path (don't run the monkey from its current location as it may delete itself)
try:

View File

@ -4,10 +4,10 @@ import flask_restful
from bson import ObjectId
from flask import request
from cc.auth import jwt_required
from cc.database import mongo
from cc.services.log import LogService
from cc.services.node import NodeService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.database import mongo
from monkey_island.cc.services.log import LogService
from monkey_island.cc.services.node import NodeService
__author__ = "itay.mizeretz"

View File

@ -5,9 +5,9 @@ import dateutil.parser
from flask import request
import flask_restful
from cc.database import mongo
from cc.services.config import ConfigService
from cc.services.node import NodeService
from monkey_island.cc.database import mongo
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.node import NodeService
__author__ = 'Barak'

View File

@ -3,8 +3,8 @@ import json
import flask_restful
from flask import request, jsonify, abort
from cc.auth import jwt_required
from cc.services.config import ConfigService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.config import ConfigService
__author__ = 'Barak'

View File

@ -5,6 +5,8 @@ import os
import flask_restful
from flask import request, send_from_directory
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
__author__ = 'Barak'
logger = logging.getLogger(__name__)
@ -70,7 +72,7 @@ class MonkeyDownload(flask_restful.Resource):
# Used by monkey. can't secure.
def get(self, path):
return send_from_directory('binaries', path)
return send_from_directory(os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'binaries'), path)
# Used by monkey. can't secure.
def post(self):
@ -81,7 +83,7 @@ class MonkeyDownload(flask_restful.Resource):
if result:
# change resulting from new base path
real_path = os.path.join("monkey_island", "cc", 'binaries', result['filename'])
real_path = os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", 'binaries', result['filename'])
if os.path.isfile(real_path):
result['size'] = os.path.getsize(real_path)
return result

View File

@ -1,9 +1,9 @@
import flask_restful
from cc.auth import jwt_required
from cc.services.edge import EdgeService
from cc.services.node import NodeService
from cc.database import mongo
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.edge import EdgeService
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.database import mongo
__author__ = 'Barak'

View File

@ -1,8 +1,8 @@
from flask import request
import flask_restful
from cc.auth import jwt_required
from cc.services.node import NodeService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.node import NodeService
__author__ = 'Barak'

View File

@ -1,6 +1,6 @@
import flask_restful
from flask import send_from_directory
from cc.resources.pba_file_upload import GET_FILE_DIR
from monkey_island.cc.resources.pba_file_upload import GET_FILE_DIR
__author__ = 'VakarisZ'

View File

@ -1,8 +1,8 @@
import flask_restful
from flask import request, send_from_directory, Response
from cc.services.config import ConfigService
from cc.services.post_breach_files import PBA_WINDOWS_FILENAME_PATH, PBA_LINUX_FILENAME_PATH, UPLOADS_DIR
from cc.auth import jwt_required
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.post_breach_files import PBA_WINDOWS_FILENAME_PATH, PBA_LINUX_FILENAME_PATH, UPLOADS_DIR
from monkey_island.cc.auth import jwt_required
import os
from werkzeug.utils import secure_filename
import logging

View File

@ -2,8 +2,8 @@ import json
from flask import request, jsonify, make_response
import flask_restful
from cc.auth import jwt_required
from cc.services.remote_run_aws import RemoteRunAwsService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
from common.cloud.aws_service import AwsService

View File

@ -1,7 +1,7 @@
import flask_restful
from cc.auth import jwt_required
from cc.services.report import ReportService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.report import ReportService
__author__ = "itay.mizeretz"

View File

@ -4,14 +4,14 @@ import logging
import flask_restful
from flask import request, make_response, jsonify
from cc.auth import jwt_required
from cc.database import mongo
from cc.services.config import ConfigService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.database import mongo
from monkey_island.cc.services.config import ConfigService
from cc.services.attack.attack_config import reset_config as reset_attack_config
from cc.services.node import NodeService
from cc.services.report import ReportService
from cc.utils import local_ip_addresses
from cc.services.post_breach_files import remove_PBA_files
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.report import ReportService
from monkey_island.cc.utils import local_ip_addresses
from monkey_island.cc.services.post_breach_files import remove_PBA_files
__author__ = 'Barak'

View File

@ -7,14 +7,14 @@ import dateutil
import flask_restful
from flask import request
from cc.auth import jwt_required
from cc.database import mongo
from cc.services import mimikatz_utils
from cc.services.config import ConfigService
from cc.services.edge import EdgeService
from cc.services.node import NodeService
from cc.encryptor import encryptor
from cc.services.wmi_handler import WMIHandler
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.database import mongo
from monkey_island.cc.services import mimikatz_utils
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.edge import EdgeService
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.encryptor import encryptor
from monkey_island.cc.services.wmi_handler import WMIHandler
__author__ = 'Barak'

View File

@ -5,9 +5,9 @@ import flask_restful
from flask import request
import flask_pymongo
from cc.auth import jwt_required
from cc.database import mongo
from cc.services.node import NodeService
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.database import mongo
from monkey_island.cc.services.node import NodeService
__author__ = 'itay.mizeretz'

View File

@ -0,0 +1,19 @@
"""
File that contains ATT&CK telemetry storing/retrieving logic
"""
import logging
from monkey_island.cc.database import mongo
__author__ = "VakarisZ"
logger = logging.getLogger(__name__)
def set_results(technique, data):
"""
Adds ATT&CK technique results(telemetry) to the database
:param technique: technique ID string e.g. T1110
:param data: Data, relevant to the technique
"""
data.update({'technique': technique})
mongo.db.attack_results.insert(data)

View File

@ -4,12 +4,12 @@ import functools
import logging
from jsonschema import Draft4Validator, validators
from six import string_types
import cc.services.post_breach_files
import monkey_island.cc.services.post_breach_files
from cc.database import mongo
from cc.encryptor import encryptor
from cc.environment.environment import env
from cc.utils import local_ip_addresses
from monkey_island.cc.database import mongo
from monkey_island.cc.encryptor import encryptor
from monkey_island.cc.environment.environment import env
from monkey_island.cc.utils import local_ip_addresses
from config_schema import SCHEMA
__author__ = "itay.mizeretz"
@ -146,7 +146,7 @@ class ConfigService:
@staticmethod
def update_config(config_json, should_encrypt):
# PBA file upload happens on pba_file_upload endpoint and corresponding config options are set there
cc.services.post_breach_files.set_config_PBA_files(config_json)
monkey_island.cc.services.post_breach_files.set_config_PBA_files(config_json)
if should_encrypt:
try:
ConfigService.encrypt_config(config_json)
@ -182,7 +182,7 @@ class ConfigService:
@staticmethod
def reset_config():
cc.services.post_breach_files.remove_PBA_files()
monkey_island.cc.services.post_breach_files.remove_PBA_files()
config = ConfigService.get_default_config(True)
ConfigService.set_server_ips_in_config(config)
ConfigService.update_config(config, should_encrypt=False)

View File

@ -1,7 +1,7 @@
from bson import ObjectId
from cc.database import mongo
import cc.services.node
from monkey_island.cc.database import mongo
import monkey_island.cc.services.node
__author__ = "itay.mizeretz"
@ -87,7 +87,7 @@ class EdgeService:
@staticmethod
def get_infected_monkey_island_pseudo_edges():
monkey = cc.services.node.NodeService.get_monkey_island_monkey()
monkey = monkey_island.cc.services.node.NodeService.get_monkey_island_monkey()
existing_ids = [x["from"] for x in mongo.db.edge.find({"to": monkey["_id"]})]
monkey_ids = [x["_id"] for x in mongo.db.monkey.find({})
if ("tunnel" not in x) and (x["_id"] not in existing_ids) and (x["_id"] != monkey["_id"])]
@ -136,11 +136,11 @@ class EdgeService:
{"_id": edge["_id"]},
{"$set": {"exploited": True}}
)
cc.services.node.NodeService.set_node_exploited(edge["to"])
monkey_island.cc.services.node.NodeService.set_node_exploited(edge["to"])
@staticmethod
def get_edge_label(edge):
NodeService = cc.services.node.NodeService
NodeService = monkey_island.cc.services.node.NodeService
from_label = NodeService.get_monkey_label(NodeService.get_monkey_by_id(edge["from"]))
if edge["to"] == ObjectId("000000000000000000000000"):
to_label = 'MonkeyIsland'

View File

@ -1,7 +1,7 @@
from datetime import datetime
import cc.services.node
from cc.database import mongo, database
import monkey_island.cc.services.node
from monkey_island.cc.database import mongo, database
__author__ = "itay.mizeretz"
@ -15,8 +15,8 @@ class LogService:
log = mongo.db.log.find_one({'monkey_id': monkey_id})
if log:
log_file = database.gridfs.get(log['file_id'])
monkey_label = cc.services.node.NodeService.get_monkey_label(
cc.services.node.NodeService.get_monkey_by_id(log['monkey_id']))
monkey_label = monkey_island.cc.services.node.NodeService.get_monkey_label(
monkey_island.cc.services.node.NodeService.get_monkey_by_id(log['monkey_id']))
return \
{
'monkey_label': monkey_label,

View File

@ -2,10 +2,10 @@ from datetime import datetime, timedelta
from bson import ObjectId
import cc.services.log
from cc.database import mongo
from cc.services.edge import EdgeService
from cc.utils import local_ip_addresses
import monkey_island.cc.services.log
from monkey_island.cc.database import mongo
from monkey_island.cc.services.edge import EdgeService
from monkey_island.cc.utils import local_ip_addresses
import socket
__author__ = "itay.mizeretz"
@ -59,7 +59,7 @@ class NodeService:
else:
new_node["services"] = []
new_node['has_log'] = cc.services.log.LogService.log_exists(ObjectId(node_id))
new_node['has_log'] = monkey_island.cc.services.log.LogService.log_exists(ObjectId(node_id))
return new_node
@staticmethod

View File

@ -1,4 +1,4 @@
import cc.services.config
import monkey_island.cc.services.config
import logging
import os
@ -13,9 +13,9 @@ UPLOADS_DIR = 'monkey_island/cc/userUploads'
def remove_PBA_files():
if cc.services.config.ConfigService.get_config():
windows_filename = cc.services.config.ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH)
linux_filename = cc.services.config.ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH)
if monkey_island.cc.services.config.ConfigService.get_config():
windows_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH)
linux_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH)
if linux_filename:
remove_file(linux_filename)
if windows_filename:
@ -36,8 +36,8 @@ def set_config_PBA_files(config_json):
Sets PBA file info in config_json to current config's PBA file info values.
:param config_json: config_json that will be modified
"""
if cc.services.config.ConfigService.get_config():
linux_filename = cc.services.config.ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH)
windows_filename = cc.services.config.ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH)
if monkey_island.cc.services.config.ConfigService.get_config():
linux_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH)
windows_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH)
config_json['monkey']['behaviour']['PBA_linux_filename'] = linux_filename
config_json['monkey']['behaviour']['PBA_windows_filename'] = windows_filename

View File

@ -1,10 +1,10 @@
from itertools import product
from cc.database import mongo
from monkey_island.cc.database import mongo
from bson import ObjectId
from cc.services.groups_and_users_consts import USERTYPE
from cc.services.node import NodeService
from monkey_island.cc.services.groups_and_users_consts import USERTYPE
from monkey_island.cc.services.node import NodeService
__author__ = 'maor.rayzin'

View File

@ -1,4 +1,4 @@
from cc.services.config import ConfigService
from monkey_island.cc.services.config import ConfigService
from common.cloud.aws_instance import AwsInstance
from common.cloud.aws_service import AwsService
from common.cmd.aws.aws_cmd_runner import AwsCmdRunner

View File

@ -9,12 +9,12 @@ from enum import Enum
from six import text_type
from cc.database import mongo
from cc.report_exporter_manager import ReportExporterManager
from cc.services.config import ConfigService
from cc.services.edge import EdgeService
from cc.services.node import NodeService
from cc.utils import local_ip_addresses, get_subnets
from monkey_island.cc.database import mongo
from monkey_island.cc.report_exporter_manager import ReportExporterManager
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.edge import EdgeService
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.utils import local_ip_addresses, get_subnets
from pth_report import PTHReportService
from common.network.network_range import NetworkRange

View File

@ -1,5 +1,5 @@
from cc.database import mongo
from cc.services.groups_and_users_consts import USERTYPE, GROUPTYPE
from monkey_island.cc.database import mongo
from monkey_island.cc.services.groups_and_users_consts import USERTYPE, GROUPTYPE
__author__ = 'maor.rayzin'

View File

@ -24,8 +24,8 @@ let renderPbaResults = function (results) {
};
const subColumns = [
{id: 'pba_name', Header: "Name", accessor: x => x.name, style: { 'white-space': 'unset' }},
{id: 'pba_output', Header: "Output", accessor: x => renderPbaResults(x.result), style: { 'white-space': 'unset' }}
{id: 'pba_name', Header: "Name", accessor: x => x.name, style: { 'whiteSpace': 'unset' }},
{id: 'pba_output', Header: "Output", accessor: x => renderPbaResults(x.result), style: { 'whiteSpace': 'unset' }}
];
let renderDetails = function (data) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -0,0 +1,93 @@
# -*- mode: python -*-
import os
import platform
__author__ = 'itay.mizeretz'
block_cipher = None
def main():
a = Analysis(['cc/main.py'],
pathex=['..'],
hiddenimports=get_hidden_imports(),
hookspath=None,
runtime_hooks=None,
binaries=None,
datas=None,
excludes=None,
win_no_prefer_redirects=None,
win_private_assemblies=None,
cipher=block_cipher
)
a.binaries += get_binaries()
a.datas = process_datas(a.datas)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name=get_monkey_filename(),
debug=False,
strip=get_exe_strip(),
upx=True,
console=True,
icon=get_exe_icon())
def is_windows():
return platform.system().find("Windows") >= 0
def is_32_bit():
return platform.architecture()[0] == "32bit"
def process_datas(orig_datas):
datas = orig_datas
if is_windows():
datas = [i for i in datas if i[0].find('Include') < 0]
return datas
def get_binaries():
binaries = get_windows_only_binaries() if is_windows() else get_linux_only_binaries()
return binaries
def get_windows_only_binaries():
binaries = []
binaries += get_msvcr()
return binaries
def get_linux_only_binaries():
binaries = []
return binaries
def get_hidden_imports():
return ['_cffi_backend', 'queue'] if is_windows() else ['_cffi_backend']
def get_msvcr():
return [('msvcr100.dll', os.environ['WINDIR'] + '\\system32\\msvcr100.dll', 'BINARY')]
def get_monkey_filename():
return 'monkey_island.exe' if is_windows() else 'monkey_island'
def get_exe_strip():
return not is_windows()
def get_exe_icon():
return 'monkey_island.ico' if is_windows() else None
main() # We don't check if __main__ because this isn't the main script.

View File

@ -17,3 +17,6 @@ pycryptodome
boto3
awscli
dpath
bson
cffi
PyInstaller

View File

@ -0,0 +1,5 @@
REM - Builds Monkey Island Server EXE using pyinstaller -
bin\Python27\Scripts\pyinstaller.exe -F --log-level=DEBUG --clean --upx-dir=.\bin monkey_island.spec
move /Y dist\monkey_island.exe monkey_island.exe
rmdir /S /Q build
rmdir /S /Q dist

View File

@ -1,3 +1,4 @@
REM - Runs Monkey Island Server using python -
@title C^&C Server
@pushd ..
@monkey_island\bin\Python27\Scripts\python monkey_island.py

View File

@ -0,0 +1,5 @@
REM - Runs Monkey Island Server using built pyinstaller EXE -
@title C^&C Server
@pushd ..
@monkey_island\monkey_island.exe
@popd

View File

@ -1,2 +1,3 @@
REM - Runs MongoDB Server -
@title MongoDB
@bin\mongodb\mongod.exe --dbpath db

View File

@ -1,4 +1,5 @@
REM - Runs MongoDB Server & Monkey Island Server using built pyinstaller EXE -
if not exist db mkdir db
start windows\run_mongodb.bat
start windows\run_cc.bat
start windows\run_cc_exe.bat
start https://localhost:5000

View File

@ -0,0 +1,5 @@
REM - Runs MongoDB Server & Monkey Island Server using python -
if not exist db mkdir db
start windows\run_mongodb.bat
start windows\run_cc.bat
start https://localhost:5000