Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@ $ pip3 install -r attack2jira/requirements.txt

- You will need a [Jira Software Cloud](https://www.atlassian.com/software) environment.
- You can set up a [free trial](https://www.atlassian.com/software/jira/free) environment for up to 10 users [here](https://www.atlassian.com/try/cloud/signup?bundle=jira-software&edition=free).
- Admin access is required
- Admin access is required

### Usage

Print the help menu
```
$ python3 attack2jira.py -h
```

Create the Jira ATTACK project and issues
```
$ python3 attack2jira.py -url https://yourjiracloud.atlassian.net -u user@domain.com -a initialize
Expand All @@ -43,6 +42,13 @@ $ pip3 install -r attack2jira/requirements.txt
```
$ python3 attack2jira.py -url https://yourjiracloud.atlassian.net -u user@domain.com -a initialize -p 'ATTACK Coverage' -k ATT
```
Create a Jira Kanban board on existing project and issues
```
$ python3 attack2jira.py -url https://yourjiracloud.atlassian.net -u user@domain.com -a board
```
>It will then prompt you for the [FilterID](https://community.atlassian.com/t5/Jira-questions/Where-to-find-Filter-ID/qaq-p/81945) and BoardID (if there is not an existing board you'd like to add the tickets to, it will create one for you if you leave blank).
Reminder: FilterIDs are neccesary because it specifies the filter for the board. They could be like Select * from PROJECTNAME or you can also specify them to only contain "MITRE".

Export an ATTACK Navigator JSON layer
```
$ python3 attack2jira.py -url https://yourjiracloud.atlassian.net -u user@domain.com -a export
Expand Down
323 changes: 158 additions & 165 deletions attack2jira.py

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions lib/boardhandler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import sys
import traceback
import requests
import urllib3
from typing import NamedTuple
from yarl import URL
from http import HTTPStatus

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class BoardHandler(NamedTuple):
""" Kanban Board Class for Attack2Jira"""

url: URL
username: str
apitoken: str

def check_board(self, board_id):
# TODO: pass the id created from create_board() if there isn't a board created for future checks
"""Checks if Kanban Board Exists"""

print("[*] Checking if there is an Att&ck board... ")

headers = {"Content-Type": "application/json"}

r = requests.get(
f"{self.url}/rest/agile/1.0/board/{board_id}",
headers=headers,
auth=(self.username, self.apitoken),
verify=False,
)

if r.status_code == HTTPStatus.OK:
print("[!] Success! Looks like there is an existing kanban board")
return True

else:
print("[!] No board detected ")
return False

def create_board(self, board, filter_id, project_key):
"""Creates Kanban Board under Project: Security"""

print("[*] Creating the Att&ck board...")
headers = {"Content-Type": "application/json"}

project_dict = {
"name": board,
"type": "kanban",
"filterId": filter_id,
"location": {"type": "project", "projectKeyOrId": project_key},
}

r = requests.post(
f"{self.url}/rest/agile/1.0/board",
json=project_dict,
headers=headers,
auth=(self.username, self.apitoken),
verify=False,
)
if r.status_code == HTTPStatus.CREATED:
print("[!] Success!")
return HTTPStatus.OK

elif r.status_code == HTTPStatus.UNAUTHORIZED:
print("[!] Unauthorized. Probably not enough permissions :(")
return HTTPStatus.UNAUTHORIZED

else:
print("[!] Error creating Jira board: ")
traceback.print_exc(file=sys.stderr)
return HTTPStatus.BAD_REQUEST
Loading