* Added missing findings

* switched to using the aws account id from the island's configuration page
This commit is contained in:
maor.rayzin 2018-11-27 16:57:53 +02:00
parent fb5ae63f04
commit 9e6b2b2d26
2 changed files with 355 additions and 170 deletions

View File

@ -10,7 +10,8 @@ from cc.environment.environment import load_server_configuration_from_file
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
AWS_CRED_CONFIG_KEYS = [['cnc', 'aws_config', 'aws_access_key_id'], AWS_CRED_CONFIG_KEYS = [['cnc', 'aws_config', 'aws_access_key_id'],
['cnc', 'aws_config', 'aws_secret_access_key']] ['cnc', 'aws_config', 'aws_secret_access_key'],
['cnc', 'aws_config', 'aws_account_id']]
class AWSExporter(Exporter): class AWSExporter(Exporter):
@ -34,7 +35,7 @@ class AWSExporter(Exporter):
def _get_aws_keys(): def _get_aws_keys():
creds_dict = {} creds_dict = {}
for key in AWS_CRED_CONFIG_KEYS: for key in AWS_CRED_CONFIG_KEYS:
creds_dict[key[2]] = ConfigService.get_config_value(key) creds_dict[key[2]] = str(ConfigService.get_config_value(key))
return creds_dict return creds_dict
@ -56,16 +57,28 @@ class AWSExporter(Exporter):
'smb_pth': AWSExporter._handle_smb_pth_issue, 'smb_pth': AWSExporter._handle_smb_pth_issue,
'sambacry': AWSExporter._handle_sambacry_issue, 'sambacry': AWSExporter._handle_sambacry_issue,
'shared_passwords': AWSExporter._handle_shared_passwords_issue, 'shared_passwords': AWSExporter._handle_shared_passwords_issue,
'wmi_password': AWSExporter._handle_wmi_password_issue,
'wmi_pth': AWSExporter._handle_wmi_pth_issue,
'ssh_key': AWSExporter._handle_ssh_key_issue,
'rdp': AWSExporter._handle_rdp_issue,
'shared_passwords_domain': AWSExporter._handle_shared_passwords_domain_issue,
'shared_admins_domain': AWSExporter._handle_shared_admins_domain_issue,
'strong_users_on_crit': AWSExporter._handle_strong_users_on_crit_issue,
'struts2': AWSExporter._handle_struts2_issue,
'weblogic': AWSExporter._handle_weblogic_issue,
'hadoop': AWSExporter._handle_hadoop_issue,
# azure and conficker are not relevant issues for an AWS env
} }
product_arn = load_server_configuration_from_file()['aws'].get('sec_hub_product_arn', '') product_arn = load_server_configuration_from_file()['aws'].get('sec_hub_product_arn', '')
account_id = AWSExporter._get_aws_keys().get('aws_account_id', '')
finding = { finding = {
"SchemaVersion": "2018-10-08", "SchemaVersion": "2018-10-08",
"Id": uuid.uuid4().hex, "Id": uuid.uuid4().hex,
"ProductArn": product_arn, "ProductArn": product_arn,
"GeneratorId": issue['type'], "GeneratorId": issue['type'],
"AwsAccountId": "324264561773", "AwsAccountId": account_id,
"Types": [ "Types": [
"Software and Configuration Checks/Vulnerabilities/CVE" "Software and Configuration Checks/Vulnerabilities/CVE"
], ],
@ -93,222 +106,393 @@ class AWSExporter(Exporter):
@staticmethod @staticmethod
def _handle_tunnel_issue(issue): def _handle_tunnel_issue(issue):
finding =\ finding = \
{ {"Severity": {
"Severity": { "Product": 5,
"Product": 5, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE",
"Id": issue['aws_instance_id'] "Title": "Weak segmentation - Machines were able to communicate over unused ports.",
}], "Description": "Use micro-segmentation policies to disable communication other than the required.",
"RecordState": "ACTIVE", "Remediation": {
} "Recommendation": {
"Text": "Machines are not locked down at port level. Network tunnel was set up from {0} to {1}"
.format(issue['machine'], issue['dest'])
}
}}
finding["Title"] = "Weak segmentation - Machines were able to communicate over unused ports."
finding["Description"] = "Use micro-segmentation policies to disable communication other than the required."
finding["Remediation"] = {
"Recommendation": {
"Text": "Machines are not locked down at port level. Network tunnel was set up from {0} to {1}"
.format(issue['machine'], issue['dest'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_sambacry_issue(issue): def _handle_sambacry_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 10,
"Product": 10, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE", "Title": "Samba servers are vulnerable to 'SambaCry'",
"Id": issue['aws_instance_id'] "Description": "Change {0} password to a complex one-use password that is not shared with other computers on the network. Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up." \
}], .format(issue['username']), "Remediation": {
"RecordState": "ACTIVE", "Recommendation": {
} "Text": "The machine {0} ({1}) is vulnerable to a SambaCry attack. The Monkey authenticated over the SMB protocol with user {2} and its password, and used the SambaCry vulnerability.".format(
issue['machine'], issue['ip_address'], issue['username'])
}
}}
finding["Title"] = "Samba servers are vulnerable to 'SambaCry'"
finding["Description"] = "Change {0} password to a complex one-use password that is not shared with other computers on the network. Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up."\
.format(issue['username'])
finding["Remediation"] = {
"Recommendation": {
"Text": "The machine {0} ({1}) is vulnerable to a SambaCry attack. The Monkey authenticated over the SMB protocol with user {2} and its password, and used the SambaCry vulnerability.".format(issue['machine'], issue['ip_address'], issue['username'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_smb_pth_issue(issue): def _handle_smb_pth_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 5,
"Product": 5, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE",
"Id": issue['aws_instance_id'] "Title": "Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
}], "Description": "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
"RecordState": "ACTIVE", issue['username']), "Remediation": {
} "Recommendation": {
"Text": "The machine {0}({1}) is vulnerable to a SMB attack. The Monkey used a pass-the-hash attack over SMB protocol with user {2}.".format(
issue['machine'], issue['ip_address'], issue['username'])
}
}}
finding["Title"] = "Machines are accessible using passwords supplied by the user during the Monkey's configuration."
finding["Description"] = "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(issue['username'])
finding["Remediation"] = {
"Recommendation": {
"Text": "The machine {0}({1}) is vulnerable to a SMB attack. The Monkey used a pass-the-hash attack over SMB protocol with user {2}.".format(issue['machine'], issue['ip_address'], issue['username'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_ssh_issue(issue): def _handle_ssh_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 1,
"Product": 1, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE",
"Id": issue['aws_instance_id'] "Title": "Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration.",
}], "Description": "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
"RecordState": "ACTIVE", issue['username']), "Remediation": {
} "Recommendation": {
"Text": "The machine {0} ({1}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH protocol with user {2} and its password.".format(
issue['machine'], issue['ip_address'], issue['username'])
}
}}
return finding
@staticmethod
def _handle_ssh_key_issue(issue):
finding = \
{"Severity": {
"Product": 1,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE",
"Title": "Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration.",
"Description": "Protect {ssh_key} private key with a pass phrase.".format(ssh_key=issue['ssh_key']),
"Remediation": {
"Recommendation": {
"Text": "The machine {machine} ({ip_address}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH protocol with private key {ssh_key}.".format(
machine=issue['machine'], ip_address=issue['ip_address'], ssh_key=issue['ssh_key'])
}
}}
finding["Title"] = "Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration."
finding["Description"] = "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(issue['username'])
finding["Remediation"] = {
"Recommendation": {
"Text": "The machine {0} ({1}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH protocol with user {2} and its password.".format(issue['machine'], issue['ip_address'], issue['username'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_elastic_issue(issue): def _handle_elastic_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 10,
"Product": 10, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE", "Title": "Elasticsearch servers are vulnerable to CVE-2015-1427",
"Id": issue['aws_instance_id'] "Description": "Update your Elastic Search server to version 1.4.3 and up.", "Remediation": {
}], "Recommendation": {
"RecordState": "ACTIVE", "Text": "The machine {0}({1}) is vulnerable to an Elastic Groovy attack. The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427.".format(
} issue['machine'], issue['ip_address'])
}
}}
finding["Title"] = "Elasticsearch servers are vulnerable to CVE-2015-1427"
finding["Description"] = "Update your Elastic Search server to version 1.4.3 and up."
finding["Remediation"] = {
"Recommendation": {
"Text": "The machine {0}({1}) is vulnerable to an Elastic Groovy attack. The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427.".format(issue['machine'], issue['ip_address'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_island_cross_segment_issue(issue): def _handle_island_cross_segment_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 1,
"Product": 1, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE",
"Id": issue['aws_instance_id'] "Title": "Weak segmentation - Machines from different segments are able to communicate.",
}], "Description": "Segment your network and make sure there is no communication between machines from different segments.",
"RecordState": "ACTIVE", "Remediation": {
} "Recommendation": {
"Text": "The network can probably be segmented. A monkey instance on \
finding["Title"] = "Weak segmentation - Machines from different segments are able to communicate."
finding["Description"] = "egment your network and make sure there is no communication between machines from different segments."
finding["Remediation"] = {
"Recommendation": {
"Text": "The network can probably be segmented. A monkey instance on \
{0} in the networks {1} \ {0} in the networks {1} \
could directly access the Monkey Island server in the networks {2}.".format(issue['machine'], could directly access the Monkey Island server in the networks {2}.".format(issue['machine'],
issue['networks'], issue['networks'],
issue['server_networks']) issue['server_networks'])
} }
} }}
return finding return finding
@staticmethod @staticmethod
def _handle_shared_passwords_issue(issue): def _handle_shared_passwords_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 1,
"Product": 1, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE", "Title": "Multiple users have the same password",
"Id": issue['aws_instance_id'] "Description": "Some users are sharing passwords, this should be fixed by changing passwords.",
}], "Remediation": {
"RecordState": "ACTIVE", "Recommendation": {
} "Text": "These users are sharing access password: {0}.".format(issue['shared_with'])
}
}}
finding["Title"] = "Multiple users have the same password"
finding["Description"] = "Some users are sharing passwords, this should be fixed by changing passwords."
finding["Remediation"] = {
"Recommendation": {
"Text": "These users are sharing access password: {0}.".format(issue['shared_with'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_shellshock_issue(issue): def _handle_shellshock_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 10,
"Product": 10, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE", "Title": "Machines are vulnerable to 'Shellshock'",
"Id": issue['aws_instance_id'] "Description": "Update your Bash to a ShellShock-patched version.", "Remediation": {
}], "Recommendation": {
"RecordState": "ACTIVE", "Text": "The machine {0} ({1}) is vulnerable to a ShellShock attack. "
} "The attack was made possible because the HTTP server running on TCP port {2} was vulnerable to a shell injection attack on the paths: {3}.".format(
issue['machine'], issue['ip_address'], issue['port'], issue['paths'])
}
}}
finding["Title"] = "Machines are vulnerable to 'Shellshock'"
finding["Description"] = "Update your Bash to a ShellShock-patched version."
finding["Remediation"] = {
"Recommendation": {
"Text": "The machine {0} ({1}) is vulnerable to a ShellShock attack. The attack was made possible because the HTTP server running on TCP port {2} was vulnerable to a shell injection attack on the paths: {3}.".format(issue['machine'], issue['ip_address'], issue['port'], issue['paths'])
}
}
return finding return finding
@staticmethod @staticmethod
def _handle_smb_password_issue(issue): def _handle_smb_password_issue(issue):
finding = \ finding = \
{ {"Severity": {
"Severity": { "Product": 1,
"Product": 1, "Normalized": 100
"Normalized": 100 }, "Resources": [{
}, "Type": "AwsEc2Instance",
"Resources": [{ "Id": issue['aws_instance_id']
"Type": "AwsEc2Instance", }], "RecordState": "ACTIVE",
"Id": issue['aws_instance_id'] "Title": "Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
}], "Description": "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
"RecordState": "ACTIVE", issue['username']), "Remediation": {
} "Recommendation": {
"Text": "The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB protocol with user {2} and its password.".format(
issue['machine'], issue['ip_address'], issue['username'])
}
}}
finding["Title"] = "Machines are accessible using passwords supplied by the user during the Monkey's configuration." return finding
finding["Description"] = "Change {0}'s password to a complex one-use password that is not shared with other computers on the network."
finding["Remediation"] = { @staticmethod
"Recommendation": { def _handle_wmi_password_issue(issue):
"Text": "The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB protocol with user {2} and its password.".format(issue['machine'], issue['ip_address'], issue['username']) finding = \
} {"Severity": {
} "Product": 1,
return finding "Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE",
"Title": "Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
"Description": "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.",
"Remediation": {
"Recommendation": {
"Text": "The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over the WMI protocol with user {username} and its password.".format(
machine=issue['machine'], ip_address=issue['ip_address'], username=issue['username'])
}
}}
return finding
@staticmethod
def _handle_wmi_pth_issue(issue):
finding = \
{"Severity": {
"Product": 1,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE",
"Title": "Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
"Description": "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
issue['username']), "Remediation": {
"Recommendation": {
"Text": "The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey used a pass-the-hash attack over WMI protocol with user {username}".format(
machine=issue['machine'], ip_address=issue['ip_address'], username=issue['username'])
}
}}
return finding
@staticmethod
def _handle_rdp_issue(issue):
finding = \
{"Severity": {
"Product": 1,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE",
"Title": "Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
"Description": "Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
issue['username']), "Remediation": {
"Recommendation": {
"Text": "The machine machine ({ip_address}) is vulnerable to a RDP attack. The Monkey authenticated over the RDP protocol with user {username} and its password.".format(
machine=issue['machine'], ip_address=issue['ip_address'], username=issue['username'])
}
}}
return finding
@staticmethod
def _handle_shared_passwords_domain_issue(issue):
finding = \
{"Severity": {
"Product": 1,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE", "Title": "Multiple users have the same password.",
"Description": "Some domain users are sharing passwords, this should be fixed by changing passwords.",
"Remediation": {
"Recommendation": {
"Text": "These users are sharing access password: {shared_with}.".format(
shared_with=issue['shared_with'])
}
}}
return finding
@staticmethod
def _handle_shared_admins_domain_issue(issue):
finding = \
{"Severity": {
"Product": 1,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE",
"Title": "Shared local administrator account - Different machines have the same account as a local administrator.",
"Description": "Make sure the right administrator accounts are managing the right machines, and that there isn\'t an unintentional local admin sharing.",
"Remediation": {
"Recommendation": {
"Text": "Here is a list of machines which the account {username} is defined as an administrator: {shared_machines}".format(
username=issue['username'], shared_machines=issue['shared_machines'])
}
}}
return finding
@staticmethod
def _handle_strong_users_on_crit_issue(issue):
finding = \
{"Severity": {
"Product": 1,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE",
"Title": "Mimikatz found login credentials of a user who has admin access to a server defined as critical.",
"Description": "This critical machine is open to attacks via strong users with access to it.",
"Remediation": {
"Recommendation": {
"Text": "The services: {services} have been found on the machine thus classifying it as a critical machine. These users has access to it:{threatening_users}.".format(
services=issue['services'], threatening_users=issue['threatening_users'])
}
}}
return finding
@staticmethod
def _handle_struts2_issue(issue):
finding = \
{"Severity": {
"Product": 10,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE", "Title": "Struts2 servers are vulnerable to remote code execution.",
"Description": "Upgrade Struts2 to version 2.3.32 or 2.5.10.1 or any later versions.", "Remediation": {
"Recommendation": {
"Text": "Struts2 server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
" The attack was made possible because the server is using an old version of Jakarta based file upload Multipart parser.".format(
machine=issue['machine'], ip_address=issue['ip_address'])
}
}}
return finding
@staticmethod
def _handle_weblogic_issue(issue):
finding = \
{"Severity": {
"Product": 10,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE", "Title": "Oracle WebLogic servers are vulnerable to remote code execution.",
"Description": "Install Oracle critical patch updates. Or update to the latest version. " \
"Vulnerable versions are 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0.",
"Remediation": {
"Recommendation": {
"Text": "Oracle WebLogic server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
" The attack was made possible due to incorrect permission assignment in Oracle Fusion Middleware (subcomponent: WLS Security).".format(
machine=issue['machine'], ip_address=issue['ip_address'])
}
}}
return finding
@staticmethod
def _handle_hadoop_issue(issue):
finding = \
{"Severity": {
"Product": 10,
"Normalized": 100
}, "Resources": [{
"Type": "AwsEc2Instance",
"Id": issue['aws_instance_id']
}], "RecordState": "ACTIVE", "Title": "Hadoop/Yarn servers are vulnerable to remote code execution.",
"Description": "Run Hadoop in secure mode, add Kerberos authentication.", "Remediation": {
"Recommendation": {
"Text": "The Hadoop server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
" The attack was made possible due to default Hadoop/Yarn configuration being insecure."
}
}}
return finding

View File

@ -907,6 +907,7 @@ ENCRYPTED_CONFIG_ARRAYS = \
ENCRYPTED_CONFIG_STRINGS = \ ENCRYPTED_CONFIG_STRINGS = \
[ [
['cnc', 'aws_config', 'aws_access_key_id'], ['cnc', 'aws_config', 'aws_access_key_id'],
['cnc', 'aws_config', 'aws_account_id'],
['cnc', 'aws_config', 'aws_secret_access_key'] ['cnc', 'aws_config', 'aws_secret_access_key']
] ]