forked from p15670423/monkey
Merge pull request #920 from mssalvatore/refactor-advanced-multiselect
* Add warning icon to unsafe checkbox options * Add "Reset to safe defaults" button * Add warning icon and message to InfoPane * Change behavior of master checkbox to be consistent with KDE user interface guidelines (mixed state) * Extracted MasterCheckbox and ChildCheckbox from AdvancedMultiSelect * Add "safe" property to schemas that feed AdvancedMultiSelect components
This commit is contained in:
commit
13af101c2a
|
@ -1,58 +1,92 @@
|
|||
{
|
||||
"id": "AzD8XysWg1BBXCjCDkfq",
|
||||
"name": "Add a new configuration setting to the Agent ⚙",
|
||||
"dod": "TWFrZSUyMHRoZSUyMG1heCUyMHZpY3RpbSUyMG51bWJlciUyMHRoYXQlMjBNb25rZXklMjB3aWxsJTIwZmluZCUyMGJlZm9yZSUyMHN0b3BwaW5nJTIwY29uZmlndXJhYmxlJTIwYnklMjB0aGUlMjB1c2VyJTIwaW5zdGVhZCUyMG9mJTIwY29uc3RhbnQu",
|
||||
"description": "JTIzJTIwTWFrZSUyMHNvbWV0aGluZyUyMGNvbmZpZ3VyYWJsZSUwQSUwQUluJTIwdGhpcyUyMHVuaXQlMkMlMjB5b3UlMjB3aWxsJTIwbGVhcm4lMjBob3clMjB0byUyMGFkZCUyMGElMjBjb25maWd1cmF0aW9uJTIwb3B0aW9uJTIwdG8lMjBNb25rZXklMjBhbmQlMjBob3clMjB0byUyMHVzZSUyMGl0JTIwaW4lMjB0aGUlMjBNb25rZXklMjBBZ2VudCUyMGNvZGUuJTIwJTBBJTBBISU1QmNvbXB1dGVyJTIwZmlyZSU1RChodHRwcyUzQSUyRiUyRm1lZGlhLmdpcGh5LmNvbSUyRm1lZGlhJTJGN0o0UDdjVXVyMkRsRXJpanAzJTJGZ2lwaHkuZ2lmJTIwJTIyY29tcHV0ZXIlMjBmaXJlJTIyKSUwQSUwQSUyMyUyMyUyMFdoeSUyMGlzJTIwdGhpcyUyMGltcG9ydGFudCUzRiUwQSUwQUVuYWJsaW5nJTIwdXNlcnMlMjB0byUyMGNvbmZpZ3VyZSUyMHRoZSUyME1vbmtleSdzJTIwYmVoYXZpb3VyJTIwZ2l2ZXMlMjB0aGVtJTIwYSUyMGxvdCUyMG1vcmUlMjBmcmVlZG9tJTIwaW4lMjBob3clMjB0aGV5JTIwd2FudCUyMHRvJTIwdXNlJTIwdGhlJTIwTW9ua2V5JTIwYW5kJTIwZW5hYmxlcyUyMG1vcmUlMjB1c2UlMjBjYXNlcy4lMEElMEElMjMlMjMlMjBXaGF0JTIwaXMlMjAlMjJNYXglMjB2aWN0aW1zJTIwdG8lMjBmaW5kJTIyJTNGJTBBJTBBVGhlJTIwTW9ua2V5JTIwaGFzJTIwYSUyMGZ1bmN0aW9uJTIwd2hpY2glMjBmaW5kcyUyMCUyMnZpY3RpbSUyMiUyMG1hY2hpbmVzJTIwb24lMjB0aGUlMjBuZXR3b3JrJTIwZm9yJTIwdGhlJTIwTW9ua2V5JTIwdG8lMjB0cnklMjBhbmQlMjBleHBsb2l0LiUyMEl0J3MlMjBjYWxsZWQlMjAlNjBnZXRfdmljdGltX21hY2hpbmVzJTYwLiUyMFRoaXMlMjBmdW5jdGlvbiUyMGFjY2VwdHMlMjBhbiUyMGFyZ3VtZW50JTIwd2hpY2glMjBsaW1pdHMlMjBob3clMjBtYW55JTIwbWFjaGluZXMlMjB0aGUlMjBNb25rZXklMjBzaG91bGQlMjBmaW5kLiUwQSUwQVdlJTIwd2FudCUyMHRvJTIwbWFrZSUyMHRoYXQlMjB2YWx1ZSUyMGVkaXRhYmxlJTIwYnklMjB0aGUlMjB1c2VyJTIwaW5zdGVhZCUyMG9mJTIwY29uc3RhbnQlMjBpbiUyMHRoZSUyMGNvZGUuJTBBJTBBJTIzJTIzJTIwTWFudWFsJTIwdGVzdGluZyUwQSUwQTEuJTIwQWZ0ZXIlMjB5b3UndmUlMjBwZXJmb3JtZWQlMjB0aGUlMjByZXF1aXJlZCUyMGNoYW5nZXMlMkMlMjByZWxvYWQlMjB0aGUlMjBTZXJ2ZXIlMjBhbmQlMjBjaGVjayUyMHlvdXIlMjB2YWx1ZSUyMGV4aXN0cyUyMGluJTIwdGhlJTIwSW50ZXJuYWwlMjB0YWIlMjBvZiUyMHRoZSUyMGNvbmZpZyUyMChzZWUlMjBpbWFnZSkuJTBBJTBBISU1QiU1RChodHRwcyUzQSUyRiUyRmkuaW1ndXIuY29tJTJGZTBYQXh1Vi5wbmcpJTBBJTBBMi4lMjBTZXQlMjB0aGUlMjBuZXclMjB2YWx1ZSUyMHRvJTIwMSUyQyUyMGFuZCUyMHJ1biUyME1vbmtleSUyMGxvY2FsbHklMjAoZnJvbSUyMHNvdXJjZSkuJTIwU2VlJTIwdGhhdCUyMHRoZSUyME1vbmtleSUyMG9ubHklMjBzY2FucyUyMG9uZSUyMG1hY2hpbmUu",
|
||||
"summary": "KiUyMFdoZW4lMjBjaGFuZ2luZyUyMGNvbmZpZyUyMHNjaGVtYSUyMGJ5JTIwYWRkaW5nJTIwb3IlMjBkZWxldGluZyUyMGtleXMlMkMlMjB5b3UlMjBuZWVkJTIwdG8lMjB1cGRhdGUlMjB0aGUlMjBCbGFja2JveCUyMFRlc3QlMjBjb25maWd1cmF0aW9ucyUyMGFzJTIwd2VsbCUyMCU1QmhlcmUlNUQoaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGZ3VhcmRpY29yZSUyRm1vbmtleSUyRnRyZWUlMkZkZXZlbG9wJTJGZW52cyUyRm1vbmtleV96b28lMkZibGFja2JveCUyRmlzbGFuZF9jb25maWdzKS4=",
|
||||
"diff": "ZGlmZiUyMC0tZ2l0JTIwYSUyRm1vbmtleSUyRmluZmVjdGlvbl9tb25rZXklMkZjb25maWcucHklMjBiJTJGbW9ua2V5JTJGaW5mZWN0aW9uX21vbmtleSUyRmNvbmZpZy5weSUwQWluZGV4JTIwMWZiY2I4NzYuLjY3ZWQxOWRlJTIwMTAwNjQ0JTBBLS0tJTIwYSUyRm1vbmtleSUyRmluZmVjdGlvbl9tb25rZXklMkZjb25maWcucHklMEElMkIlMkIlMkIlMjBiJTJGbW9ua2V5JTJGaW5mZWN0aW9uX21vbmtleSUyRmNvbmZpZy5weSUwQSU0MCU0MCUyMC0xMzElMkM5JTIwJTJCMTMxJTJDNiUyMCU0MCU0MCUyMGNsYXNzJTIwQ29uZmlndXJhdGlvbihvYmplY3QpJTNBJTBBJTIwJTIwJTIwJTIwJTIwZXhwbG9pdGVyX2NsYXNzZXMlMjAlM0QlMjAlNUIlNUQlMEElMjAlMjAlMjAlMjAlMjBzeXN0ZW1faW5mb19jb2xsZWN0b3JfY2xhc3NlcyUyMCUzRCUyMCU1QiU1RCUwQSUyMCUwQS0lMjAlMjAlMjAlMjAlMjMlMjBob3clMjBtYW55JTIwdmljdGltcyUyMHRvJTIwbG9vayUyMGZvciUyMGluJTIwYSUyMHNpbmdsZSUyMHNjYW4lMjBpdGVyYXRpb24lMEEtJTIwJTIwJTIwJTIwdmljdGltc19tYXhfZmluZCUyMCUzRCUyMDEwMCUwQS0lMEElMjAlMjAlMjAlMjAlMjAlMjMlMjBob3clMjBtYW55JTIwdmljdGltcyUyMHRvJTIwZXhwbG9pdCUyMGJlZm9yZSUyMHN0b3BwaW5nJTBBJTIwJTIwJTIwJTIwJTIwdmljdGltc19tYXhfZXhwbG9pdCUyMCUzRCUyMDEwMCUwQSUyMCUwQWRpZmYlMjAtLWdpdCUyMGElMkZtb25rZXklMkZpbmZlY3Rpb25fbW9ua2V5JTJGbW9ua2V5LnB5JTIwYiUyRm1vbmtleSUyRmluZmVjdGlvbl9tb25rZXklMkZtb25rZXkucHklMEFpbmRleCUyMDQ0NGJkZTQ1Li5mZjIzZjY3MSUyMDEwMDY0NCUwQS0tLSUyMGElMkZtb25rZXklMkZpbmZlY3Rpb25fbW9ua2V5JTJGbW9ua2V5LnB5JTBBJTJCJTJCJTJCJTIwYiUyRm1vbmtleSUyRmluZmVjdGlvbl9tb25rZXklMkZtb25rZXkucHklMEElNDAlNDAlMjAtMTU4JTJDNyUyMCUyQjE1OCUyQzclMjAlNDAlNDAlMjBjbGFzcyUyMEluZmVjdGlvbk1vbmtleShvYmplY3QpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBub3QlMjBzZWxmLl9rZWVwX3J1bm5pbmclMjBvciUyMG5vdCUyMFdvcm1Db25maWd1cmF0aW9uLmFsaXZlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwYnJlYWslMEElMjAlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWFjaGluZXMlMjAlM0QlMjBzZWxmLl9uZXR3b3JrLmdldF92aWN0aW1fbWFjaGluZXMobWF4X2ZpbmQlM0RXb3JtQ29uZmlndXJhdGlvbi52aWN0aW1zX21heF9maW5kJTJDJTBBJTJCJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWFjaGluZXMlMjAlM0QlMjBzZWxmLl9uZXR3b3JrLmdldF92aWN0aW1fbWFjaGluZXMobWF4X2ZpbmQlM0QxMDAlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzdG9wX2NhbGxiYWNrJTNEQ29udHJvbENsaWVudC5jaGVja19mb3Jfc3RvcCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpc19lbXB0eSUyMCUzRCUyMFRydWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBmb3IlMjBtYWNoaW5lJTIwaW4lMjBtYWNoaW5lcyUzQSUwQWRpZmYlMjAtLWdpdCUyMGElMkZtb25rZXklMkZtb25rZXlfaXNsYW5kJTJGY2MlMkZzZXJ2aWNlcyUyRmNvbmZpZ19zY2hlbWElMkZpbnRlcm5hbC5weSUyMGIlMkZtb25rZXklMkZtb25rZXlfaXNsYW5kJTJGY2MlMkZzZXJ2aWNlcyUyRmNvbmZpZ19zY2hlbWElMkZpbnRlcm5hbC5weSUwQWluZGV4JTIwYmRiYWUyNDYuLmQ2MDQyZDM1JTIwMTAwNjQ0JTBBLS0tJTIwYSUyRm1vbmtleSUyRm1vbmtleV9pc2xhbmQlMkZjYyUyRnNlcnZpY2VzJTJGY29uZmlnX3NjaGVtYSUyRmludGVybmFsLnB5JTBBJTJCJTJCJTJCJTIwYiUyRm1vbmtleSUyRm1vbmtleV9pc2xhbmQlMkZjYyUyRnNlcnZpY2VzJTJGY29uZmlnX3NjaGVtYSUyRmludGVybmFsLnB5JTBBJTQwJTQwJTIwLTQwJTJDMTIlMjAlMkI0MCUyQzYlMjAlNDAlNDAlMjBJTlRFUk5BTCUyMCUzRCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnRpdGxlJTIyJTNBJTIwJTIyTW9ua2V5JTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIydHlwZSUyMiUzQSUyMCUyMm9iamVjdCUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnByb3BlcnRpZXMlMjIlM0ElMjAlN0IlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIydmljdGltc19tYXhfZmluZCUyMiUzQSUyMCU3QiUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJ0aXRsZSUyMiUzQSUyMCUyMk1heCUyMHZpY3RpbXMlMjB0byUyMGZpbmQlMjIlMkMlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIydHlwZSUyMiUzQSUyMCUyMmludGVnZXIlMjIlMkMlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyZGVmYXVsdCUyMiUzQSUyMDEwMCUyQyUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJkZXNjcmlwdGlvbiUyMiUzQSUyMCUyMkRldGVybWluZXMlMjB0aGUlMjBtYXhpbXVtJTIwbnVtYmVyJTIwb2YlMjBtYWNoaW5lcyUyMHRoZSUyMG1vbmtleSUyMGlzJTIwYWxsb3dlZCUyMHRvJTIwc2NhbiUyMiUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJ2aWN0aW1zX21heF9leHBsb2l0JTIyJTNBJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIydGl0bGUlMjIlM0ElMjAlMjJNYXglMjB2aWN0aW1zJTIwdG8lMjBleHBsb2l0JTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIydHlwZSUyMiUzQSUyMCUyMmludGVnZXIlMjIlMkMlMEE=",
|
||||
"dod": "Make the max victim number that Monkey will find before stopping configurable by the user instead of constant.",
|
||||
"description": "# Make something configurable\n\nIn this unit, you will learn how to add a configuration option to Monkey and how to use it in the Monkey Agent code. \n\n![computer fire](https://media.giphy.com/media/7J4P7cUur2DlErijp3/giphy.gif \"computer fire\")\n\n## Why is this important?\n\nEnabling users to configure the Monkey's behaviour gives them a lot more freedom in how they want to use the Monkey and enables more use cases.\n\n## What is \"Max victims to find\"?\n\nThe Monkey has a function which finds \"victim\" machines on the network for the Monkey to try and exploit. It's called `get_victim_machines`. This function accepts an argument which limits how many machines the Monkey should find.\n\nWe want to make that value editable by the user instead of constant in the code.\n\n## Manual testing\n\n1. After you've performed the required changes, reload the Server and check your value exists in the Internal tab of the config (see image).\n\n![](https://i.imgur.com/e0XAxuV.png)\n\n2. Set the new value to 1, and run Monkey locally (from source). See that the Monkey only scans one machine.",
|
||||
"summary": "* When changing config schema by adding or deleting keys, you need to update the Blackbox Test configurations as well [here](https://github.com/guardicore/monkey/tree/develop/envs/monkey_zoo/blackbox/island_configs).",
|
||||
"hunksOrder": [
|
||||
"monkey/infection_monkey/config.py_0",
|
||||
"monkey/infection_monkey/monkey.py_0",
|
||||
"monkey/monkey_island/cc/services/config_schema/internal.py_0"
|
||||
],
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"Look for `victims_max_exploit` - it's rather similar."
|
||||
],
|
||||
"files": {
|
||||
"play_mode": "all",
|
||||
"swimmPatch": {
|
||||
"monkey/infection_monkey/config.py": {
|
||||
"index": [
|
||||
"1fbcb876..67ed19de",
|
||||
"100644"
|
||||
],
|
||||
"fileA": "monkey/infection_monkey/config.py",
|
||||
"fileB": "monkey/infection_monkey/config.py",
|
||||
"status": "MODIFIED",
|
||||
"numLineDeletions": 3,
|
||||
"numLineAdditions": 0,
|
||||
"hunkContainers": [
|
||||
"JTdCJTIyaHVuayUyMiUzQSU3QiUyMmhlYWRlciUyMiUzQSUyMiU0MCU0MCUyMC0xMzElMkM5JTIwJTJCMTMxJTJDNiUyMCU0MCU0MCUyMGNsYXNzJTIwQ29uZmlndXJhdGlvbihvYmplY3QpJTNBJTIyJTJDJTIyY2hhbmdlcyUyMiUzQSU1QiU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMGV4cGxvaXRlcl9jbGFzc2VzJTIwJTNEJTIwJTVCJTVEJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTMxJTJDJTIyYiUyMiUzQTEzMSU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMHN5c3RlbV9pbmZvX2NvbGxlY3Rvcl9jbGFzc2VzJTIwJTNEJTIwJTVCJTVEJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTMyJTJDJTIyYiUyMiUzQTEzMiU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTEzMyUyQyUyMmIlMjIlM0ExMzMlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIzJTIwaG93JTIwbWFueSUyMHZpY3RpbXMlMjB0byUyMGxvb2slMjBmb3IlMjBpbiUyMGElMjBzaW5nbGUlMjBzY2FuJTIwaXRlcmF0aW9uJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTM0JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmRlbCUyMiUyQyUyMm1hcmslMjIlM0ElMjItJTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMHZpY3RpbXNfbWF4X2ZpbmQlMjAlM0QlMjAxMDAlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0ExMzUlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTM2JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIzJTIwaG93JTIwbWFueSUyMHZpY3RpbXMlMjB0byUyMGV4cGxvaXQlMjBiZWZvcmUlMjBzdG9wcGluZyUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTEzNyUyQyUyMmIlMjIlM0ExMzQlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjB2aWN0aW1zX21heF9leHBsb2l0JTIwJTNEJTIwMTAwJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTM4JTJDJTIyYiUyMiUzQTEzNSU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTEzOSUyQyUyMmIlMjIlM0ExMzYlN0QlN0QlNUQlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0ElN0IlMjJzdGFydExpbmUlMjIlM0ExMzElMkMlMjJsaW5lc0NvdW50JTIyJTNBOSU3RCUyQyUyMmIlMjIlM0ElN0IlMjJzdGFydExpbmUlMjIlM0ExMzElMkMlMjJsaW5lc0NvdW50JTIyJTNBNiU3RCU3RCU3RCU3RA=="
|
||||
"diffType": "MODIFIED",
|
||||
"fileDiffHeader": "diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py\nindex 1fbcb876..67ed19de 100644\n--- a/monkey/infection_monkey/config.py\n+++ b/monkey/infection_monkey/config.py",
|
||||
"hunks": [
|
||||
{
|
||||
"swimmHunkMetadata": {
|
||||
"hunkComments": []
|
||||
},
|
||||
"hunkDiffLines": [
|
||||
"@@ -131,8 +131,6 @@",
|
||||
" exploiter_classes = []\r",
|
||||
" system_info_collector_classes = []\r",
|
||||
" \r",
|
||||
"- # how many victims to look for in a single scan iteration\r",
|
||||
"- victims_max_find = 100\r",
|
||||
" \r",
|
||||
" # how many victims to exploit before stopping\r",
|
||||
" victims_max_exploit = 100\r"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"monkey/infection_monkey/monkey.py": {
|
||||
"index": [
|
||||
"444bde45..ff23f671",
|
||||
"100644"
|
||||
],
|
||||
"fileA": "monkey/infection_monkey/monkey.py",
|
||||
"fileB": "monkey/infection_monkey/monkey.py",
|
||||
"status": "MODIFIED",
|
||||
"numLineDeletions": 1,
|
||||
"numLineAdditions": 1,
|
||||
"hunkContainers": [
|
||||
"JTdCJTIyaHVuayUyMiUzQSU3QiUyMmhlYWRlciUyMiUzQSUyMiU0MCU0MCUyMC0xNTglMkM3JTIwJTJCMTU4JTJDNyUyMCU0MCU0MCUyMGNsYXNzJTIwSW5mZWN0aW9uTW9ua2V5KG9iamVjdCklM0ElMjIlMkMlMjJjaGFuZ2VzJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBub3QlMjBzZWxmLl9rZWVwX3J1bm5pbmclMjBvciUyMG5vdCUyMFdvcm1Db25maWd1cmF0aW9uLmFsaXZlJTNBJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTU4JTJDJTIyYiUyMiUzQTE1OCU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGJyZWFrJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTU5JTJDJTIyYiUyMiUzQTE1OSU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTE2MCUyQyUyMmIlMjIlM0ExNjAlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWFjaGluZXMlMjAlM0QlMjBzZWxmLl9uZXR3b3JrLmdldF92aWN0aW1fbWFjaGluZXMobWF4X2ZpbmQlM0RXb3JtQ29uZmlndXJhdGlvbi52aWN0aW1zX21heF9maW5kJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTYxJTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmFkZCUyMiUyQyUyMm1hcmslMjIlM0ElMjIlMkIlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWFjaGluZXMlMjAlM0QlMjBzZWxmLl9uZXR3b3JrLmdldF92aWN0aW1fbWFjaGluZXMobWF4X2ZpbmQlM0QxMDAlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmIlMjIlM0ExNjElN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyY29udGV4dCUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzdG9wX2NhbGxiYWNrJTNEQ29udHJvbENsaWVudC5jaGVja19mb3Jfc3RvcCklMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0ExNjIlMkMlMjJiJTIyJTNBMTYyJTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaXNfZW1wdHklMjAlM0QlMjBUcnVlJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTYzJTJDJTIyYiUyMiUzQTE2MyU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZvciUyMG1hY2hpbmUlMjBpbiUyMG1hY2hpbmVzJTNBJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBMTY0JTJDJTIyYiUyMiUzQTE2NCU3RCU3RCU1RCUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQSU3QiUyMnN0YXJ0TGluZSUyMiUzQTE1OCUyQyUyMmxpbmVzQ291bnQlMjIlM0E3JTdEJTJDJTIyYiUyMiUzQSU3QiUyMnN0YXJ0TGluZSUyMiUzQTE1OCUyQyUyMmxpbmVzQ291bnQlMjIlM0E3JTdEJTdEJTdEJTdE"
|
||||
"diffType": "MODIFIED",
|
||||
"fileDiffHeader": "diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py\nindex 444bde45..ff23f671 100644\n--- a/monkey/infection_monkey/monkey.py\n+++ b/monkey/infection_monkey/monkey.py",
|
||||
"hunks": [
|
||||
{
|
||||
"swimmHunkMetadata": {
|
||||
"hunkComments": []
|
||||
},
|
||||
"hunkDiffLines": [
|
||||
"@@ -159,8 +159,6 @@",
|
||||
" if not self._keep_running or not WormConfiguration.alive:\r",
|
||||
" break\r",
|
||||
" \r",
|
||||
"- machines = self._network.get_victim_machines(max_find=WormConfiguration.victims_max_find,\r",
|
||||
"- stop_callback=ControlClient.check_for_stop)\r",
|
||||
" is_empty = True\r",
|
||||
" for machine in machines:\r",
|
||||
" if ControlClient.check_for_stop():\r"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"monkey/monkey_island/cc/services/config_schema/internal.py": {
|
||||
"index": [
|
||||
"bdbae246..d6042d35",
|
||||
"100644"
|
||||
],
|
||||
"fileA": "monkey/monkey_island/cc/services/config_schema/internal.py",
|
||||
"fileB": "monkey/monkey_island/cc/services/config_schema/internal.py",
|
||||
"status": "MODIFIED",
|
||||
"numLineDeletions": 6,
|
||||
"numLineAdditions": 0,
|
||||
"hunkContainers": [
|
||||
"JTdCJTIyaHVuayUyMiUzQSU3QiUyMmhlYWRlciUyMiUzQSUyMiU0MCU0MCUyMC00MCUyQzEyJTIwJTJCNDAlMkM2JTIwJTQwJTQwJTIwSU5URVJOQUwlMjAlM0QlMjAlN0IlMjIlMkMlMjJjaGFuZ2VzJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIydGl0bGUlNUMlMjIlM0ElMjAlNUMlMjJNb25rZXklNUMlMjIlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0MCUyQyUyMmIlMjIlM0E0MCU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMnR5cGUlNUMlMjIlM0ElMjAlNUMlMjJvYmplY3QlNUMlMjIlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0MSUyQyUyMmIlMjIlM0E0MSU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMnByb3BlcnRpZXMlNUMlMjIlM0ElMjAlN0IlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0MiUyQyUyMmIlMjIlM0E0MiU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJkZWwlMjIlMkMlMjJtYXJrJTIyJTNBJTIyLSUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUMlMjJ2aWN0aW1zX21heF9maW5kJTVDJTIyJTNBJTIwJTdCJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNDMlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIydGl0bGUlNUMlMjIlM0ElMjAlNUMlMjJNYXglMjB2aWN0aW1zJTIwdG8lMjBmaW5kJTVDJTIyJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNDQlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIydHlwZSU1QyUyMiUzQSUyMCU1QyUyMmludGVnZXIlNUMlMjIlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0NSU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJkZWwlMjIlMkMlMjJtYXJrJTIyJTNBJTIyLSUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUMlMjJkZWZhdWx0JTVDJTIyJTNBJTIwMTAwJTJDJTIyJTJDJTIybGluZU51bWJlcnMlMjIlM0ElN0IlMjJhJTIyJTNBNDYlN0QlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIyZGVsJTIyJTJDJTIybWFyayUyMiUzQSUyMi0lMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIyZGVzY3JpcHRpb24lNUMlMjIlM0ElMjAlNUMlMjJEZXRlcm1pbmVzJTIwdGhlJTIwbWF4aW11bSUyMG51bWJlciUyMG9mJTIwbWFjaGluZXMlMjB0aGUlMjBtb25rZXklMjBpcyUyMGFsbG93ZWQlMjB0byUyMHNjYW4lNUMlMjIlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0NyU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJkZWwlMjIlMkMlMjJtYXJrJTIyJTNBJTIyLSUyMiUyQyUyMmRhdGElMjIlM0ElMjIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0OCU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMnZpY3RpbXNfbWF4X2V4cGxvaXQlNUMlMjIlM0ElMjAlN0IlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E0OSUyQyUyMmIlMjIlM0E0MyU3RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJjb250ZXh0JTIyJTJDJTIyZGF0YSUyMiUzQSUyMiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1QyUyMnRpdGxlJTVDJTIyJTNBJTIwJTVDJTIyTWF4JTIwdmljdGltcyUyMHRvJTIwZXhwbG9pdCU1QyUyMiUyQyUyMiUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQTUwJTJDJTIyYiUyMiUzQTQ0JTdEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmNvbnRleHQlMjIlMkMlMjJkYXRhJTIyJTNBJTIyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVDJTIydHlwZSU1QyUyMiUzQSUyMCU1QyUyMmludGVnZXIlNUMlMjIlMkMlMjIlMkMlMjJsaW5lTnVtYmVycyUyMiUzQSU3QiUyMmElMjIlM0E1MSUyQyUyMmIlMjIlM0E0NSU3RCU3RCU1RCUyQyUyMmxpbmVOdW1iZXJzJTIyJTNBJTdCJTIyYSUyMiUzQSU3QiUyMnN0YXJ0TGluZSUyMiUzQTQwJTJDJTIybGluZXNDb3VudCUyMiUzQTEyJTdEJTJDJTIyYiUyMiUzQSU3QiUyMnN0YXJ0TGluZSUyMiUzQTQwJTJDJTIybGluZXNDb3VudCUyMiUzQTYlN0QlN0QlN0QlN0Q="
|
||||
"diffType": "MODIFIED",
|
||||
"fileDiffHeader": "diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py\nindex bdbae246..d6042d35 100644\n--- a/monkey/monkey_island/cc/services/config_schema/internal.py\n+++ b/monkey/monkey_island/cc/services/config_schema/internal.py",
|
||||
"hunks": [
|
||||
{
|
||||
"swimmHunkMetadata": {
|
||||
"hunkComments": []
|
||||
},
|
||||
"hunkDiffLines": [
|
||||
"@@ -40,12 +40,6 @@",
|
||||
" \"title\": \"Monkey\",\r",
|
||||
" \"type\": \"object\",\r",
|
||||
" \"properties\": {\r",
|
||||
"- \"victims_max_find\": {\r",
|
||||
"- \"title\": \"Max victims to find\",\r",
|
||||
"- \"type\": \"integer\",\r",
|
||||
"- \"default\": 100,\r",
|
||||
"- \"description\": \"Determines the maximum number of machines the monkey is allowed to scan\"\r",
|
||||
"- },\r",
|
||||
" \"victims_max_exploit\": {\r",
|
||||
" \"title\": \"Max victims to exploit\",\r",
|
||||
" \"type\": \"integer\",\r"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"app_version": "0.1.80",
|
||||
"file_version": "1.0.2"
|
||||
"app_version": "0.3.5-1",
|
||||
"file_version": "1.0.4",
|
||||
"last_commit_sha_for_swimm_patch": "17ee823b086f0b027612e2d1864930d2c5593c3e"
|
||||
}
|
|
@ -1,30 +1,54 @@
|
|||
{
|
||||
"id": "JFXftJml8DpmuCPBA9rL",
|
||||
"name": "Add details about your new PBA",
|
||||
"dod": "WW91JTIwc2hvdWxkJTIwYWRkJTIweW91ciUyMG5ldyUyMFBCQSdzJTIwZGV0YWlscyUyMHRvJTIwdGhlJTIwY29uZmlndXJhdGlvbi4=",
|
||||
"description": "SW4lMjBvcmRlciUyMHRvJTIwbWFrZSUyMHN1cmUlMjB0aGF0JTIwdGhlJTIwbmV3JTIwJTYwU2NoZWR1bGVKb2JzJTYwJTIwUEJBJTIwaXMlMjBzaG93biUyMGluJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMG9uJTIwdGhlJTIwTW9ua2V5JTIwSXNsYW5kJTJDJTIweW91JTIwbmVlZCUyMHRvJTIwYWRkJTIwaXRzJTIwZGV0YWlscyUyMHRvJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMGZpbGUocykuJTIwJTNDYnIlM0UlM0NiciUzRSUwQSUwQVNpbmNlJTIwdGhpcyUyMHBhcnRpY3VsYXIlMjBQQkElMjBpcyUyMHJlbGF0ZWQlMjB0byUyMHRoZSUyME1JVFJFJTIwdGVjaG5pcXVlcyUyMCU1QlQxMTY4JTVEKGh0dHBzJTNBJTJGJTJGYXR0YWNrLm1pdHJlLm9yZyUyRnRlY2huaXF1ZXMlMkZUMTE2OCklMjBhbmQlMjAlNUJUMTA1MyU1RChodHRwcyUzQSUyRiUyRmF0dGFjay5taXRyZS5vcmclMkZ0ZWNobmlxdWVzJTJGVDEwNTMpJTJDJTIwbWFrZSUyMHN1cmUlMjB0byUyMGxpbmslMjB0aGUlMjBQQkElMjB3aXRoJTIwdGhlc2UlMjB0ZWNobmlxdWVzJTIwaW4lMjB0aGUlMjBjb25maWd1cmF0aW9uJTIwYXMlMjB3ZWxsLiUyMCUzQ2JyJTNFJTNDYnIlM0UlMEElMEFFYWNoJTIwcGFydCUyMG9mJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMGhhcyUyMGFuJTIwaW1wb3J0YW50JTIwcm9sZSUyMCUyMCUwQS0lMjAqZW51bSolMjAlRTIlODAlOTQlMjBjb250YWlucyUyMHRoZSUyMHJlbGV2YW50JTIwUEJBJ3MlMjBjbGFzcyUyMG5hbWUocyklMEEtJTIwKnRpdGxlKiUyMCVFMiU4MCU5NCUyMGhvbGRzJTIwdGhlJTIwbmFtZSUyMG9mJTIwdGhlJTIwUEJBJTIwd2hpY2glMjBpcyUyMGRpc3BsYXllZCUyMGluJTIwdGhlJTIwY29uZmlndXJhdGlvbiUyMG9uJTIwdGhlJTIwTW9ua2V5JTIwSXNsYW5kJTBBLSUyMCppbmZvKiUyMCVFMiU4MCU5NCUyMGNvbnNpc3RzJTIwb2YlMjBhbiUyMGVsYWJvcmF0aW9uJTIwb24lMjB0aGUlMjBQQkEncyUyMHdvcmtpbmclMjB3aGljaCUyMGlzJTIwZGlzcGxheWVkJTIwaW4lMjB0aGUlMjBjb25maWd1cmF0aW9uJTIwb24lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMEEtJTIwKmF0dGFja190ZWNobmlxdWVzKiUyMCVFMiU4MCU5NCUyMGhhcyUyMHRoZSUyMElEcyUyMG9mJTIwdGhlJTIwTUlUUkUlMjB0ZWNobmlxdWVzJTIwYXNzb2NpYXRlZCUyMHdpdGglMjB0aGUlMjBQQkElMEElMEElMjMlMjMlMjBNYW51YWwlMjB0ZXN0JTIwJTIwJTBBT25jZSUyMHlvdSUyMHRoaW5rJTIweW91J3JlJTIwZG9uZS4uLiUwQS0lMjBSdW4lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMEEtJTIwWW91JTIwc2hvdWxkJTIwYmUlMjBhYmxlJTIwdG8lMjBzZWUlMjB5b3VyJTIwbmV3JTIwUEJBJTIwdW5kZXIlMjB0aGUlMjAlMjJNb25rZXklMjIlMjB0YWIlMjBpbiUyMHRoZSUyMGNvbmZpZ3VyYXRpb24lMkMlMjBhbG9uZyUyMHdpdGglMjBpdHMlMjBpbmZvcm1hdGlvbiUyMHdoZW4lMjB5b3UlMjBjbGljayUyMG9uJTIwaXQlMEEtJTIwRnVydGhlciUyQyUyMHdoZW4lMjB5b3UlMjBlbmFibGUlMkZkaXNhYmxlJTIwdGhlJTIwYXNzb2NpYXRlZCUyME1JVFJFJTIwdGVjaG5pcXVlcyUyMHVuZGVyJTIwdGhlJTIwQVRUJTI2Q0slMjB0YWIlMjBpbiUyMHRoZSUyMGNvbmZpZ3VyYXRpb24lMkMlMjB0aGUlMjBQQkElMjBzaG91bGQlMjBhbHNvJTIwYmUlMjBlbmFibGVkJTJGZGlzYWJsZWQlMEElMEElM0NpbWclMjBzcmMlM0QlMjJodHRwcyUzQSUyRiUyRmkuaW1ndXIuY29tJTJGYTVWU2tMNS5naWYlMjIlMjBoZWlnaHQlM0Q0MDAlM0U=",
|
||||
"summary": "LSUyMFRoZSUyMFBCQSUyMGRldGFpbHMlMjBpbiUyMHRoaXMlMjBmaWxlJTIwYXJlJTIwcmVmbGVjdGVkJTIwb24lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQlMjBpbiUyMHRoZSUyMFBCQSUyMGNvbmZpZ3VyYXRpb24uJTBBLSUyMFBCQXMlMjBhcmUlMjBhbHNvJTIwbGlua2VkJTIwdG8lMjB0aGUlMjByZWxldmFudCUyME1JVFJFJTIwdGVjaG5pcXVlcyUyMGluJTIwdGhpcyUyMGZpbGUlMkMlMjB3aG9zZSUyMHJlc3VsdHMlMjBjYW4lMjB0aGVuJTIwYmUlMjBzZWVuJTIwaW4lMjB0aGUlMjBNSVRSRSUyMEFUVCUyNkNLJTIwcmVwb3J0JTIwb24lMjB0aGUlMjBNb25rZXklMjBJc2xhbmQu",
|
||||
"diff": "ZGlmZiUyMC0tZ2l0JTIwYSUyRm1vbmtleSUyRm1vbmtleV9pc2xhbmQlMkZjYyUyRnNlcnZpY2VzJTJGY29uZmlnX3NjaGVtYSUyRmRlZmluaXRpb25zJTJGcG9zdF9icmVhY2hfYWN0aW9ucy5weSUyMGIlMkZtb25rZXklMkZtb25rZXlfaXNsYW5kJTJGY2MlMkZzZXJ2aWNlcyUyRmNvbmZpZ19zY2hlbWElMkZkZWZpbml0aW9ucyUyRnBvc3RfYnJlYWNoX2FjdGlvbnMucHklMEFpbmRleCUyMGYxZmUwZjZmLi5jY2UzN2IyNCUyMDEwMDY0NCUwQS0tLSUyMGElMkZtb25rZXklMkZtb25rZXlfaXNsYW5kJTJGY2MlMkZzZXJ2aWNlcyUyRmNvbmZpZ19zY2hlbWElMkZkZWZpbml0aW9ucyUyRnBvc3RfYnJlYWNoX2FjdGlvbnMucHklMEElMkIlMkIlMkIlMjBiJTJGbW9ua2V5JTJGbW9ua2V5X2lzbGFuZCUyRmNjJTJGc2VydmljZXMlMkZjb25maWdfc2NoZW1hJTJGZGVmaW5pdGlvbnMlMkZwb3N0X2JyZWFjaF9hY3Rpb25zLnB5JTBBJTQwJTQwJTIwLTYyJTJDMTUlMjAlMkI2MiUyQzclMjAlNDAlNDAlMjBQT1NUX0JSRUFDSF9BQ1RJT05TJTIwJTNEJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyUmVtb3ZlcyUyMHRoZSUyMGZpbGUlMjBhZnRlcndhcmRzLiUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmF0dGFja190ZWNobmlxdWVzJTIyJTNBJTIwJTVCJTIyVDExNjYlMjIlNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMkMlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTBBLSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnR5cGUlMjIlM0ElMjAlMjJzdHJpbmclMjIlMkMlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyZW51bSUyMiUzQSUyMCU1QiUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJTY2hlZHVsZUpvYnMlMjIlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVEJTJDJTBBLSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnRpdGxlJTIyJTNBJTIwJTIySm9iJTIwc2NoZWR1bGluZyUyMiUyQyUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJpbmZvJTIyJTNBJTIwJTIyQXR0ZW1wdHMlMjB0byUyMGNyZWF0ZSUyMGElMjBzY2hlZHVsZWQlMjBqb2IlMjBvbiUyMHRoZSUyMHN5c3RlbSUyMGFuZCUyMHJlbW92ZSUyMGl0LiUyMiUyQyUwQS0lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJhdHRhY2tfdGVjaG5pcXVlcyUyMiUzQSUyMCU1QiUyMlQxMTY4JTIyJTJDJTIwJTIyVDEwNTMlMjIlNUQlMEEtJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTJDJTBBJTJCJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwU3dpbW1lciUzQSUyMEFERCUyMERFVEFJTFMlMjBIRVJFISUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnR5cGUlMjIlM0ElMjAlMjJzdHJpbmclMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJlbnVtJTIyJTNBJTIwJTVCJTBB",
|
||||
"dod": "You should add your new PBA's details to the configuration.",
|
||||
"description": "In order to make sure that the new `ScheduleJobs` PBA is shown in the configuration on the Monkey Island, you need to add its details to the configuration file(s). <br><br>\n\nSince this particular PBA is related to the MITRE techniques [T1168](https://attack.mitre.org/techniques/T1168) and [T1053](https://attack.mitre.org/techniques/T1053), make sure to link the PBA with these techniques in the configuration as well. <br><br>\n\nEach part of the configuration has an important role \n- *enum* — contains the relevant PBA's class name(s)\n- *title* — holds the name of the PBA which is displayed in the configuration on the Monkey Island\n- *info* — consists of an elaboration on the PBA's working which is displayed in the configuration on the Monkey Island\n- *attack_techniques* — has the IDs of the MITRE techniques associated with the PBA\n\n## Manual test \nOnce you think you're done...\n- Run the Monkey Island\n- You should be able to see your new PBA under the \"Monkey\" tab in the configuration, along with its information when you click on it\n- Further, when you enable/disable the associated MITRE techniques under the ATT&CK tab in the configuration, the PBA should also be enabled/disabled\n\n<img src=\"https://i.imgur.com/a5VSkL5.gif\" height=400>",
|
||||
"summary": "- The PBA details in this file are reflected on the Monkey Island in the PBA configuration.\n- PBAs are also linked to the relevant MITRE techniques in this file, whose results can then be seen in the MITRE ATT&CK report on the Monkey Island.",
|
||||
"hunksOrder": [
|
||||
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py_0"
|
||||
],
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"Have a look at the details of the other techniques."
|
||||
],
|
||||
"files": {
|
||||
"play_mode": "all",
|
||||
"swimmPatch": {
|
||||
"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="
|
||||
"diffType": "MODIFIED",
|
||||
"fileDiffHeader": "diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py\nindex f1fe0f6f..b231f96c 100644\n--- a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py\n+++ b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
|
||||
"hunks": [
|
||||
{
|
||||
"swimmHunkMetadata": {
|
||||
"hunkComments": []
|
||||
},
|
||||
"hunkDiffLines": [
|
||||
"@@ -68,16 +68,7 @@",
|
||||
" \"Removes the file afterwards.\",",
|
||||
" \"attack_techniques\": [\"T1166\"]",
|
||||
" },",
|
||||
"- {",
|
||||
"+ # Swimmer: ADD DETAILS HERE!",
|
||||
"- \"type\": \"string\",",
|
||||
"- \"enum\": [",
|
||||
"- \"ScheduleJobs\"",
|
||||
"- ],",
|
||||
"- \"title\": \"Job scheduling\",",
|
||||
"- \"safe\": True,",
|
||||
"- \"info\": \"Attempts to create a scheduled job on the system and remove it.\",",
|
||||
"- \"attack_techniques\": [\"T1168\", \"T1053\"]",
|
||||
"- },",
|
||||
" {",
|
||||
" \"type\": \"string\",",
|
||||
" \"enum\": ["
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"app_version": "0.1.90",
|
||||
"file_version": "1.0.2"
|
||||
"app_version": "0.3.5-1",
|
||||
"file_version": "1.0.4",
|
||||
"hunksOrder": [
|
||||
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py_0"
|
||||
],
|
||||
"last_commit_sha_for_swimm_patch": "9d9e8168fb2c23367b9947273aa1a041687b3e2e"
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -4,18 +4,19 @@
|
|||
"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",
|
||||
"hunksOrder": [
|
||||
"monkey/infection_monkey/post_breach/actions/schedule_jobs.py_0"
|
||||
],
|
||||
"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",
|
||||
"play_mode": "all",
|
||||
"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",
|
||||
"fileDiffHeader": "diff --git a/monkey/infection_monkey/post_breach/actions/schedule_jobs.py b/monkey/infection_monkey/post_breach/actions/schedule_jobs.py\nindex f7d8d805..06839463 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": {
|
||||
|
@ -41,6 +42,8 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"app_version": "0.3.5-1",
|
||||
"file_version": "1.0.4",
|
||||
"hunksOrder": [
|
||||
"monkey/infection_monkey/post_breach/actions/schedule_jobs.py_0"
|
||||
],
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 101 KiB |
|
@ -12,6 +12,7 @@ EXPLOITER_CLASSES = {
|
|||
"SmbExploiter"
|
||||
],
|
||||
"title": "SMB Exploiter",
|
||||
"safe": True,
|
||||
"attack_techniques": ["T1110", "T1075", "T1035"],
|
||||
"info": "Brute forces using credentials provided by user and"
|
||||
" hashes gathered by mimikatz.",
|
||||
|
@ -23,6 +24,7 @@ EXPLOITER_CLASSES = {
|
|||
"WmiExploiter"
|
||||
],
|
||||
"title": "WMI Exploiter",
|
||||
"safe": True,
|
||||
"attack_techniques": ["T1110", "T1106"],
|
||||
"info": "Brute forces WMI (Windows Management Instrumentation) "
|
||||
"using credentials provided by user and hashes gathered by mimikatz.",
|
||||
|
@ -34,6 +36,7 @@ EXPLOITER_CLASSES = {
|
|||
"MSSQLExploiter"
|
||||
],
|
||||
"title": "MSSQL Exploiter",
|
||||
"safe": True,
|
||||
"attack_techniques": ["T1110"],
|
||||
"info": "Tries to brute force into MsSQL server and uses insecure "
|
||||
"configuration to execute commands on server.",
|
||||
|
@ -44,7 +47,8 @@ EXPLOITER_CLASSES = {
|
|||
"enum": [
|
||||
"Ms08_067_Exploiter"
|
||||
],
|
||||
"title": "MS08-067 Exploiter (UNSAFE)",
|
||||
"title": "MS08-067 Exploiter",
|
||||
"safe": False,
|
||||
"info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. "
|
||||
"Uses MS08-067 vulnerability.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/ms08-067/"
|
||||
|
@ -55,6 +59,7 @@ EXPLOITER_CLASSES = {
|
|||
"SSHExploiter"
|
||||
],
|
||||
"title": "SSH Exploiter",
|
||||
"safe": True,
|
||||
"attack_techniques": ["T1110", "T1145", "T1106"],
|
||||
"info": "Brute forces using credentials provided by user and SSH keys gathered from systems.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sshexec/"
|
||||
|
@ -65,6 +70,7 @@ EXPLOITER_CLASSES = {
|
|||
"ShellShockExploiter"
|
||||
],
|
||||
"title": "ShellShock Exploiter",
|
||||
"safe": True,
|
||||
"info": "CVE-2014-6271, based on logic from "
|
||||
"https://github.com/nccgroup/shocker/blob/master/shocker.py .",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/shellshock/"
|
||||
|
@ -75,6 +81,7 @@ EXPLOITER_CLASSES = {
|
|||
"SambaCryExploiter"
|
||||
],
|
||||
"title": "SambaCry Exploiter",
|
||||
"safe": True,
|
||||
"info": "Bruteforces and searches for anonymous shares. Uses Impacket.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sambacry/"
|
||||
},
|
||||
|
@ -84,6 +91,7 @@ EXPLOITER_CLASSES = {
|
|||
"ElasticGroovyExploiter"
|
||||
],
|
||||
"title": "ElasticGroovy Exploiter",
|
||||
"safe": True,
|
||||
"info": "CVE-2015-1427. Logic is based on Metasploit module.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/elasticgroovy/"
|
||||
},
|
||||
|
@ -93,6 +101,7 @@ EXPLOITER_CLASSES = {
|
|||
"Struts2Exploiter"
|
||||
],
|
||||
"title": "Struts2 Exploiter",
|
||||
"safe": True,
|
||||
"info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on "
|
||||
"https://www.exploit-db.com/exploits/41570 .",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/struts2/"
|
||||
|
@ -103,6 +112,7 @@ EXPLOITER_CLASSES = {
|
|||
"WebLogicExploiter"
|
||||
],
|
||||
"title": "WebLogic Exploiter",
|
||||
"safe": True,
|
||||
"info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/weblogic/"
|
||||
},
|
||||
|
@ -112,6 +122,7 @@ EXPLOITER_CLASSES = {
|
|||
"HadoopExploiter"
|
||||
],
|
||||
"title": "Hadoop/Yarn Exploiter",
|
||||
"safe": True,
|
||||
"info": "Remote code execution on HADOOP server with YARN and default settings. "
|
||||
"Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/"
|
||||
|
@ -122,6 +133,7 @@ EXPLOITER_CLASSES = {
|
|||
"VSFTPDExploiter"
|
||||
],
|
||||
"title": "VSFTPD Exploiter",
|
||||
"safe": True,
|
||||
"info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. "
|
||||
"Logic based on Metasploit module.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/"
|
||||
|
@ -132,6 +144,7 @@ EXPLOITER_CLASSES = {
|
|||
"DrupalExploiter"
|
||||
],
|
||||
"title": "Drupal Exploiter",
|
||||
"safe": True,
|
||||
"info": "Exploits a remote command execution vulnerability in a Drupal server,"
|
||||
"for which certain modules (such as RESTful Web Services) are enabled.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/drupal/"
|
||||
|
|
|
@ -10,6 +10,7 @@ FINGER_CLASSES = {
|
|||
"SMBFinger"
|
||||
],
|
||||
"title": "SMBFinger",
|
||||
"safe": True,
|
||||
"info": "Figures out if SMB is running and what's the version of it.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
|
@ -19,6 +20,7 @@ FINGER_CLASSES = {
|
|||
"SSHFinger"
|
||||
],
|
||||
"title": "SSHFinger",
|
||||
"safe": True,
|
||||
"info": "Figures out if SSH is running.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
|
@ -28,6 +30,7 @@ FINGER_CLASSES = {
|
|||
"PingScanner"
|
||||
],
|
||||
"title": "PingScanner",
|
||||
"safe": True,
|
||||
"info": "Tries to identify if host is alive and which OS it's running by ping scan."
|
||||
},
|
||||
{
|
||||
|
@ -36,6 +39,7 @@ FINGER_CLASSES = {
|
|||
"HTTPFinger"
|
||||
],
|
||||
"title": "HTTPFinger",
|
||||
"safe": True,
|
||||
"info": "Checks if host has HTTP/HTTPS ports open."
|
||||
},
|
||||
{
|
||||
|
@ -44,6 +48,7 @@ FINGER_CLASSES = {
|
|||
"MySQLFinger"
|
||||
],
|
||||
"title": "MySQLFinger",
|
||||
"safe": True,
|
||||
"info": "Checks if MySQL server is running and tries to get it's version.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
|
@ -53,6 +58,7 @@ FINGER_CLASSES = {
|
|||
"MSSQLFinger"
|
||||
],
|
||||
"title": "MSSQLFinger",
|
||||
"safe": True,
|
||||
"info": "Checks if Microsoft SQL service is running and tries to gather information about it.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
|
@ -62,6 +68,7 @@ FINGER_CLASSES = {
|
|||
"ElasticFinger"
|
||||
],
|
||||
"title": "ElasticFinger",
|
||||
"safe": True,
|
||||
"info": "Checks if ElasticSearch is running and attempts to find it's version.",
|
||||
"attack_techniques": ["T1210"]
|
||||
},
|
||||
|
@ -71,6 +78,7 @@ FINGER_CLASSES = {
|
|||
"WindowsServerFinger"
|
||||
],
|
||||
"title": "WindowsServerFinger",
|
||||
"safe": True,
|
||||
"info": "Checks if server is a Windows Server and tests if it is vulnerable to Zerologon.",
|
||||
"attack_techniques": ["T1210"]
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ POST_BREACH_ACTIONS = {
|
|||
"BackdoorUser"
|
||||
],
|
||||
"title": "Back door user",
|
||||
"safe": True,
|
||||
"info": "Attempts to create a new user on the system and delete it afterwards.",
|
||||
"attack_techniques": ["T1136"]
|
||||
},
|
||||
|
@ -19,6 +20,7 @@ POST_BREACH_ACTIONS = {
|
|||
"CommunicateAsNewUser"
|
||||
],
|
||||
"title": "Communicate as new user",
|
||||
"safe": True,
|
||||
"info": "Attempts to create a new user, create HTTPS requests as that user and delete the user "
|
||||
"afterwards.",
|
||||
"attack_techniques": ["T1136"]
|
||||
|
@ -29,6 +31,7 @@ POST_BREACH_ACTIONS = {
|
|||
"ModifyShellStartupFiles"
|
||||
],
|
||||
"title": "Modify shell startup files",
|
||||
"safe": True,
|
||||
"info": "Attempts to modify shell startup files, like ~/.profile, ~/.bashrc, ~/.bash_profile "
|
||||
"in linux, and profile.ps1 in windows. Reverts modifications done afterwards.",
|
||||
"attack_techniques": ["T1156", "T1504"]
|
||||
|
@ -39,6 +42,7 @@ POST_BREACH_ACTIONS = {
|
|||
"HiddenFiles"
|
||||
],
|
||||
"title": "Hidden files and directories",
|
||||
"safe": True,
|
||||
"info": "Attempts to create a hidden file and remove it afterward.",
|
||||
"attack_techniques": ["T1158"]
|
||||
},
|
||||
|
@ -48,6 +52,7 @@ POST_BREACH_ACTIONS = {
|
|||
"TrapCommand"
|
||||
],
|
||||
"title": "Trap",
|
||||
"safe": True,
|
||||
"info": "On Linux systems, attempts to trap an interrupt signal in order to execute a command "
|
||||
"upon receiving that signal. Removes the trap afterwards.",
|
||||
"attack_techniques": ["T1154"]
|
||||
|
@ -58,6 +63,7 @@ POST_BREACH_ACTIONS = {
|
|||
"ChangeSetuidSetgid"
|
||||
],
|
||||
"title": "Setuid and Setgid",
|
||||
"safe": True,
|
||||
"info": "On Linux systems, attempts to set the setuid and setgid bits of a new file. "
|
||||
"Removes the file afterwards.",
|
||||
"attack_techniques": ["T1166"]
|
||||
|
@ -68,6 +74,7 @@ POST_BREACH_ACTIONS = {
|
|||
"ScheduleJobs"
|
||||
],
|
||||
"title": "Job scheduling",
|
||||
"safe": True,
|
||||
"info": "Attempts to create a scheduled job on the system and remove it.",
|
||||
"attack_techniques": ["T1168", "T1053"]
|
||||
},
|
||||
|
@ -77,6 +84,7 @@ POST_BREACH_ACTIONS = {
|
|||
"Timestomping"
|
||||
],
|
||||
"title": "Timestomping",
|
||||
"safe": True,
|
||||
"info": "Creates a temporary file and attempts to modify its time attributes. Removes the file afterwards.",
|
||||
"attack_techniques": ["T1099"]
|
||||
},
|
||||
|
@ -86,7 +94,8 @@ POST_BREACH_ACTIONS = {
|
|||
"SignedScriptProxyExecution"
|
||||
],
|
||||
"title": "Signed script proxy execution",
|
||||
"info": "On Windows systems, attemps to execute an arbitrary file "
|
||||
"safe": False,
|
||||
"info": "On Windows systems, attempts to execute an arbitrary file "
|
||||
"with the help of a pre-existing signed script.",
|
||||
"attack_techniques": ["T1216"]
|
||||
},
|
||||
|
@ -96,6 +105,7 @@ POST_BREACH_ACTIONS = {
|
|||
"AccountDiscovery"
|
||||
],
|
||||
"title": "Account Discovery",
|
||||
"safe": True,
|
||||
"info": "Attempts to get a listing of user accounts on the system.",
|
||||
"attack_techniques": ["T1087"]
|
||||
},
|
||||
|
@ -105,6 +115,7 @@ POST_BREACH_ACTIONS = {
|
|||
"ClearCommandHistory"
|
||||
],
|
||||
"title": "Clear command history",
|
||||
"safe": False,
|
||||
"info": "Attempts to clear the command history.",
|
||||
"attack_techniques": ["T1146"]
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
|||
ENVIRONMENT_COLLECTOR
|
||||
],
|
||||
"title": "Environment collector",
|
||||
"safe": True,
|
||||
"info": "Collects information about machine's environment (on premise/GCP/AWS).",
|
||||
"attack_techniques": ["T1082"]
|
||||
},
|
||||
|
@ -25,6 +26,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
|||
MIMIKATZ_COLLECTOR
|
||||
],
|
||||
"title": "Mimikatz collector",
|
||||
"safe": True,
|
||||
"info": "Collects credentials from Windows credential manager.",
|
||||
"attack_techniques": ["T1003", "T1005"]
|
||||
},
|
||||
|
@ -34,6 +36,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
|||
AWS_COLLECTOR
|
||||
],
|
||||
"title": "AWS collector",
|
||||
"safe": True,
|
||||
"info": "If on AWS, collects more information about the AWS instance currently running on.",
|
||||
"attack_techniques": ["T1082"]
|
||||
},
|
||||
|
@ -43,6 +46,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
|||
HOSTNAME_COLLECTOR
|
||||
],
|
||||
"title": "Hostname collector",
|
||||
"safe": True,
|
||||
"info": "Collects machine's hostname.",
|
||||
"attack_techniques": ["T1082", "T1016"]
|
||||
},
|
||||
|
@ -52,6 +56,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
|||
PROCESS_LIST_COLLECTOR
|
||||
],
|
||||
"title": "Process list collector",
|
||||
"safe": True,
|
||||
"info": "Collects a list of running processes on the machine.",
|
||||
"attack_techniques": ["T1082"]
|
||||
},
|
||||
|
@ -61,6 +66,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
|||
AZURE_CRED_COLLECTOR
|
||||
],
|
||||
"title": "Azure credential collector",
|
||||
"safe": True,
|
||||
"info": "Collects password credentials from Azure VMs",
|
||||
"attack_techniques": ["T1003", "T1005"]
|
||||
}
|
||||
|
|
|
@ -1,121 +1,192 @@
|
|||
import React, {useState} from 'react';
|
||||
import React from 'react';
|
||||
import {Button, Card} from 'react-bootstrap';
|
||||
|
||||
import {Card, Button, Form} from 'react-bootstrap';
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faCheckSquare} from '@fortawesome/free-solid-svg-icons';
|
||||
import {faSquare} from '@fortawesome/free-regular-svg-icons';
|
||||
import {cloneDeep} from 'lodash';
|
||||
|
||||
import {getComponentHeight} from './utils/HeightCalculator';
|
||||
import {resolveObjectPath} from './utils/ObjectPathResolver';
|
||||
import InfoPane from './InfoPane';
|
||||
import {getDefaultPaneParams, InfoPane, WarningType} from './InfoPane';
|
||||
import {MasterCheckbox, MasterCheckboxState} from './MasterCheckbox';
|
||||
import ChildCheckboxContainer from './ChildCheckbox';
|
||||
import {getFullDefinitionByKey} from './JsonSchemaHelpers';
|
||||
|
||||
|
||||
function getSelectValuesAfterClick(valueArray, clickedValue) {
|
||||
if (valueArray.includes(clickedValue)) {
|
||||
return valueArray.filter((e) => {
|
||||
return e !== clickedValue;
|
||||
});
|
||||
} else {
|
||||
valueArray.push(clickedValue);
|
||||
return valueArray;
|
||||
}
|
||||
}
|
||||
|
||||
function onMasterCheckboxClick(checkboxValue, defaultArray, onChangeFnc) {
|
||||
if (checkboxValue) {
|
||||
onChangeFnc([]);
|
||||
} else {
|
||||
onChangeFnc(defaultArray);
|
||||
}
|
||||
}
|
||||
|
||||
// Definitions passed to components only contains value and label,
|
||||
// custom fields like "info" or "links" must be pulled from registry object using this function
|
||||
function getFullDefinitionsFromRegistry(refString, registry) {
|
||||
return getObjectFromRegistryByRef(refString, registry).anyOf;
|
||||
}
|
||||
|
||||
function getObjectFromRegistryByRef(refString, registry) {
|
||||
let refArray = refString.replace('#', '').split('/');
|
||||
return resolveObjectPath(refArray, registry);
|
||||
}
|
||||
|
||||
function getFullDefinitionByKey(refString, registry, itemKey) {
|
||||
let fullArray = getFullDefinitionsFromRegistry(refString, registry);
|
||||
return fullArray.filter(e => (e.enum[0] === itemKey))[0];
|
||||
}
|
||||
|
||||
function setPaneInfo(refString, registry, itemKey, setPaneInfoFnc) {
|
||||
let definitionObj = getFullDefinitionByKey(refString, registry, itemKey);
|
||||
setPaneInfoFnc({title: definitionObj.title, content: definitionObj.info, link: definitionObj.link});
|
||||
}
|
||||
|
||||
function getDefaultPaneParams(refString, registry) {
|
||||
let configSection = getObjectFromRegistryByRef(refString, registry);
|
||||
return ({title: configSection.title, content: configSection.description});
|
||||
}
|
||||
|
||||
function AdvancedMultiSelect(props) {
|
||||
const [masterCheckbox, setMasterCheckbox] = useState(true);
|
||||
function AdvancedMultiSelectHeader(props) {
|
||||
const {
|
||||
schema,
|
||||
id,
|
||||
options,
|
||||
value,
|
||||
required,
|
||||
disabled,
|
||||
readonly,
|
||||
multiple,
|
||||
autofocus,
|
||||
onChange,
|
||||
registry
|
||||
title,
|
||||
onCheckboxClick,
|
||||
checkboxState,
|
||||
hideReset,
|
||||
onResetClick
|
||||
} = props;
|
||||
const {enumOptions} = options;
|
||||
const [infoPaneParams, setInfoPaneParams] = useState(getDefaultPaneParams(schema.items.$ref, registry));
|
||||
getDefaultPaneParams(schema.items.$ref, registry);
|
||||
const selectValue = cloneDeep(value);
|
||||
|
||||
return (
|
||||
<div className={'advanced-multi-select'}>
|
||||
<Card.Header>
|
||||
<Button key={`${props.schema.title}-button`} value={value}
|
||||
variant={'link'} disabled={disabled}
|
||||
onClick={() => {
|
||||
onMasterCheckboxClick(masterCheckbox, schema.default, onChange);
|
||||
setMasterCheckbox(!masterCheckbox);
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={masterCheckbox ? faCheckSquare : faSquare}/>
|
||||
</Button>
|
||||
<span className={'header-title'}>{props.schema.title}</span>
|
||||
</Card.Header>
|
||||
<Form.Group
|
||||
style={{height: `${getComponentHeight(enumOptions.length)}px`}}
|
||||
id={id}
|
||||
multiple={multiple}
|
||||
className='choice-block form-control'
|
||||
required={required}
|
||||
disabled={disabled || readonly}
|
||||
autoFocus={autofocus}>
|
||||
{enumOptions.map(({value, label}, i) => {
|
||||
return (
|
||||
<Form.Group
|
||||
key={i}
|
||||
onClick={() => setPaneInfo(schema.items.$ref, registry, value, setInfoPaneParams)}>
|
||||
<Button value={value} variant={'link'} disabled={disabled}
|
||||
onClick={() => onChange(getSelectValuesAfterClick(selectValue, value))}>
|
||||
<FontAwesomeIcon icon={selectValue.includes(value) ? faCheckSquare : faSquare}/>
|
||||
</Button>
|
||||
<span className={'option-text'}>
|
||||
{label}
|
||||
</span>
|
||||
</Form.Group>
|
||||
);
|
||||
})}
|
||||
</Form.Group>
|
||||
<InfoPane title={infoPaneParams.title} body={infoPaneParams.content} link={infoPaneParams.link}/>
|
||||
</div>
|
||||
<Card.Header className="d-flex justify-content-between">
|
||||
<MasterCheckbox title={title} onClick={onCheckboxClick} checkboxState={checkboxState}/>
|
||||
<Button className={'reset-safe-defaults'} type={'reset'} variant={'warning'}
|
||||
hidden={hideReset} onClick={onResetClick}>
|
||||
Reset to safe defaults
|
||||
</Button>
|
||||
</Card.Header>
|
||||
);
|
||||
}
|
||||
|
||||
class AdvancedMultiSelect extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.defaultValues = props.schema.default;
|
||||
this.infoPaneRefString = props.schema.items.$ref;
|
||||
this.registry = props.registry;
|
||||
this.enumOptions = props.options.enumOptions.sort(this.compareOptions);
|
||||
|
||||
this.state = {
|
||||
masterCheckboxState: this.getMasterCheckboxState(props.value),
|
||||
hideReset: this.getHideResetState(props.value),
|
||||
infoPaneParams: getDefaultPaneParams(
|
||||
this.infoPaneRefString,
|
||||
this.registry,
|
||||
this.isUnsafeOptionSelected(this.props.value)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// Sort options alphabetically. "Unsafe" options float to the bottom"
|
||||
compareOptions = (a, b) => {
|
||||
// Apparently, you can use additive operators with boolean types. Ultimately,
|
||||
// the ToNumber() abstraction operation is called to convert the booleans to
|
||||
// numbers: https://tc39.es/ecma262/#sec-tonumeric
|
||||
if (this.isSafe(b.value) - this.isSafe(a.value) !== 0) {
|
||||
return this.isSafe(b.value) - this.isSafe(a.value);
|
||||
}
|
||||
|
||||
return a.value.localeCompare(b.value);
|
||||
}
|
||||
|
||||
onMasterCheckboxClick = () => {
|
||||
if (this.state.masterCheckboxState === MasterCheckboxState.ALL) {
|
||||
var newValues = [];
|
||||
} else {
|
||||
newValues = this.enumOptions.map(({value}) => value);
|
||||
}
|
||||
|
||||
this.props.onChange(newValues);
|
||||
this.setMasterCheckboxState(newValues);
|
||||
this.setHideResetState(newValues);
|
||||
this.setPaneInfoToDefault(this.isUnsafeOptionSelected(newValues));
|
||||
}
|
||||
|
||||
onChildCheckboxClick = (value) => {
|
||||
let selectValues = this.getSelectValuesAfterClick(value);
|
||||
this.props.onChange(selectValues);
|
||||
|
||||
this.setMasterCheckboxState(selectValues);
|
||||
this.setHideResetState(selectValues);
|
||||
}
|
||||
|
||||
getSelectValuesAfterClick(clickedValue) {
|
||||
const valueArray = cloneDeep(this.props.value);
|
||||
|
||||
if (valueArray.includes(clickedValue)) {
|
||||
return valueArray.filter(e => e !== clickedValue);
|
||||
} else {
|
||||
valueArray.push(clickedValue);
|
||||
return valueArray;
|
||||
}
|
||||
}
|
||||
|
||||
setMasterCheckboxState(selectValues) {
|
||||
this.setState(() => ({
|
||||
masterCheckboxState: this.getMasterCheckboxState(selectValues)
|
||||
}));
|
||||
}
|
||||
|
||||
getMasterCheckboxState(selectValues) {
|
||||
if (selectValues.length === 0) {
|
||||
return MasterCheckboxState.NONE;
|
||||
}
|
||||
|
||||
if (selectValues.length !== this.enumOptions.length) {
|
||||
return MasterCheckboxState.MIXED;
|
||||
}
|
||||
|
||||
return MasterCheckboxState.ALL;
|
||||
}
|
||||
|
||||
onResetClick = () => {
|
||||
this.props.onChange(this.defaultValues);
|
||||
this.setHideResetState(this.defaultValues);
|
||||
this.setMasterCheckboxState(this.defaultValues);
|
||||
this.setPaneInfoToDefault(this.isUnsafeOptionSelected(this.defaultValues));
|
||||
}
|
||||
|
||||
setHideResetState(selectValues) {
|
||||
this.setState(() => ({
|
||||
hideReset: this.getHideResetState(selectValues)
|
||||
}));
|
||||
}
|
||||
|
||||
getHideResetState(selectValues) {
|
||||
return !(this.isUnsafeOptionSelected(selectValues))
|
||||
}
|
||||
|
||||
isUnsafeOptionSelected(selectValues) {
|
||||
return !(selectValues.every((value) => this.isSafe(value)));
|
||||
}
|
||||
|
||||
isSafe = (itemKey) => {
|
||||
return getFullDefinitionByKey(this.infoPaneRefString, this.registry, itemKey).safe;
|
||||
}
|
||||
|
||||
setPaneInfo = (itemKey) => {
|
||||
let definitionObj = getFullDefinitionByKey(this.infoPaneRefString, this.registry, itemKey);
|
||||
this.setState(
|
||||
{
|
||||
infoPaneParams: {
|
||||
title: definitionObj.title,
|
||||
content: definitionObj.info,
|
||||
link: definitionObj.link,
|
||||
warningType: this.isSafe(itemKey) ? WarningType.NONE : WarningType.SINGLE
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
setPaneInfoToDefault(isUnsafeOptionSelected) {
|
||||
this.setState(() => ({
|
||||
infoPaneParams: getDefaultPaneParams(
|
||||
this.props.schema.items.$ref,
|
||||
this.props.registry,
|
||||
isUnsafeOptionSelected
|
||||
)
|
||||
}));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
schema,
|
||||
id,
|
||||
required,
|
||||
multiple,
|
||||
autofocus
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className={'advanced-multi-select'}>
|
||||
<AdvancedMultiSelectHeader title={schema.title}
|
||||
onCheckboxClick={this.onMasterCheckboxClick}
|
||||
checkboxState={this.state.masterCheckboxState}
|
||||
hideReset={this.state.hideReset} onResetClick={this.onResetClick}/>
|
||||
|
||||
<ChildCheckboxContainer id={id} multiple={multiple} required={required}
|
||||
autoFocus={autofocus} isSafe={this.isSafe}
|
||||
onPaneClick={this.setPaneInfo} onCheckboxClick={this.onChildCheckboxClick}
|
||||
selectedValues={this.props.value} enumOptions={this.enumOptions}/>
|
||||
|
||||
<InfoPane title={this.state.infoPaneParams.title}
|
||||
body={this.state.infoPaneParams.content}
|
||||
link={this.state.infoPaneParams.link}
|
||||
warningType={this.state.infoPaneParams.warningType}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AdvancedMultiSelect;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import React from 'react';
|
||||
import {Button, Form} from 'react-bootstrap';
|
||||
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faCheckSquare} from '@fortawesome/free-solid-svg-icons';
|
||||
import {faSquare} from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
import {getComponentHeight} from './utils/HeightCalculator';
|
||||
import WarningIcon from './WarningIcon';
|
||||
|
||||
function ChildCheckboxContainer(props) {
|
||||
const {
|
||||
enumOptions,
|
||||
id,
|
||||
multiple,
|
||||
required,
|
||||
autofocus,
|
||||
onPaneClick,
|
||||
onCheckboxClick,
|
||||
selectedValues,
|
||||
isSafe
|
||||
} = props;
|
||||
|
||||
return(
|
||||
<Form.Group
|
||||
style={{height: `${getComponentHeight(enumOptions.length)}px`}}
|
||||
id={id} multiple={multiple} className='choice-block form-control'
|
||||
required={required} autoFocus={autofocus}>
|
||||
{
|
||||
enumOptions.map(({value, label}, i) => {
|
||||
return (
|
||||
<ChildCheckbox key={i} onPaneClick={onPaneClick}
|
||||
onClick={onCheckboxClick} value={value}
|
||||
label={label} checkboxState={selectedValues.includes(value)}
|
||||
safe={isSafe(value)}/>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</Form.Group>
|
||||
);
|
||||
}
|
||||
|
||||
function ChildCheckbox(props) {
|
||||
const {
|
||||
onPaneClick,
|
||||
onClick,
|
||||
value,
|
||||
label,
|
||||
checkboxState,
|
||||
safe
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form.Group onClick={() => onPaneClick(value)}>
|
||||
<Button value={value} variant={'link'} onClick={() => onClick(value)}>
|
||||
<FontAwesomeIcon icon={checkboxState ? faCheckSquare : faSquare}/>
|
||||
</Button>
|
||||
<span key={'label'} className={'option-text'}>{label}</span>
|
||||
{!safe && <WarningIcon key="warning-icon"/>}
|
||||
</Form.Group>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChildCheckboxContainer;
|
|
@ -3,6 +3,24 @@ import React from 'react';
|
|||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faQuestionCircle} from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import {getObjectFromRegistryByRef} from './JsonSchemaHelpers';
|
||||
import WarningIcon from './WarningIcon';
|
||||
|
||||
const WarningType = {
|
||||
NONE: 0,
|
||||
SINGLE: 1,
|
||||
MULTIPLE: 2
|
||||
}
|
||||
|
||||
function getDefaultPaneParams(refString, registry, isUnsafeOptionSelected) {
|
||||
let configSection = getObjectFromRegistryByRef(refString, registry);
|
||||
return (
|
||||
{
|
||||
title: configSection.title,
|
||||
content: configSection.description,
|
||||
warningType: isUnsafeOptionSelected ? WarningType.Multiple : WarningType.NONE
|
||||
});
|
||||
}
|
||||
|
||||
function InfoPane(props) {
|
||||
return (
|
||||
|
@ -44,9 +62,36 @@ function getSubtitle(props) {
|
|||
function getBody(props) {
|
||||
return (
|
||||
<Card.Body className={'pane-body'}>
|
||||
{props.body}
|
||||
<span key={'body'}>{props.body}</span>
|
||||
{props.warningType !== WarningType.NONE && getWarning(props.warningType)}
|
||||
</Card.Body>
|
||||
)
|
||||
}
|
||||
|
||||
export default InfoPane
|
||||
function getWarning(warningType) {
|
||||
return (
|
||||
<div className={'info-pane-warning'} key={'warning'}>
|
||||
<WarningIcon/>{warningType === WarningType.SINGLE ? getSingleOptionWarning() : getMultipleOptionsWarning()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getSingleOptionWarning() {
|
||||
return (
|
||||
<span>This option may cause a system to become unstable or
|
||||
may change a system's state in undesirable ways. Therefore, this option
|
||||
is not recommended for use in production or other sensitive
|
||||
environments.</span>
|
||||
);
|
||||
}
|
||||
|
||||
function getMultipleOptionsWarning() {
|
||||
return (
|
||||
<span>Some options have been selected that may cause a system
|
||||
to become unstable or may change a system's state in undesirable ways.
|
||||
Running Infection Monkey in a production or other sensitive environment
|
||||
with this configuration is not recommended.</span>
|
||||
);
|
||||
}
|
||||
|
||||
export {getDefaultPaneParams, InfoPane, WarningType}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import {resolveObjectPath} from './utils/ObjectPathResolver';
|
||||
|
||||
function getFullDefinitionByKey(refString, registry, itemKey) {
|
||||
let fullArray = getFullDefinitionsFromRegistry(refString, registry);
|
||||
return fullArray.filter(e => (e.enum[0] === itemKey))[0];
|
||||
}
|
||||
|
||||
// Definitions passed to components only contains value and label,
|
||||
// custom fields like "info" or "links" must be pulled from registry object using this function
|
||||
function getFullDefinitionsFromRegistry(refString, registry) {
|
||||
return getObjectFromRegistryByRef(refString, registry).anyOf;
|
||||
}
|
||||
|
||||
function getObjectFromRegistryByRef(refString, registry) {
|
||||
let refArray = refString.replace('#', '').split('/');
|
||||
return resolveObjectPath(refArray, registry);
|
||||
}
|
||||
|
||||
export {getFullDefinitionByKey, getObjectFromRegistryByRef};
|
|
@ -0,0 +1,40 @@
|
|||
import React from 'react';
|
||||
import {Button} from 'react-bootstrap';
|
||||
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faCheckSquare} from '@fortawesome/free-solid-svg-icons';
|
||||
import {faMinusSquare} from '@fortawesome/free-solid-svg-icons';
|
||||
import {faSquare} from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
const MasterCheckboxState = {
|
||||
NONE: 0,
|
||||
MIXED: 1,
|
||||
ALL: 2
|
||||
}
|
||||
|
||||
function MasterCheckbox(props) {
|
||||
const {
|
||||
title,
|
||||
onClick,
|
||||
checkboxState
|
||||
} = props;
|
||||
|
||||
let newCheckboxIcon = faCheckSquare;
|
||||
|
||||
if (checkboxState === MasterCheckboxState.NONE) {
|
||||
newCheckboxIcon = faSquare;
|
||||
} else if (checkboxState === MasterCheckboxState.MIXED) {
|
||||
newCheckboxIcon = faMinusSquare;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'master-checkbox'}>
|
||||
<Button key={`${title}-button`} variant={'link'} onClick={onClick}>
|
||||
<FontAwesomeIcon icon={newCheckboxIcon}/>
|
||||
</Button>
|
||||
<span className={'header-title'}>{title}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export {MasterCheckboxState, MasterCheckbox};
|
|
@ -0,0 +1,11 @@
|
|||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons';
|
||||
import React from 'react';
|
||||
|
||||
function WarningIcon() {
|
||||
return (
|
||||
<FontAwesomeIcon className="warning-icon" icon={faExclamationTriangle}/>
|
||||
);
|
||||
}
|
||||
|
||||
export default WarningIcon;
|
|
@ -18,12 +18,14 @@
|
|||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.advanced-multi-select .card-header button {
|
||||
padding-top: 0;
|
||||
.advanced-multi-select .card-header .master-checkbox span {
|
||||
padding-bottom: 0.188rem;
|
||||
}
|
||||
|
||||
.advanced-multi-select .card-header .header-title {
|
||||
font-size: 1.2em;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.advanced-multi-select .choice-block .form-group {
|
||||
|
|
|
@ -27,3 +27,14 @@
|
|||
margin: 10px 15px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.info-pane-warning {
|
||||
margin-top: 1em;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.info-pane-warning .warning-icon {
|
||||
margin-top: .188em;
|
||||
margin-left: 0em;
|
||||
margin-right: .75em;
|
||||
}
|
||||
|
|
|
@ -57,3 +57,8 @@
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.warning-icon {
|
||||
text-transform: uppercase;
|
||||
color: #FFC107;
|
||||
margin-left: .75em;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue