Compare commits
10 Commits
985d7c9cbc
...
8ccbf4a2c7
Author | SHA1 | Date |
---|---|---|
Lili Pavelů | 8ccbf4a2c7 | |
Lili Pavelů | 5c6d047452 | |
Lili (Tlapka) | 8415320435 | |
Lili (Tlapka) | 22652402e1 | |
Lili (Tlapka) | 066c7f3305 | |
Lili (Tlapka) | ae6cc86bd4 | |
Lili (Tlapka) | 9750de29d8 | |
Lili (Tlapka) | 8517530807 | |
Lili (Tlapka) | 7c823315e9 | |
Lili (Tlapka) | b9fb065de5 |
56
README.md
56
README.md
|
@ -1,4 +1,14 @@
|
||||||
# Adaptive game assistant
|
# Adaptive game assistant
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> As of 2024, I'm archiving this repository and removing the adaptive game try-out section from the README.md.
|
||||||
|
> The information in this README.md was correct as of 2022, but as Vagrant, VirtualBox, Ansible and the applications
|
||||||
|
> used in individual games change, I can't guarantee that things will continue to work the way they did.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If you're a lector or an assistant of the PA197 course, you're probably looking for the the PA197 resources in the
|
||||||
|
> university Gitlab instead of this repository.
|
||||||
|
|
||||||
The adaptive game assistant is a Python program allowing easy deployment and playing of adaptive cybersecurity games.
|
The adaptive game assistant is a Python program allowing easy deployment and playing of adaptive cybersecurity games.
|
||||||
|
|
||||||
When bundled with a compatible game (and a few config files), the assistant
|
When bundled with a compatible game (and a few config files), the assistant
|
||||||
|
@ -25,6 +35,7 @@ Basic commands:
|
||||||
- (L)og - saves data from the game into a file.
|
- (L)og - saves data from the game into a file.
|
||||||
|
|
||||||
The project's wiki has a user guide with examples: [Assistant guide](https://github.com/SleepyLili/adaptive-game-assistant/wiki/Assistant-guide)
|
The project's wiki has a user guide with examples: [Assistant guide](https://github.com/SleepyLili/adaptive-game-assistant/wiki/Assistant-guide)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
The assistant requires Python 3.7 or higher to run.
|
The assistant requires Python 3.7 or higher to run.
|
||||||
|
|
||||||
|
@ -46,6 +57,13 @@ The adaptive game module contains:
|
||||||
- `hint_giver.py`. The `HintGiver` class keeps tracks of taken hints and gives new ones.
|
- `hint_giver.py`. The `HintGiver` class keeps tracks of taken hints and gives new ones.
|
||||||
- `level_selector.py`. The `LevelSelector` class helps decide which level to go to next.
|
- `level_selector.py`. The `LevelSelector` class helps decide which level to go to next.
|
||||||
|
|
||||||
|
## Game requirements
|
||||||
|
### Ansible tags
|
||||||
|
The assistant expects some things of the Ansible playbooks.
|
||||||
|
- All tasks should be tagged
|
||||||
|
- Tasks for game setup and the first level are tagged `setup`
|
||||||
|
- Tasks for level past the first are in the format `level + [number] + [branch, optional]` i.e. "level3", "level4a"
|
||||||
|
|
||||||
### Game config files
|
### Game config files
|
||||||
Besides tagged ansible playbooks, each adaptive game needs a few config files to work.
|
Besides tagged ansible playbooks, each adaptive game needs a few config files to work.
|
||||||
The config files are mostly YAML lists and dicts.
|
The config files are mostly YAML lists and dicts.
|
||||||
|
@ -59,18 +77,32 @@ The needed files are:
|
||||||
- `tools.yml`
|
- `tools.yml`
|
||||||
|
|
||||||
More about the config files and their format is on the wiki: [Config files](https://github.com/SleepyLili/adaptive-game-assistant/wiki/Config-files)
|
More about the config files and their format is on the wiki: [Config files](https://github.com/SleepyLili/adaptive-game-assistant/wiki/Config-files)
|
||||||
## I want to try out the assistant, but I don't have an adaptive game
|
|
||||||
The simplest way to try the assistant out with no access to another adaptive game is:
|
|
||||||
|
|
||||||
1. Download the [thesis archive](https://is.muni.cz/th/mnrr8/thesis-archive.zip) of my Adaptive Cybersecurity Games thesis.
|
|
||||||
2. In the archive, replace the `assistant/` folder with the folder of this repository.
|
|
||||||
(The assistant included with the thesis is an earlier version.)
|
|
||||||
3. Extract `game.zip` from the archive. (So that you have a `game/` folder.)
|
|
||||||
4. From the file `game/provisioning/roles/attacker/tasks/main.yml`, delete lines 34-39.
|
|
||||||
5. Run the assistant.
|
|
||||||
|
|
||||||
The assistant should run the game included with my thesis using the sample resources files.
|
|
||||||
The level instructions for that game are included in the `wiki/` subfolder of the thesis archive you downloaded.
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
All known common problems are in the [troubleshooting](https://github.com/SleepyLili/adaptive-game-assistant/wiki/Troubleshooting) doc on the repository wiki.
|
All known common problems are in the [troubleshooting](https://github.com/SleepyLili/adaptive-game-assistant/wiki/Troubleshooting) doc on the repository wiki.
|
||||||
|
|
||||||
|
## Possible improvements
|
||||||
|
Since the assistant needed to be ready and functional by a deadline,
|
||||||
|
there are some features that would have been nice to have, but weren't necessary
|
||||||
|
at the moment. Those features include:
|
||||||
|
|
||||||
|
- **A "manual mode" where the user gets to decide next level**
|
||||||
|
|
||||||
|
This would be similar to the original assistant prototype, where the user had the
|
||||||
|
teacher tell them what branch they were choosing. It would also simplify some testing
|
||||||
|
scenarios.
|
||||||
|
|
||||||
|
- **A "dry run mode" for testing**
|
||||||
|
|
||||||
|
Sometimes, it'd be nice to turn off the assistant's underlying calls to Vagrant,
|
||||||
|
to speed up testing of features, config files, etc.
|
||||||
|
|
||||||
|
- **The ability to turn off certain modules**
|
||||||
|
|
||||||
|
In a game without flags, or where flag checking isn't important, the flag
|
||||||
|
checker could be turned off, for example.
|
||||||
|
|
||||||
|
- **Better support for branching levels -- arbitrary names, shorter and longer playthroughs**
|
||||||
|
|
||||||
|
The assistant as it is right now expects the levels to have a naming convention, and it also expects that for every possible playthrough, there will always be the same number of levels.
|
||||||
|
Removing these constraints would make it possible to support games of variable length, or with entire "replacement" branches, etc.
|
||||||
|
|
92
assistant.py
92
assistant.py
|
@ -302,49 +302,63 @@ def game_loop():
|
||||||
print("Basic commands are:")
|
print("Basic commands are:")
|
||||||
print("(S)tart, (N)ext, (H)elp, (C)heck, (E)xit")
|
print("(S)tart, (N)ext, (H)elp, (C)heck, (E)xit")
|
||||||
while True:
|
while True:
|
||||||
print("Waiting for your input:")
|
try:
|
||||||
command = input()
|
print("Waiting for your input:")
|
||||||
command = command.lower()
|
command = input()
|
||||||
if command in ("a", "abort", "(a)bort"):
|
command = command.lower()
|
||||||
abort_game(game, hint_giver, flag_checker)
|
if command in ("a", "abort", "(a)bort"):
|
||||||
elif command in ("e", "exit"):
|
abort_game(game, hint_giver, flag_checker)
|
||||||
abort_game(game, hint_giver, flag_checker)
|
elif command in ("e", "exit"):
|
||||||
print("Exiting...")
|
abort_game(game, hint_giver, flag_checker)
|
||||||
return
|
print("Exiting...")
|
||||||
elif command in ("s", "start", "(s)tart"):
|
return
|
||||||
start_game(game, level_selector)
|
elif command in ("s", "start", "(s)tart"):
|
||||||
elif command in ("n", "next", "(n)ext"):
|
start_game(game, level_selector)
|
||||||
try:
|
elif command in ("n", "next", "(n)ext"):
|
||||||
if game.level == 0:
|
try:
|
||||||
print("Can't continue, (S)tart the game first!")
|
if game.level == 0:
|
||||||
elif game.level == 5:
|
print("Can't continue, (S)tart the game first!")
|
||||||
print("Can't continue, you are on the last level!")
|
elif game.level == 5:
|
||||||
print("Make sure to run (F)inish and (L)og your progress before exiting.")
|
print("Can't continue, you are on the last level!")
|
||||||
|
print("Make sure to run (F)inish and (L)og your progress before exiting.")
|
||||||
|
else:
|
||||||
|
if check_flag(game.level, flag_checker):
|
||||||
|
try_next_level(game, level_selector)
|
||||||
|
except NoLevelFoundError as err:
|
||||||
|
print("Error encountered: {}".format(err))
|
||||||
|
elif command in ("f", "finish", "(f)inish"):
|
||||||
|
if (not game.game_in_progress and not game.game_finished):
|
||||||
|
print("Can't finish game, game was not started yet.")
|
||||||
|
elif (not game.game_in_progress and game.game_finished):
|
||||||
|
print("Can't finish game, game was already finished earlier.")
|
||||||
else:
|
else:
|
||||||
if check_flag(game.level, flag_checker):
|
if check_flag(game.level, flag_checker):
|
||||||
try_next_level(game, level_selector)
|
finish_game(game)
|
||||||
except NoLevelFoundError as err:
|
elif command in ("i", "info", "information", "(i)nfo", "(i)nformation"):
|
||||||
print("Error encountered: {}".format(err))
|
game.print_info()
|
||||||
elif command in ("f", "finish", "(f)inish"):
|
elif command in ("h", "help", "(h)elp"):
|
||||||
if (not game.game_in_progress and not game.game_finished):
|
print_help()
|
||||||
print("Can't finish game, game was not started yet.")
|
elif command in ("c", "check", "(c)heck"):
|
||||||
elif (not game.game_in_progress and game.game_finished):
|
check_prerequisites()
|
||||||
print("Can't finish game, game was already finished earlier.")
|
elif command in ("l", "log", "(l)og"):
|
||||||
|
player_logging(game, hint_giver, flag_checker)
|
||||||
|
elif command in ("t", "hint", "hin(t)"):
|
||||||
|
give_hint(game, hint_giver)
|
||||||
else:
|
else:
|
||||||
if check_flag(game.level, flag_checker):
|
print("Unknown command. Enter another command or try (H)elp.")
|
||||||
finish_game(game)
|
except EOFError:
|
||||||
elif command in ("i", "info", "information", "(i)nfo", "(i)nformation"):
|
|
||||||
game.print_info()
|
|
||||||
elif command in ("h", "help", "(h)elp"):
|
|
||||||
print_help()
|
|
||||||
elif command in ("c", "check", "(c)heck"):
|
|
||||||
check_prerequisites()
|
|
||||||
elif command in ("l", "log", "(l)og"):
|
|
||||||
player_logging(game, hint_giver, flag_checker)
|
|
||||||
elif command in ("t", "hint", "hin(t)"):
|
|
||||||
give_hint(game, hint_giver)
|
|
||||||
else:
|
|
||||||
print("Unknown command. Enter another command or try (H)elp.")
|
print("Unknown command. Enter another command or try (H)elp.")
|
||||||
|
print("If you want to exit the assistant, please use the `exit` command.")
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("You sent a keyboard interrupt to the program.")
|
||||||
|
print("Would you like to exit?")
|
||||||
|
print("This will NOT save your log or end the game. yes/no")
|
||||||
|
confirmation = input()
|
||||||
|
confirmation = confirmation.lower()
|
||||||
|
if confirmation in ("y", "yes"):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print("Not exiting. Continuing normal operation.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -31,7 +31,7 @@ level4:
|
||||||
"Password cracking": "The password appears to be encrypted with a simple MD5 hash. A tool like John the Ripper, which is already installed on the computer, could be used to crack the password."
|
"Password cracking": "The password appears to be encrypted with a simple MD5 hash. A tool like John the Ripper, which is already installed on the computer, could be used to crack the password."
|
||||||
"Command line options": 'The arguments you will need to crack the password are "--format=" and "--wordlist="'
|
"Command line options": 'The arguments you will need to crack the password are "--format=" and "--wordlist="'
|
||||||
"Database interaction": "Use the [SQL] button in the web shell to interact with log into local databases and interact with them using SQL queries."
|
"Database interaction": "Use the [SQL] button in the web shell to interact with log into local databases and interact with them using SQL queries."
|
||||||
"Solution": "Place to hash in to_crack.txt. Run `john --format=raw-md5 --wordlist=passwords.txt to_crack.txt` to get the password."
|
"Solution": "Place the hash in to_crack.txt. Run `john --format=raw-md5 --wordlist=passwords.txt to_crack.txt` to get the password."
|
||||||
level5:
|
level5:
|
||||||
level5:
|
level5:
|
||||||
"Database interaction": "You can communicate with local databases using SQL queries."
|
"Database interaction": "You can communicate with local databases using SQL queries."
|
||||||
|
|
Reference in New Issue