Refactored to run series of tests, improved configurations, file structure
This commit is contained in:
parent
0ee4445ca1
commit
36b6752827
|
@ -6,6 +6,6 @@ def pytest_addoption(parser):
|
||||||
help="Specify the Monkey Island address (host+port).")
|
help="Specify the Monkey Island address (host+port).")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture(scope='module')
|
||||||
def island(request):
|
def island(request):
|
||||||
request.cls.island = request.config.getoption("--island")
|
return request.config.getoption("--island")
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"general": {
|
"general": {
|
||||||
"blocked_ips": [],
|
"blocked_ips": [],
|
||||||
"depth": 2,
|
"depth": 2,
|
||||||
"local_network_scan": true,
|
"local_network_scan": false,
|
||||||
"subnet_scan_list": [
|
"subnet_scan_list": [
|
||||||
"10.2.2.4",
|
"10.2.2.4",
|
||||||
"10.2.2.5"
|
"10.2.2.5"
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -181,4 +181,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -192,4 +192,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -180,4 +180,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -180,4 +180,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,14 +101,11 @@
|
||||||
},
|
},
|
||||||
"exploits": {
|
"exploits": {
|
||||||
"exploit_lm_hash_list": [],
|
"exploit_lm_hash_list": [],
|
||||||
"exploit_ntlm_hash_list": [
|
"exploit_ntlm_hash_list": [],
|
||||||
"5da0889ea2081aa79f6852294cba4a5e",
|
|
||||||
"5da0889ea2081aa79f6852294cba4a5e"
|
|
||||||
],
|
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -182,4 +179,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,23 +112,10 @@
|
||||||
"exploits": {
|
"exploits": {
|
||||||
"exploit_lm_hash_list": [],
|
"exploit_lm_hash_list": [],
|
||||||
"exploit_ntlm_hash_list": [],
|
"exploit_ntlm_hash_list": [],
|
||||||
"exploit_ssh_keys": [
|
"exploit_ssh_keys": []
|
||||||
{
|
|
||||||
"ip": "10.2.2.41",
|
|
||||||
"private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAyH0k1LOILDTVli5NlqcvRdoRc2aMn5I5ZhJsnBNuzB28D6Fd\nAEbjDn/v+dPK58L4WGoGMpHqk47mNDgdTIkfP5BBgbuQpBUmrsCZn8QVRpqZ3ESC\nXsnMrOjrYRqTelquGWR9xJvIJwNz3UbME2c8SYOPc3tHsINyn8Tt2ssA8L9KjcTe\n6CzNpbCNbZ6Q3o7/isYP79ogiFY+VHK3rtBY17aG9bDx5vce8RoIr463u/+a+jYX\nPuzZgndTtO3EPwq4Ti1pydpuJo9PYh1iY6RP3XPMYNwpoKToYzyESeqqwolmz+nh\nEh/rQtuwwW7043IM+62w9UPkHWv28pqDZxBxhwIDAQABAoIBAGA1/ei8xwo/yIer\nbLxxOnRQ87LncXBaIYVkLg6wHKmDU25Ex3aMjgW1S5oeEu8pVzhGmPbHo0RwfPRu\nQVErNH2yYl05f23eYJPYBWDwHi2ln1Re5BlMyhXoKJyOvlsnDQlOejRRdbmTJJT5\nlpFxJzM4GS0X6g1A507YmDQ42xisOkmL/Wsv/t9/GiE9P6h0I1bNmXzSy8sDZwea\nNDe09U+rfuIkh2tO+nEzWs13AG3CxV9YlK4vMK7A0KiWF8LPvrbBegEm5VG+qrJ2\nsxoDkCBc5DV6QRyLU1SIyDIRIR2J0gTgfLDSbqNp0qm+Zby2o3V/q26bvrWWwP9a\nU/W2vJECgYEA5jK52pUMmriCiWNgQOiyOGx5OfHo6gRomiiiALivaMhNN3mm8CFI\nuIXMjU1V0BoHXCW8ciMOAeXl72rX/XVC+/E3GJQFCtBHJQ6tPNOOnWcxR/Ldwvxd\nsBz8Wx50MlxvbrxqtzTn+VmVnExKskwsZGI/GDPotPo7QKcBJUsGfhsCgYEA3vXx\ncyG805RsJH/J54cg+cHW5xDn6YNuHwbVdB4FWfi184oDDxtPT84XF1JA3dN3gwJF\nSfO1kNwpNK0C58evJA+6rZfUps/HOcQqFPvzCUhkLeZD5QgaOTQZBKndXYgeXkJD\ntpN+kjhCdxWN40N6FAMtLUYTbaQdTUHSBuXzoQUCgYEAgwXgTw+DCxV2ByjvAkLw\nHblwDpEoVvqHZyc1fl+gR22qtaaiZA8tywks8khQTZBjHAnGhth5Ao+OHoWbxoHV\nzHzxNSYa8Jq3w9nktLhddi3kGOWdX3ww/yqgYGSnEnsWWdsYioqsdnqM81dhNLay\nlbht3SK+kzPSQexMdKONYH0CgYAS1lKk+Ie8lICigM1tK0SE9XSTpyEA4KLQKkKk\ngdjP5ixxPArQHu2Pf4kB5mgmlbQ2NF3oRpfjekZc9fUV4hARCucpvXcw9MMPRVyM\n01CQSzZzjk3ULuAQTy+B7lwOh+6Q5iZUaZe7ANfUudR4C/5nbHFHrvD7RW9YVKRL\nAuiXhQKBgDMFeZRfu/dhTdVQ9XZigOWvkeXYxxoloiIHIg3ByZwEAlH/RnlA0M1Z\nOaLt/Q1KNh2UDKkstfOAJ1FdqLm3JU0Hqx/D8dpvTUQBkqoMf8U1WQC2WVmlpmUv\ndrIj1d5/r2N1Cxorx0IbVWsW7WPVM/lVyBU7+2QsKoI5YIervsJY\n-----END RSA PRIVATE KEY-----\n",
|
|
||||||
"public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIfSTUs4gsNNWWLk2Wpy9F2hFzZoyfkjlmEmycE27MHbwPoV0ARuMOf+/508rnwvhYagYykeqTjuY0OB1MiR8/kEGBu5CkFSauwJmfxBVGmpncRIJeycys6OthGpN6Wq4ZZH3Em8gnA3PdRswTZzxJg49ze0ewg3KfxO3aywDwv0qNxN7oLM2lsI1tnpDejv+Kxg/v2iCIVj5Ucreu0FjXtob1sPHm9x7xGgivjre7/5r6Nhc+7NmCd1O07cQ/CrhOLWnJ2m4mj09iHWJjpE/dc8xg3CmgpOhjPIRJ6qrCiWbP6eESH+tC27DBbvTjcgz7rbD1Q+Qda/bymoNnEHGH m0nk3y@sshkeys-11\n",
|
|
||||||
"user": "m0nk3y"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ip": "10.2.2.42",
|
|
||||||
"private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA5fmqwJV/NZOThZ0B0SXJ7jz+xp2zvVI+DR141JpEJGAm8xP8\nCMmDACkGVDZfwQQEWsmG6WHsRJnBTm1jawUbhgD8EGYNp9sj8G4oW6GvThzzlZvp\nABgtSyWtT6CLBoF7t3/wgFXfAaA33lTg/Ht+bXBMaAZiHyRlexPjmtfhu1Hw44cM\nBuxJwA31OqnO0OPKOh6wW0OWta9BsJnFBckEve1y2Bf2SOnFdlAEV9tNWwGt/AK8\nMAEpgwEZXISrqOucjn7YGEzfZ+Ygjq4/M3FGE31ttrTgERqAPchd1Cp6da6mlYtu\nzx35spV2kxf2ydYHYOOgvS8cCIIk7GIANZztmQIDAQABAoIBAQCAOcXQHUrRV5hw\nbkt+DuDZWd8AZRu7mqiIbX9aoy0NTyNIc0MaryjApR8nQy3+k7vN1wHHDNdMpKIY\nlXtSR4XCILhqeExy5AfU3cbY2HzDQ/c42rZ+W/ydIsPQWwZJOVb+yHITTE3MPUYJ\nTDAp9r1WTb/8XFrHXGbMyhkk0+vDoezj+FDS0YbFImt2iFgC7wgDjuoG5CnlW09/\n/r2bfH/qKKvs9sDwCypVqH5bki1VyQLRfdrCgPisBnhBAj8OBFN+IN5L3P+Zv5UI\nwyZA34RETijHb158vAtIfz2LT0Gin6CNGZY+QOOjM1hCevgrbLeD13Bc9Oog7367\nlm10eMKBAoGBAPUPrbpgA/rg77YrL7uBQhy13HtrRnxW4AjtDs/dEelXlF/Zdfi6\nzukVkb6PaYVPAOC58E21gOJNDYXUdwkbGrJSIDr6rfb9AeEnGIcyDPn36roLjGBn\nJO3Ikr4AhycjbQVVdvo4VY5baCtHNonbn4VFeb+ThszMOQWci4djPGWJAoGBAPA9\nmbboApqV/zoy4PAukFFWOUxb+3GxwcywlVYIuAk3DfM5zJuLgxV70KJ/Z6ppmTzF\n+uPkydTFQv/aLA3IiUioPijl2/l1HmspHpzQztdJaMHhFolKCB+X7wa7QlSFKKyE\ngT8dV8mPsW2HMoNv/yfVQ7lv2M9t4CKhzgssnFORAoGAbeqJXqYAQv+vJQM71ptE\nXwJHEWhtZgnFVNuXIC6lAQdSOqecHWMUuUD+bP2AM9Xaq/FaUlCNrXMoFJXWilQI\n5mClqi6T5stWk3lorAMMBPZo5ueVIAxDaQ/kmao89JYUKSdLRTINVduz3m2DjdPf\nOfSOhhoShTs4fEbZ4nDlPxkCgYEAhz1WM/YFyToZVIzhvbOowHD2jnrVYJp9i5n4\nZ1c/KsjYTIzEFugBoe1ydJeeJvuNLP4Sj4ny6Jknb1pFJHk4dzNm0qUbISICPrcG\nKacOWXlUxJfOlPic/BQOlc6Ct4vCauOo0nvVOH1wl0Tddcpta+INXu2MsrCa1UQa\n9oVld1ECgYADhllIDq3mkM4y58BSIOQ7uOKqbOgTyOjUCS2cFtYXtv6UY/OxFVxJ\n9soergMdd1uDOOwv96Yu9aNzgqjXFixb3Gyk+xh1viOpLrpbCUgg6j20IHcv8pwS\nhsp2wHDCuS8cKK9E8RJ3YYNgLh5uH1J+GhzSix1V8sizT0Y1UPOCDQ==\n-----END RSA PRIVATE KEY-----\n",
|
|
||||||
"public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDl+arAlX81k5OFnQHRJcnuPP7GnbO9Uj4NHXjUmkQkYCbzE/wIyYMAKQZUNl/BBARayYbpYexEmcFObWNrBRuGAPwQZg2n2yPwbihboa9OHPOVm+kAGC1LJa1PoIsGgXu3f/CAVd8BoDfeVOD8e35tcExoBmIfJGV7E+Oa1+G7UfDjhwwG7EnADfU6qc7Q48o6HrBbQ5a1r0GwmcUFyQS97XLYF/ZI6cV2UARX201bAa38ArwwASmDARlchKuo65yOftgYTN9n5iCOrj8zcUYTfW22tOARGoA9yF3UKnp1rqaVi27PHfmylXaTF/bJ1gdg46C9LxwIgiTsYgA1nO2Z m0nk3y@sshkeys-12\n",
|
|
||||||
"user": "m0nk3y"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -202,4 +189,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -190,4 +190,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -181,4 +181,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,13 +109,11 @@
|
||||||
},
|
},
|
||||||
"exploits": {
|
"exploits": {
|
||||||
"exploit_lm_hash_list": [],
|
"exploit_lm_hash_list": [],
|
||||||
"exploit_ntlm_hash_list": [
|
"exploit_ntlm_hash_list": [],
|
||||||
"5da0889ea2081aa79f6852294cba4a5e"
|
|
||||||
],
|
|
||||||
"exploit_ssh_keys": []
|
"exploit_ssh_keys": []
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"keep_tunnel_open_time": 60,
|
"keep_tunnel_open_time": 50,
|
||||||
"monkey_dir_name": "monkey_dir",
|
"monkey_dir_name": "monkey_dir",
|
||||||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||||
},
|
},
|
||||||
|
@ -189,4 +187,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,106 +1,89 @@
|
||||||
import unittest
|
from time import sleep
|
||||||
from time import sleep, time
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from envs.monkey_zoo.blackbox.monkey_island_client import MonkeyIslandClient
|
from envs.monkey_zoo.blackbox.utils.monkey_island_client import MonkeyIslandClient
|
||||||
from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer
|
from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer
|
||||||
from envs.monkey_zoo.blackbox.island_config_parser import IslandConfigParser
|
from envs.monkey_zoo.blackbox.utils.island_config_parser import IslandConfigParser
|
||||||
from envs.monkey_zoo.blackbox.gcp_machine_handlers import GCPHandler
|
from envs.monkey_zoo.blackbox.utils import gcp_machine_handlers
|
||||||
|
from envs.monkey_zoo.blackbox.tests.basic_test import BasicTest
|
||||||
|
|
||||||
|
DEFAULT_TIMEOUT_SECONDS = 4 * 60 # 4 minutes
|
||||||
|
DELAY_BETWEEN_TESTS = 10
|
||||||
|
GCP_TEST_MACHINE_LIST = ['sshkeys-11', 'sshkeys-12', 'elastic-4', 'elastic-5', 'haddop-2-v3', 'hadoop-3', 'mssql-16',
|
||||||
|
'mimikatz-14', 'mimikatz-15', 'final-test-struts2-23', 'final-test-struts2-24',
|
||||||
|
'tunneling-9', 'tunneling-10', 'tunneling-11', 'weblogic-18', 'weblogic-19', 'shellshock-8']
|
||||||
|
|
||||||
|
|
||||||
MACHINE_BOOT_TIME_SECONDS = 20
|
@pytest.fixture(autouse=True, scope='session')
|
||||||
TEST_TIME_SECONDS = 70
|
def GCPHandler(request):
|
||||||
DELAY_BETWEEN_TESTS = 1
|
GCPHandler = gcp_machine_handlers.GCPHandler()
|
||||||
|
#GCPHandler.start_machines(" ".join(GCP_TEST_MACHINE_LIST))
|
||||||
|
|
||||||
|
def fin():
|
||||||
|
pass
|
||||||
|
# GCPHandler.stop_machines(" ".join(GCP_TEST_MACHINE_LIST))
|
||||||
|
|
||||||
|
request.addfinalizer(fin)
|
||||||
|
|
||||||
|
|
||||||
class BlackBoxTest(object):
|
@pytest.fixture(scope='class')
|
||||||
|
def island_client(island):
|
||||||
def __init__(self, name, island_client, island_config, analyzers, timeout=TEST_TIME_SECONDS):
|
island_client_object = MonkeyIslandClient(island)
|
||||||
self.name = name
|
yield island_client_object
|
||||||
self.island_client = island_client
|
|
||||||
self.island_config = island_config
|
|
||||||
self.analyzers = analyzers
|
|
||||||
self.timeout = timeout
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.island_client.import_config(self.island_config)
|
|
||||||
self.island_client.run_monkey_local()
|
|
||||||
self.test_until_timeout()
|
|
||||||
self.island_client.reset_env()
|
|
||||||
|
|
||||||
def test_until_timeout(self):
|
|
||||||
timer = TestTimer(self.timeout)
|
|
||||||
while not timer.timed_out():
|
|
||||||
if self.analyzers_pass():
|
|
||||||
self.log_success(timer)
|
|
||||||
return
|
|
||||||
sleep(DELAY_BETWEEN_TESTS)
|
|
||||||
self.log_failure(timer)
|
|
||||||
assert False
|
|
||||||
|
|
||||||
def log_success(self, timer):
|
|
||||||
print(self.get_analyzer_logs())
|
|
||||||
print("{} test passed, time taken: {:.1f} seconds.".format(self.name, timer.get_time_taken()))
|
|
||||||
|
|
||||||
def log_failure(self, timer):
|
|
||||||
print(self.get_analyzer_logs())
|
|
||||||
print("{} test failed because of timeout. Time taken: {:.1f} seconds.".format(self.name,
|
|
||||||
timer.get_time_taken()))
|
|
||||||
|
|
||||||
def analyzers_pass(self):
|
|
||||||
for analyzer in self.analyzers:
|
|
||||||
if not analyzer.analyze_test_results():
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_analyzer_logs(self):
|
|
||||||
log = ""
|
|
||||||
for analyzer in self.analyzers:
|
|
||||||
log += "\n"+analyzer.log.get_contents()
|
|
||||||
return log
|
|
||||||
|
|
||||||
|
|
||||||
class TestTimer(object):
|
@pytest.mark.usefixtures('island_client')
|
||||||
def __init__(self, timeout):
|
|
||||||
self.timeout_time = TestTimer.get_timeout_time(timeout)
|
|
||||||
self.start_time = time()
|
|
||||||
|
|
||||||
def timed_out(self):
|
|
||||||
return time() > self.timeout_time
|
|
||||||
|
|
||||||
def get_time_taken(self):
|
|
||||||
return time() - self.start_time
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_timeout_time(timeout):
|
|
||||||
return time() + timeout
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("island")
|
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
class TestMonkeyBlackbox(unittest.TestCase):
|
class TestMonkeyBlackbox(object):
|
||||||
|
|
||||||
def setUp(self):
|
def run_basic_test(self, island_client, conf_filename, test_name, timeout_in_seconds=DEFAULT_TIMEOUT_SECONDS):
|
||||||
self.GCPHandler = GCPHandler()
|
TestMonkeyBlackbox.wait_between_tests()
|
||||||
self.island_client = MonkeyIslandClient(self.island)
|
config_parser = IslandConfigParser(conf_filename)
|
||||||
self.GCPHandler.start_machines("sshkeys-11 sshkeys-12")
|
analyzer = CommunicationAnalyzer(island_client, config_parser.get_ips_of_targets())
|
||||||
TestMonkeyBlackbox.wait_for_machine_boot()
|
BasicTest(test_name,
|
||||||
|
island_client,
|
||||||
def tearDown(self):
|
config_parser.config_raw,
|
||||||
self.GCPHandler.stop_machines("sshkeys-11 sshkeys-12")
|
[analyzer],
|
||||||
print("Killing all GCP machines...")
|
timeout_in_seconds).run()
|
||||||
|
|
||||||
def test_server_online(self):
|
|
||||||
assert self.island_client.get_api_status() is not None
|
|
||||||
|
|
||||||
def test_ssh_exec(self):
|
|
||||||
conf_file_name = 'SSH.conf'
|
|
||||||
config_parser = IslandConfigParser(conf_file_name)
|
|
||||||
analyzer = CommunicationAnalyzer(self.island_client, config_parser.get_ips_of_targets())
|
|
||||||
BlackBoxTest("SSH test", self.island_client, config_parser.config_raw, [analyzer]).run()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def wait_for_machine_boot(time=MACHINE_BOOT_TIME_SECONDS):
|
def wait_between_tests():
|
||||||
print("Waiting for machines to fully boot up({:.0f} seconds).".format(time))
|
print("Waiting for ({:.0f} seconds) for old monkey's to die or GCP machines to boot up.".format(DELAY_BETWEEN_TESTS))
|
||||||
sleep(time)
|
sleep(DELAY_BETWEEN_TESTS)
|
||||||
|
|
||||||
|
"""
|
||||||
|
def test_server_online(self, island_client):
|
||||||
|
assert island_client.get_api_status() is not None
|
||||||
|
|
||||||
|
def test_ssh_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "SSH.conf", "SSH exploiter and keys")
|
||||||
|
|
||||||
|
def test_hadoop_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "HADOOP.conf", "Hadoop exploiter")
|
||||||
|
|
||||||
|
def test_mssql_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "MSSQL.conf", "MSSQL exploiter")
|
||||||
|
"""
|
||||||
|
def test_smb_and_mimikatz_exploiters(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "SMB_MIMIKATZ.conf", "SMB exploiter, mimikatz")
|
||||||
|
"""
|
||||||
|
def test_elastic_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "ELASTIC.conf", "Elastic exploiter", 180)
|
||||||
|
|
||||||
|
|
||||||
|
def test_struts_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "STRUTS2.conf", "Strtuts2 exploiter")
|
||||||
|
|
||||||
|
def test_weblogic_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "WEBLOGIC.conf", "Weblogic exploiter")
|
||||||
|
|
||||||
|
def test_shellshock_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "SHELLSHOCK.conf", "Shellschock exploiter")
|
||||||
|
|
||||||
|
def test_tunneling(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "TUNNELING.conf", "Tunneling exploiter")
|
||||||
|
|
||||||
|
def test_wmi_exploiter(self, island_client):
|
||||||
|
self.run_basic_test(island_client, "WMI_MIMIKATZ.conf", "WMI exploiter, mimikatz")
|
||||||
|
"""
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
from envs.monkey_zoo.blackbox.utils.test_timer import TestTimer
|
||||||
|
|
||||||
|
DELAY_BETWEEN_ANALYSIS = 1
|
||||||
|
|
||||||
|
|
||||||
|
class BasicTest(object):
|
||||||
|
|
||||||
|
def __init__(self, name, island_client, island_config, analyzers, timeout):
|
||||||
|
self.name = name
|
||||||
|
self.island_client = island_client
|
||||||
|
self.island_config = island_config
|
||||||
|
self.analyzers = analyzers
|
||||||
|
self.timeout = timeout
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.island_client.import_config(self.island_config)
|
||||||
|
try:
|
||||||
|
self.island_client.run_monkey_local()
|
||||||
|
self.test_until_timeout()
|
||||||
|
finally:
|
||||||
|
self.island_client.kill_all_monkeys()
|
||||||
|
self.island_client.reset_env()
|
||||||
|
|
||||||
|
def test_until_timeout(self):
|
||||||
|
timer = TestTimer(self.timeout)
|
||||||
|
while not timer.timed_out():
|
||||||
|
if self.all_analyzers_pass():
|
||||||
|
self.log_success(timer)
|
||||||
|
return
|
||||||
|
sleep(DELAY_BETWEEN_ANALYSIS)
|
||||||
|
self.log_failure(timer)
|
||||||
|
assert False
|
||||||
|
|
||||||
|
def log_success(self, timer):
|
||||||
|
print(self.get_analyzer_logs())
|
||||||
|
print("{} test passed, time taken: {:.1f} seconds.".format(self.name, timer.get_time_taken()))
|
||||||
|
|
||||||
|
def log_failure(self, timer):
|
||||||
|
print(self.get_analyzer_logs())
|
||||||
|
print("{} test failed because of timeout. Time taken: {:.1f} seconds.".format(self.name,
|
||||||
|
timer.get_time_taken()))
|
||||||
|
|
||||||
|
def all_analyzers_pass(self):
|
||||||
|
for analyzer in self.analyzers:
|
||||||
|
if not analyzer.analyze_test_results():
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_analyzer_logs(self):
|
||||||
|
log = ""
|
||||||
|
for analyzer in self.analyzers:
|
||||||
|
log += "\n"+analyzer.log.get_contents()
|
||||||
|
return log
|
|
@ -13,4 +13,6 @@ class IslandConfigParser(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_conf_file_path(conf_file_name):
|
def get_conf_file_path(conf_file_name):
|
||||||
return os.path.join(os.path.dirname(os.path.abspath(__file__)), "island_configs", conf_file_name)
|
return os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||||
|
"island_configs",
|
||||||
|
conf_file_name)
|
|
@ -10,7 +10,14 @@ NO_AUTH_CREDS = '55e97c9dcfd22b8079189ddaeea9bce8125887e3237b800c6176c9afa80d206
|
||||||
class MonkeyIslandClient(object):
|
class MonkeyIslandClient(object):
|
||||||
def __init__(self, server_address):
|
def __init__(self, server_address):
|
||||||
self.addr = "https://{IP}/".format(IP=server_address)
|
self.addr = "https://{IP}/".format(IP=server_address)
|
||||||
self.token = self.get_jwt_from_server()
|
self.token = self.try_get_jwt_from_server()
|
||||||
|
|
||||||
|
def try_get_jwt_from_server(self):
|
||||||
|
try:
|
||||||
|
return self.get_jwt_from_server()
|
||||||
|
except requests.ConnectionError:
|
||||||
|
print("Unable to connect to island, aborting!")
|
||||||
|
assert False
|
||||||
|
|
||||||
def get_jwt_from_server(self):
|
def get_jwt_from_server(self):
|
||||||
resp = requests.post(self.addr + "api/auth",
|
resp = requests.post(self.addr + "api/auth",
|
||||||
|
@ -43,12 +50,24 @@ class MonkeyIslandClient(object):
|
||||||
_ = self.request_post("api/configuration/island", data=config_contents)
|
_ = self.request_post("api/configuration/island", data=config_contents)
|
||||||
|
|
||||||
def run_monkey_local(self):
|
def run_monkey_local(self):
|
||||||
if self.request_post_json("api/local-monkey", dict_data={"action": "run"}).ok:
|
response = self.request_post_json("api/local-monkey", dict_data={"action": "run"})
|
||||||
|
if MonkeyIslandClient.monkey_ran_successfully(response):
|
||||||
print("Running the monkey.")
|
print("Running the monkey.")
|
||||||
else:
|
else:
|
||||||
print("Failed to run the monkey.")
|
print("Failed to run the monkey.")
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def monkey_ran_successfully(response):
|
||||||
|
return response.ok and json.loads(response.content)['is_running']
|
||||||
|
|
||||||
|
def kill_all_monkeys(self):
|
||||||
|
if self.request_get("api", {"action": "killall"}).ok:
|
||||||
|
print("Killing all monkeys after the test.")
|
||||||
|
else:
|
||||||
|
print("Failed to kill all monkeys.")
|
||||||
|
assert False
|
||||||
|
|
||||||
def reset_env(self):
|
def reset_env(self):
|
||||||
if self.request_get("api", {"action": "reset"}).ok:
|
if self.request_get("api", {"action": "reset"}).ok:
|
||||||
print("Resetting environment after the test.")
|
print("Resetting environment after the test.")
|
|
@ -0,0 +1,17 @@
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
|
||||||
|
class TestTimer(object):
|
||||||
|
def __init__(self, timeout):
|
||||||
|
self.timeout_time = TestTimer.get_timeout_time(timeout)
|
||||||
|
self.start_time = time()
|
||||||
|
|
||||||
|
def timed_out(self):
|
||||||
|
return time() > self.timeout_time
|
||||||
|
|
||||||
|
def get_time_taken(self):
|
||||||
|
return time() - self.start_time
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_timeout_time(timeout):
|
||||||
|
return time() + timeout
|
Loading…
Reference in New Issue