Skip to content

Commit

Permalink
Added Network paths
Browse files Browse the repository at this point in the history
  • Loading branch information
drakylar committed Jan 7, 2022
1 parent 8cdee54 commit d3f1117
Show file tree
Hide file tree
Showing 15 changed files with 10,785 additions and 162 deletions.
7 changes: 7 additions & 0 deletions documentation/report/report_fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@
9.2 host_id (or '')
9.3 html
9.4 markdown
10. paths {path_id}
10.1 host_out
10.2 network_out
10.3 host_in
10.4 network_in
10.5 description
10.6 type

Functions

Expand Down
2 changes: 1 addition & 1 deletion routes/api/v1/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1728,7 +1728,7 @@ def project_network_delete(args, current_user=None, current_token=None,
}
"""

db.delete_network(current_network['id'])
db.delete_network_safe(current_network['id'])
return {'status': 'ok'}


Expand Down
230 changes: 228 additions & 2 deletions routes/ui/project.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ipaddress

from routes.ui import routes
from functools import wraps
from docxtpl import DocxTemplate, InlineImage
Expand All @@ -24,6 +26,8 @@
from app import check_session, db, session, render_template, redirect, request, \
config, send_log_data, requires_authorization, cache

import requests


def check_project_access(fn):
@wraps(fn)
Expand Down Expand Up @@ -742,10 +746,21 @@ def hosts_hostnames_list(project_id, current_project, current_user):
@check_project_access
@send_log_data
def networks_list(project_id, current_project, current_user):
hosts_hostnames = [{'network':'{}/{}'.format(x['ip'], x['mask'])} for x in db.select_project_networks(current_project['id'])]
hosts_hostnames = [{'id': x['id'], 'network': '{}/{}'.format(x['ip'], x['mask'])} for x in db.select_project_networks(current_project['id'])]
return json.dumps(hosts_hostnames)


@routes.route('/project/<uuid:project_id>/issues/hosts_list',
methods=['GET'])
@requires_authorization
@check_session
@check_project_access
@send_log_data
def hosts_list(project_id, current_project, current_user):
hosts = [{'id': x['id'], 'ip': x['ip']} for x in db.select_project_hosts(current_project['id'])]
return json.dumps(hosts)


@routes.route('/project/<uuid:project_id>/issue/<uuid:issue_id>/',
methods=['POST'])
@requires_authorization
Expand Down Expand Up @@ -1193,6 +1208,109 @@ def networks(project_id, current_project, current_user):
tab_name='Networks')


@routes.route('/project/<uuid:project_id>/networks/graph',
methods=['GET'])
@requires_authorization
@check_session
@check_project_access
@send_log_data
def networks_graph(project_id, current_project, current_user):
return render_template('project/networks/graph_new.html',
current_project=current_project,
tab_name='Networks graph')


@routes.route('/project/<uuid:project_id>/networks/graph.json',
methods=['GET'])
@requires_authorization
@check_session
@check_project_access
@send_log_data
def networks_graph_json(project_id, current_project, current_user):
j = []
# add nodes
hosts = db.select_project_hosts(current_project['id'])

networks = db.select_project_networks(current_project['id'])
paths = db.select_project_paths(current_project['id'])
for current_network in networks:
j.append({
'group': 'nodes',
'data': {
'id': 'network_' + current_network['id'],
'name': '{}/{}'.format(current_network['ip'], current_network['mask'])
}
})
current_network['ip_obj'] = ipaddress.ip_network('{}/{}'.format(current_network['ip'], current_network['mask']))

j.append({
'group': 'nodes',
'data': {
'id': 'network_0',
'name': '0.0.0.0/0'
}
})

for current_host in hosts:

os_image = 'server.png'
if 'win' in current_host['os'].lower():
os_image = 'windows.png'
elif 'mac' in current_host['os'].lower():
os_image = 'macos.png'
elif 'lin' in current_host['os'].lower():
os_image = 'linux.png'

ip_obj = ipaddress.ip_address(current_host['ip'])

ip_json = {
'group': 'nodes',
'data': {
'id': 'host_' + current_host['id'],
'name': current_host['ip'],
'image': '/static/images/' + os_image,
'threats': json.loads(current_host['threats'])
}
}
found = 0
for current_network in networks:
if ip_obj in current_network['ip_obj']:
ip_json['data']['parent'] = 'network_' + current_network['id']
found = 1
if not found:
ip_json['data']['parent'] = 'network_0'
j.append(ip_json)

#j = j[::-1]

for current_path in paths:
source_id = ''
destination_id = ''

if current_path['host_out']:
source_id = 'host_' + current_path['host_out']
else:
source_id = 'network_' + current_path['network_out']

if current_path['host_in']:
destination_id = 'host_' + current_path['host_in']
else:
destination_id = 'network_' + current_path['network_in']

j.append({
'group': 'edges',
'data': {
'id': 'path_' + current_path['id'],
'source': source_id,
'target': destination_id,
'type': current_path['type'],
'direction': current_path['direction']
}
})

return json.dumps(j)


@routes.route('/project/<uuid:project_id>/networks/new_network',
methods=['GET'])
@requires_authorization
Expand Down Expand Up @@ -1320,7 +1438,7 @@ def project_network_edit(project_id, current_project, current_user,
errors.append(error)
else:
if form.action.data == 'Delete':
db.delete_network(current_network['id'])
db.delete_network_safe(current_network['id'])

is_ipv6 = False

Expand Down Expand Up @@ -1394,6 +1512,111 @@ def project_network_edit(project_id, current_project, current_user,
tab_name=current_network['ip'] + '/' + str(current_network['mask']))


@routes.route('/project/<uuid:project_id>/networks/add_path',
methods=['POST'])
@requires_authorization
@check_session
@check_project_access
@check_project_archived
@send_log_data
def new_path_form(project_id, current_project, current_user):
form = NewPath()
form.validate()
errors = []
if form.errors:
for field in form.errors:
for error in form.errors[field]:
errors.append(error)

host_out = ''
network_out = ''
host_in = ''
network_in = ''

if not errors:
if form.type_out.data == 'host':
host_id = form.out_id.data
current_host = db.select_host(host_id)
if not current_host or current_host[0]['project_id'] != current_project['id']:
errors.append('Wrong HOST_ID!')
else:
host_out = current_host[0]['id']
else:
network_id = form.out_id.data
current_network = db.select_network(network_id)
if not current_network or current_network[0]['project_id'] != current_project['id']:
errors.append('Wrong NETWORK_ID!')
else:
network_out = current_network[0]['id']
if form.type_in.data == 'host':
host_id = form.in_id.data
current_host = db.select_host(host_id)
if not current_host or current_host[0]['project_id'] != current_project['id']:
errors.append('Wrong HOST_ID!')
else:
host_in = current_host[0]['id']
else:
network_id = form.in_id.data
current_network = db.select_network(network_id)
if not current_network or current_network[0]['project_id'] != current_project['id']:
errors.append('Wrong NETWORK_ID!')
else:
network_in = current_network[0]['id']
added = 0
if not errors:
if (network_in != '' and network_in == network_out) or (host_in != '' and host_in == host_out):
errors.append('Source and destination are the same!')
else:
dublicate_paths = db.search_path(project_id=current_project['id'],
out_host=host_out,
out_network=network_out,
in_host=host_in,
in_network=network_in)
if dublicate_paths:
db.update_path_description_type(dublicate_paths[0]['id'],
description=form.description.data,
path_type=form.type.data,
direction=form.direction.data)
added = 1

if not errors and not added:
path_id = db.insert_path(project_id=current_project['id'],
out_host=host_out,
out_network=network_out,
in_host=host_in,
in_network=network_in,
description=form.description.data,
path_type=form.type.data,
direction=form.direction.data)

return render_template('project/networks/list.html',
current_project=current_project,
tab_name='Networks',
errors=errors)


@routes.route('/project/<uuid:project_id>/networks/delete_path',
methods=['POST'])
@requires_authorization
@check_session
@check_project_access
@check_project_archived
@send_log_data
def delete_path_form(project_id, current_project, current_user):
form = DeletePath()
form.validate()
errors = []
if form.errors:
for field in form.errors:
for error in form.errors[field]:
errors.append(error)
if not errors:
db.delete_path(path_id=form.path_id.data,
project_id=current_project['id'])

return redirect('/project/{}/networks/#/paths'.format(current_project['id']))


@routes.route('/project/<uuid:project_id>/credentials/',
methods=['GET'])
@requires_authorization
Expand Down Expand Up @@ -2652,6 +2875,7 @@ def docx_image(image_id, width=None, height=None):
"grouped_issues": project_dict['grouped_issues'],
"docx_image": docx_image,
"notes": project_dict['notes'],
"paths": project_dict['paths'],
"functions": {
"format_date": lambda unix_time,
str_format: datetime.datetime.fromtimestamp(int(unix_time)).strftime(str_format),
Expand Down Expand Up @@ -2747,6 +2971,7 @@ def docx_image(image_id, width=None, height=None):
hostnames=project_dict['hostnames'],
grouped_issues=project_dict['grouped_issues'],
notes=project_dict['notes'],
paths=project_dict['paths'],
latex_escape=latex_str_escape,
functions={
"format_date": lambda unix_time,
Expand Down Expand Up @@ -2833,6 +3058,7 @@ def docx_image(image_id, width=None, height=None):
hostnames=project_dict['hostnames'],
grouped_issues=project_dict['grouped_issues'],
notes=project_dict['notes'],
paths=project_dict['paths'],
latex_escape=latex_str_escape,
functions={
"format_date": lambda unix_time,
Expand Down
Loading

0 comments on commit d3f1117

Please sign in to comment.