Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor scenarios #20

Open
wants to merge 88 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
bf143be
Scenario 3
hkoushik Jun 19, 2024
1658aa2
Scenario 3
hkoushik Jun 19, 2024
39fd1bf
Merge branch 'main' into hk
hkoushik Jun 19, 2024
74fc2d5
Merge pull request #5 from PaloAltoNetworks/hk
hkoushik Jun 19, 2024
21161b3
Update scen-3 destory
hkoushik Jun 19, 2024
f0bdd1f
Merge pull request #6 from PaloAltoNetworks/hhk
hkoushik Jun 19, 2024
eecc944
Scenario 4 Updates
hkoushik Jun 25, 2024
9661297
Merge pull request #7 from PaloAltoNetworks/scen-4
hkoushik Jun 25, 2024
d420e76
Fix ascii cobra
hkoushik Jun 25, 2024
5c36ce0
Merge pull request #8 from PaloAltoNetworks/scen-4
hkoushik Jun 25, 2024
157a2ce
update scenario-4
hkoushik Jun 27, 2024
7cdc066
Update scenario_4.py
hkoushik Jun 27, 2024
c2c49fb
Update .gitignore
hkoushik Jun 27, 2024
7139cf1
Merge pull request #10 from PaloAltoNetworks/scen-4
hkoushik Jun 27, 2024
1e8236f
scen4
hkoushik Jun 27, 2024
5623597
Delete core/gcp-scenario-1-output.json
hkoushik Jun 27, 2024
7fb3483
Changin folder location to be absolute
amit-schnitzer Jul 3, 2024
35d25a6
Added absolute path tracking
amit-schnitzer Jul 4, 2024
40c0692
Improving directory handling
amit-schnitzer Jul 4, 2024
96b942e
cleaning debug steps
amit-schnitzer Jul 4, 2024
04422ba
Delete first-project/Pulumi.yaml
amit-schnitzer Jul 4, 2024
4cc8461
Delete first-project/Pulumi.dev.yaml
amit-schnitzer Jul 4, 2024
1f80e17
Update scenario_1.py
amit-schnitzer Jul 4, 2024
2b844c1
Fix images location
amit-schnitzer Jul 4, 2024
b2d1673
Adding Instance names (for ease of identification)
amit-schnitzer Jul 4, 2024
09fa21b
Adding instance names
amit-schnitzer Jul 4, 2024
f1c4a62
Another typo with instance name
amit-schnitzer Jul 4, 2024
6921c59
removing '/'
amit-schnitzer Jul 4, 2024
91c55ba
Added breakpoint to debug extra instance creation
amit-schnitzer Jul 4, 2024
6d40542
Trying to reduce breakpoints to 1
amit-schnitzer Jul 4, 2024
5ef76d3
Removing pdb trace
amit-schnitzer Jul 4, 2024
1b7f35a
Added instance name to the anomolous server as well
amit-schnitzer Jul 4, 2024
b82a4fb
Adding ""
amit-schnitzer Jul 4, 2024
0ba1a09
changed to '
amit-schnitzer Jul 4, 2024
cb5a115
changing aws ec2 create command concatination
amit-schnitzer Jul 4, 2024
950ccfc
Added permission to create ec2 tags
amit-schnitzer Jul 4, 2024
3de4fde
remove ')' from instances names
amit-schnitzer Jul 5, 2024
44548e5
Added 'pulumi import' command to import that instance into pulumi so …
amit-schnitzer Jul 5, 2024
73943e1
...
amit-schnitzer Jul 5, 2024
f1945ab
Continue handlind pulumi import for the anomalous server that is laun…
amit-schnitzer Jul 5, 2024
db9f3e5
trying different approach
amit-schnitzer Jul 5, 2024
8da243c
fix typo
amit-schnitzer Jul 5, 2024
619b96f
added ls and pwd commands
amit-schnitzer Jul 5, 2024
9e0cae6
Merge pull request #11 from schnitz-air/main
anandtiwarics Jul 9, 2024
3374743
remove the hard-coded path
sgordon46 Jul 9, 2024
5828811
Readme updated with Prerequisites
sgordon46 Jul 9, 2024
77c0869
Merge pull request #14 from sgordon46/update-readme
anandtiwarics Jul 10, 2024
289f45b
added cobra logo
anandtiwarics Jul 10, 2024
e30fa8a
Updated README file
anandtiwarics Jul 10, 2024
1d319ec
updated readme file with image width
anandtiwarics Jul 10, 2024
02ff4e2
updated report logo link
anandtiwarics Jul 10, 2024
bac946e
removed tmp logo
anandtiwarics Jul 10, 2024
4b0c268
updated report script
anandtiwarics Jul 10, 2024
d2daeba
fix issue 12 and some other QOL items
sgordon46 Jul 10, 2024
bfb211e
remove extra .gitignore
sgordon46 Jul 10, 2024
bfbec45
hide pulumi output
anandtiwarics Jul 12, 2024
76ff6e3
Merge pull request #15 from sgordon46/path-logic
anandtiwarics Jul 12, 2024
7d15f03
scen 2 changes
hkoushik Jul 15, 2024
2aa6109
Add --no-cli-pager flag to blocking AWS cli commands. Fixes #17
mdorn Jul 19, 2024
6cf22d7
Merge pull request #18 from mdorn/unblock-scenario-2
anandtiwarics Jul 22, 2024
56e8cbe
Add example scenario with extensively refactored logic
mdorn Jul 24, 2024
a006674
Add progress bar sleep to attack method
mdorn Jul 26, 2024
e174634
Revert "Add progress bar sleep to attack method"
mdorn Jul 26, 2024
76551d1
Add progress bar sleep to attack method
mdorn Jul 26, 2024
f7156d2
Minor cleanup including removing unnecessary code comments
mdorn Jul 26, 2024
70c319d
Refactor scenario 2
mdorn Jul 28, 2024
456109f
Refactor reporting
mdorn Jul 28, 2024
57908c8
Merge branch 'PaloAltoNetworks:main' into refactor-scenarios
mdorn Jul 28, 2024
2fb1340
Clean up unneeded code, various other cleanup
mdorn Jul 29, 2024
7852c2b
Merge branch 'refactor-scenarios' of github.com:mdorn/cobra-tool into…
mdorn Jul 29, 2024
8012e12
Remove unneeded Pulumi program
mdorn Aug 23, 2024
6c8e2f0
Refactor scenario 1
mdorn Aug 27, 2024
11676d4
Add boto3 lib to requirements
mdorn Aug 27, 2024
bdaa656
Scenario 5 init
hkoushik Jul 15, 2024
d3867ac
infra updates scen 5
hkoushik Jul 15, 2024
785198f
Infra roll out
hkoushik Jul 16, 2024
36346c5
scenario 5 updates
hkoushik Jul 16, 2024
9c6a275
Update infra
hkoushik Jul 16, 2024
687b966
updating scenario 5
hkoushik Jul 17, 2024
0ddeaed
KMS Update
hkoushik Jul 31, 2024
866e500
Same acc kms
hkoushik Jul 31, 2024
4de577d
Scen 6 init
hkoushik Aug 2, 2024
b47da11
Init Scenario 6
hkoushik Aug 7, 2024
4d99e8c
updated readme file
anandtiwarics Aug 13, 2024
b9c5a80
Add example scenario with extensively refactored logic
mdorn Jul 24, 2024
2aa085b
Add progress bar sleep to attack method
mdorn Jul 26, 2024
0715dad
Clean up unneeded code, various other cleanup
mdorn Jul 29, 2024
04c37d9
Add SSH helper, refactor helpers
mdorn Sep 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,16 @@ terraform.tfstate.backup

*aws-scenario-1-output.json
*aws-scenario-2-output.json
*aws-scenario-*
*gcp-scenario*
*token.txt
*cobra-as1-report.html
*cobra-as2-report.html
*cnbas-as1-report.html
*cnbas-as2-report.html
*cnbas-as2-report.html


files/var/logs/*
files/var/output/*
files/var/reports/*
!.gitkeep
37 changes: 25 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h2 align="center">🚀 Cloud Offensive Breach and Risk Assessment (COBRA) Tool 👩‍💻</h2>

<!-- <p align="center">
<img width="396" alt="cobra" src="https://github.com/PaloAltoNetworks/cobra-tool/assets/4271325/f618c9c8-4f3f-48ca-848b-c51b53e4e366">
<img width="300" alt="cobra" src="https://raw.githubusercontent.com/PaloAltoNetworks/cobra-tool/main/core/cobra-logo.png">
</p> -->

[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
Expand Down Expand Up @@ -37,8 +37,13 @@ It facilitates Proof of Concept (POC) evaluations, assesses security controls, m

- Python 3.8+
- pip3
- Pulumi Account
- AWS CLI
- Pulumi CLI [Docs](https://www.pulumi.com/docs/install/)
- Pulumi Account [here](https://www.pulumi.com/)
- Create Pulumi Personal Access Token [Docs](https://www.pulumi.com/docs/pulumi-cloud/access-management/access-tokens/#creating-personal-access-tokens)
- Use shell to login to Pulumi `$pulumi login` (Paste access token) [Docs](https://www.pulumi.com/docs/cli/commands/pulumi_login/)
- AWS CLI installed
- Will use the default profile credentials unless defined with the environment variables `AWS_PROFILE` and `AWS_REGION`
- Must have the region defined.
- Azure CLI
- Google Cloud SDK

Expand Down Expand Up @@ -104,6 +109,8 @@ options:
Scenario selection
```

>>Note* ONLY RUN INTO SANDBOX ENVIRONMENT

#### Simulate AWS Scenario

```
Expand All @@ -112,16 +119,19 @@ python3 cobra.py aws launch --simulation


```
____ ___ ____ ____ _
/ ___/ _ \| __ )| _ \ / \
| | | | | | _ \| |_) | / _ \
| |__| |_| | |_) | _ < / ___ \
\____\___/|____/|_| \_\/_/ \_\
____ ___ ____ ____ _
/ ___| / _ \ | __ ) | _ \ / \
| | | | | | | _ \ | |_) | / _ \
| |___ | |_| | | |_) | | _ < / ___ \
\____| \___/ |____/ |_| \_\ /_/ \_\


Select Attack Scenario of aws:
1. Exploit Vulnerable Application, EC2 takeover, Credential Exfiltration & Anomalous Compute Provisioning
2. Rest API exploit - command injection, credential exfiltration from backend lambda and privilige escalation, rogue identity creation & persistence
3. Compromising a web app living inside a GKE Pod, access pod secret, escalate privilege, take over the cluster
4. Exfiltrate EC2 role credentials using IMDSv2 with least privileged access
5. Instance takeover, abuse s3 access & perform ransomware using external KMS key
Enter your choice:

```
Expand All @@ -142,13 +152,16 @@ python3 cobra.py aws destroy --scenario <scenario-1/scenario-2>

1. Exploit Vulnerable Application, EC2 takeover, Credential Exfiltration & Anomalous Compute Provisioning
2. Rest API exploit - command injection, credential exfiltration from backend lambda and privilige escalation, rogue identity creation & persistence
3. Compromising a web app living inside a GKE Pod, access pod secret, escalate privilege, take over the cluster
4. Exfiltrate EC2 role credentials using IMDSv2 with least privileged access
5. Instance takeover, abuse s3 access & perform ransomware using external KMS key

### To Do / In Roadmap

3. Compromising a GKE Pod and accessing cluster secrets, taking over the cluster & escalating privileges at the Project level, possible project takeover.
4. Azure App exploit on a function, data exfiltration from Blob storage & abusing function misconfigs to escalate privileges & leaving a backdoor IAM entity.
5. Exploiting an App on VM, exfiltration of data from Cosmos DB & possible takeover of a resource group.
6. More scenarios loading...

- Azure App exploit on a function, data exfiltration from Blob storage & abusing function misconfigs to escalate privileges & leaving a backdoor IAM entity.
- Exploiting an App on VM, exfiltration of data from Cosmos DB & possible takeover of a resource group.
- More scenarios loading...

## License

Expand Down
18 changes: 6 additions & 12 deletions cobra.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
import argparse

from core import main
import pyfiglet
from termcolor import colored
from helpers.main import get_scenario_list

def display_banner():
ascii_art = pyfiglet.figlet_format("COBRA")
print(colored(ascii_art, color="cyan"))

def parse_arguments():
scenarios = get_scenario_list()
parser = argparse.ArgumentParser(description="Terminal-based option tool")
parser.add_argument("cloud_provider", choices=["aws", "azure", "gcp"], help="Cloud provider (aws, azure, gcp)")
parser.add_argument("action", choices=["launch", "status", "destroy"], help="Action to perform (launch, status, destroy)")
parser.add_argument("--simulation", action="store_true", help="Enable simulation mode")
parser.add_argument("--scenario", choices=["scenario-1", "scenario-2"], default="scenario-1", help="Scenario selection")
parser.add_argument("--scenario", choices=scenarios, default=scenarios[0], help="Scenario selection")
return parser.parse_args()


def main_function(cloud_provider, action, simulation, scenario):
# Call the main function from the imported module and pass the options
main.main(cloud_provider, action, simulation, scenario)


if __name__ == "__main__":
display_banner()
args = parse_arguments()

# Convert argparse Namespace to dictionary
options = vars(args)

# Call the main function with options
main_function(**options)
Binary file removed core/cnbas-logo.png
Binary file not shown.
34 changes: 0 additions & 34 deletions core/helpers.py

This file was deleted.

128 changes: 45 additions & 83 deletions core/main.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,60 @@
import os
import pyfiglet
import time
import subprocess
import json
from tqdm import tqdm
from time import sleep
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""Module providing a class for encapsulating COBRA scenarios."""
from termcolor import colored
from .report import gen_report
from .report import gen_report_2
from scenarios.scenario_1.scenario_1 import scenario_1_execute
from scenarios.scenario_2.scenario_2 import scenario_2_execute
from scenarios.scenario_2.scenario_2 import scenario_2_destroy

def loading_animation():
chars = "/—\\|"
for _ in range(10):
for char in chars:
print(f"\rLoading {char}", end="", flush=True)
time.sleep(0.1)
from core.scenario import Scenario
from helpers.main import print_ascii_art, get_scenarios_config

def select_cloud_provider():
print(colored("Select Cloud Provider:", color="yellow"))
print(colored("1. AWS", color="green"))
print(colored("2. Azure", color="green"))
print(colored("3. GCP", color="green"))
while True:
try:
choice = int(input(colored("Enter your choice (1/2/3): ", color="yellow")))
if choice not in [1, 2, 3]:
raise ValueError(colored("Invalid choice. Please enter 1, 2, or 3.", color="red"))
return choice
except ValueError as e:
print(e)

def select_attack_scenario(cloud_provider):
print(colored("Select Attack Scenario of %s:", color="yellow") % cloud_provider)
print(colored("1. Exploit Vulnerable Application, EC2 takeover, Credential Exfiltration & Anomalous Compute Provisioning", color="green"))
print(colored("2. Rest API exploit - command injection, credential exfiltration from backend lambda and privilige escalation, rogue identity creation & persistence", color="green"))
"""Get attack scenario config."""
scenarios_config = get_scenarios_config()
keys = list(scenarios_config.keys())
keys.sort()
print(colored('Select Attack Scenario of %s:', color='yellow') % cloud_provider)
choices = []
for key in keys:
index = int(key[-1:])
choices.append(index)
print(colored('{}. {}: {}'.format(
index, scenarios_config[key]['title'], scenarios_config[key]['description']),
color='green'))
while True:
try:
choice = int(input(colored("Enter your choice: ", color="yellow")))
if choice not in [1, 2]:
raise ValueError(colored("Invalid choice. Please enter 1 or 2.", color="red"))
choice = int(input(colored('Enter your choice: ', color='yellow')))
if choice not in choices:
raise ValueError(colored('Invalid choice.', color='red'))
return choice
except ValueError as e:
print(e)

def get_credentials():
while True:
try:
access_key = input(colored("Enter Access Key: ", color="yellow"))
if not access_key:
raise ValueError(colored("Access Key cannot be empty.", color="red"))
secret_key = input(colored("Enter Secret Key: ", color="yellow"))
if not secret_key:
raise ValueError(colored("Secret Key cannot be empty.", color="red"))
return access_key, secret_key
except ValueError as e:
print(e)

def execute_scenario(x):
try:
# Call the scenario function from the imported module
if x == 1:
scenario_1_execute()
elif x == 2:
scenario_2_execute()
else:
print("Invalid Scenario Selected")
print(colored("Scenario executed successfully!", color="green"))
except Exception as e:
print(colored("Error executing scenario:", color="red"), str(e))

def main(cloud_provider, action, simulation, scenario):
if cloud_provider == 'aws':
if action == 'launch':
if simulation is True:
scenario_choice = select_attack_scenario(cloud_provider)
if scenario_choice == 1:
# Pass the selected scenario module to execute
execute_scenario(1)
elif scenario_choice == 2:
execute_scenario(2)
#print(colored("Scenario coming soon!", color="yellow"))
elif action == 'status' and scenario == "scenario-1":
subprocess.call("cd ./scenarios/scenario_1/infra/ && pulumi stack ls", shell=True)
elif action == 'status' and scenario == "scenario-2":
subprocess.call("cd ./scenarios/scenario_2/infra/ && pulumi stack ls", shell=True)
elif action == 'destroy' and scenario == "scenario-1":
subprocess.call("cd ./scenarios/scenario_1/infra && pulumi destroy", shell=True)
elif action == 'destroy' and scenario == "scenario-2":
scenario_2_destroy()
else:
print('No options provided. --help to know more')
"""Instantiate and run an attack scenario."""
tool_name = 'C O B R A'
print_ascii_art(tool_name)
scenario_choice = select_attack_scenario(cloud_provider)
scenario = Scenario(scenario_choice)
if action == 'launch':
if simulation:
# TODO: what to do with cloud provider?
# scenario.setup()
scenario.attack()
# scenario.destroy()
# TODO: ^^^ do we really want to destroy the infra immediately?
# there's a separate command for destroy
scenario.generate_report() # TODO: not implemented
elif action == 'status':
# TODO
# subprocess.call('cd ./scenarios/scenario_2/infra/ && pulumi stack ls', shell=True)
pass
elif action == 'destroy':
scenario.destroy()
pass
else:
print('No options provided. --help to know more')


if __name__ == "__main__":
if __name__ == '__main__':
main()
5 changes: 0 additions & 5 deletions core/metadata.sh

This file was deleted.

Loading