fix endpoint rendering

This commit is contained in:
Yogesh Ojha
2022-04-24 22:57:31 +05:30
parent 9f56874753
commit 29f4ff7e4c
5 changed files with 1575 additions and 1586 deletions
-4
View File
@@ -78,10 +78,6 @@ urlpatterns = [
'queryVulnerabilities/',
ListVulnerability.as_view(),
name='queryVulnerabilities'),
path(
'queryEndpoints/',
ListEndpoints.as_view(),
name='queryEndpoints'),
path(
'queryTargetsWithoutOrganization/',
ListTargetsWithoutOrganization.as_view(),
+56 -74
View File
@@ -820,33 +820,6 @@ class ListVulnerability(APIView):
return Response({'vulnerabilities': vulnerability_serializer.data})
class ListEndpoints(APIView):
def get(self, request, format=None):
req = self.request
scan_id = req.query_params.get('scan_id')
subdomain_name = req.query_params.get('subdomain_name')
pattern = req.query_params.get('pattern')
if scan_id:
endpoints = EndPoint.objects.filter(scan_history__id=scan_id)
else:
endpoints = EndPoint.objects.all()
if subdomain_name:
endpoints = endpoints.filter(subdomain__name=subdomain_name)
if pattern:
endpoints = endpoints.filter(matched_gf_patterns__icontains=pattern)
if 'only_urls' in req.query_params:
endpoints_serializer = EndpointOnlyURLsSerializer(endpoints, many=True)
else:
endpoints_serializer = EndpointSerializer(endpoints, many=True)
return Response({'endpoints': endpoints_serializer.data})
class VisualiseData(APIView):
def get(self, request, format=None):
req = self.request
@@ -1540,81 +1513,90 @@ class EndPointViewSet(viewsets.ModelViewSet):
def get_queryset(self):
req = self.request
scan_id = req.query_params.get('scan_history')
target_id = req.query_params.get('target_id')
url_query = req.query_params.get('query_param')
subdomain_id = req.query_params.get('subdomain_id')
gf_tag = req.query_params.get(
'gf_tag') if 'gf_tag' in req.query_params else None
if scan_id:
self.queryset = EndPoint.objects.filter(
endpoints_queryset = EndPoint.objects.filter(
scan_history__id=scan_id
).distinct()
elif target_id:
self.queryset = EndPoint.objects.filter(
endpoints_queryset = EndPoint.objects.filter(
target_domain__id=target_id).distinct()
else:
self.queryset = EndPoint.objects.distinct()
endpoints_queryset = EndPoint.objects.distinct()
if url_query:
self.queryset = EndPoint.objects.filter(
endpoints_queryset = endpoints_queryset.filter(
Q(target_domain__name=url_query)).distinct()
if gf_tag:
self.queryset = self.queryset.filter(matched_gf_patterns__icontains=gf_tag)
endpoints_queryset = endpoints_queryset.filter(matched_gf_patterns__icontains=gf_tag)
if subdomain_id:
endpoints_queryset = endpoints_queryset.filter(subdomain__id=subdomain_id)
if 'only_urls' in req.query_params:
self.serializer_class = EndpointOnlyURLsSerializer
self.queryset = endpoints_queryset
return self.queryset
def filter_queryset(self, qs):
qs = self.queryset.filter()
print(qs)
search_value = self.request.GET.get(u'search[value]', None)
_order_col = self.request.GET.get(u'order[0][column]', None)
_order_direction = self.request.GET.get(u'order[0][dir]', None)
order_col = 'content_length'
if _order_col == '1':
order_col = 'http_url'
elif _order_col == '2':
order_col = 'http_status'
elif _order_col == '3':
order_col = 'page_title'
elif _order_col == '4':
order_col = 'matched_gf_patterns'
elif _order_col == '5':
order_col = 'content_type'
elif _order_col == '6':
if search_value or _order_col or _order_direction:
order_col = 'content_length'
elif _order_col == '7':
order_col = 'technologies'
elif _order_col == '8':
order_col = 'webserver'
elif _order_col == '9':
order_col = 'response_time'
if _order_direction == 'desc':
order_col = '-{}'.format(order_col)
# if the search query is separated by = means, it is a specific lookup
# divide the search query into two half and lookup
if '=' in search_value or '&' in search_value or '|' in search_value or '>' in search_value or '<' in search_value or '!' in search_value:
if '&' in search_value:
complex_query = search_value.split('&')
for query in complex_query:
if query.strip():
qs = qs & self.special_lookup(query.strip())
elif '|' in search_value:
qs = Subdomain.objects.none()
complex_query = search_value.split('|')
for query in complex_query:
if query.strip():
qs = self.special_lookup(query.strip()) | qs
if _order_col == '1':
order_col = 'http_url'
elif _order_col == '2':
order_col = 'http_status'
elif _order_col == '3':
order_col = 'page_title'
elif _order_col == '4':
order_col = 'matched_gf_patterns'
elif _order_col == '5':
order_col = 'content_type'
elif _order_col == '6':
order_col = 'content_length'
elif _order_col == '7':
order_col = 'technologies'
elif _order_col == '8':
order_col = 'webserver'
elif _order_col == '9':
order_col = 'response_time'
if _order_direction == 'desc':
order_col = '-{}'.format(order_col)
# if the search query is separated by = means, it is a specific lookup
# divide the search query into two half and lookup
if '=' in search_value or '&' in search_value or '|' in search_value or '>' in search_value or '<' in search_value or '!' in search_value:
if '&' in search_value:
complex_query = search_value.split('&')
for query in complex_query:
if query.strip():
qs = qs & self.special_lookup(query.strip())
elif '|' in search_value:
qs = Subdomain.objects.none()
complex_query = search_value.split('|')
for query in complex_query:
if query.strip():
qs = self.special_lookup(query.strip()) | qs
else:
qs = self.special_lookup(search_value)
else:
qs = self.special_lookup(search_value)
else:
qs = self.general_lookup(search_value)
return qs.order_by(order_col)
qs = self.general_lookup(search_value)
return qs.order_by(order_col)
return qs
def general_lookup(self, search_value):
qs = self.queryset.filter(
Q(http_url__icontains=search_value) |
File diff suppressed because it is too large Load Diff
@@ -1639,7 +1639,7 @@ $(document).ready(function(){
endpoint_count_badge = '';
if (row['endpoint_count']) {
endpoint_count_badge = `<span class="pl-2 pr-2 badge badge-soft-primary badge-link bs-tooltip" title="Endpoints" onclick="get_endpoint_modal({{history.id}}, '${row['name']}')">${row['endpoint_count']} Endpoints</span>`
endpoint_count_badge = `<span class="pl-2 pr-2 badge badge-soft-primary badge-link bs-tooltip" title="Endpoints" onclick="get_endpoint_modal({{history.id}}, '${row['id']}')">${row['endpoint_count']} Endpoints</span>`
}
vuln_count_badge = '';
+72 -66
View File
@@ -1115,72 +1115,7 @@ function show_subscan_results(subscan_id) {
}
});
} else if(response['subscan']['task'] == 'fetch_url') {
$('#xl-modal-content').append(`<h5> ${response['result'].length} Endpoints Discovered on subdomain ${response['subscan']['subdomain_name']}</h5>`);
$('#xl-modal-content').append(`
<div class="">
<table id="endpoint-modal-datatable" class="table dt-responsive nowrap w-100">
<thead>
<tr>
<th>HTTP URL</th>
<th>Status</th>
<th>Page Title</th>
<th>Tags</th>
<th>Content Type</th>
<th>Content Length</th>
<th>Response Time</th>
</tr>
</thead>
<tbody id="endpoint_tbody">
</tbody>
</table>
</div>
`);
$('#endpoint_tbody').empty();
for(var endpoint_obj in response['result']) {
var endpoint = response['result'][endpoint_obj];
var tech_badge = '';
var web_server = '';
if(endpoint['technologies']) {
tech_badge = '<div>' + parse_technology(endpoint['technologies'], "primary", outline = true);
}
if(endpoint['webserver']) {
web_server = `<span class='m-1 badge badge-soft-info' data-toggle="tooltip" data-placement="top" title="Web Server">${endpoint['webserver']}</span>`;
}
var url = split_into_lines(endpoint['http_url'], 70);
var rand_id = get_randid();
tech_badge += web_server + '</div>';
var http_url_td = "<a href='" + endpoint['http_url'] + `' target='_blank' class='text-primary'>` + url + "</a>" + tech_badge;
$('#endpoint_tbody').append(`
<tr>
<td>${http_url_td}</td>
<td>${get_http_status_badge(endpoint['http_status'])}</td>
<td>${return_str_if_not_null(endpoint['page_title'])}</td>
<td>${parse_comma_values_into_span(endpoint['matched_gf_patterns'], "danger", outline=true)}</td>
<td>${return_str_if_not_null(endpoint['content_type'])}</td>
<td>${return_str_if_not_null(endpoint['content_length'])}</td>
<td>${get_response_time_text(endpoint['response_time'])}</td>
</tr>
`);
}
$("#endpoint-modal-datatable").DataTable({
"oLanguage": {
"oPaginate": {
"sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>',
"sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>'
},
"sInfo": "Showing page _PAGE_ of _PAGES_",
"sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
"sSearchPlaceholder": "Search...",
"sLengthMenu": "Results : _MENU_",
},
"dom": "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'f><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center'l>>>" + "<'table-responsive'tr>" + "<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
"order": [
[5, "desc"]
],
drawCallback: function() {
$(".dataTables_paginate > .pagination").addClass("pagination-rounded")
}
});
render_endpoint_in_xlmodal(endpoint_count = response['result'].length, subdomain_name = response['subscan']['subdomain_name'], result = response['result']);
} else if(response['subscan']['task'] == 'dir_file_fuzz') {
if(response['result'][0]['directory_files'].length == 0) {
$('#xl-modal-content').append(`
@@ -1266,3 +1201,74 @@ function get_http_status_badge(data) {
}
return "<span class='badge badge-soft-danger'>" + data + "</span>";
}
function render_endpoint_in_xlmodal(endpoint_count, subdomain_name, result) {
// This function renders endpoints datatable in xl modal
// Used in Subscan results and subdomain to endpoints modal
$('#xl-modal-content').append(`<h5> ${endpoint_count} Endpoints Discovered on subdomain ${subdomain_name}</h5>`);
$('#xl-modal-content').append(`
<div class="">
<table id="endpoint-modal-datatable" class="table dt-responsive nowrap w-100">
<thead>
<tr>
<th>HTTP URL</th>
<th>Status</th>
<th>Page Title</th>
<th>Tags</th>
<th>Content Type</th>
<th>Content Length</th>
<th>Response Time</th>
</tr>
</thead>
<tbody id="endpoint_tbody">
</tbody>
</table>
</div>
`);
$('#endpoint_tbody').empty();
for(var endpoint_obj in result) {
var endpoint = result[endpoint_obj];
var tech_badge = '';
var web_server = '';
if(endpoint['technologies']) {
tech_badge = '<div>' + parse_technology(endpoint['technologies'], "primary", outline = true);
}
if(endpoint['webserver']) {
web_server = `<span class='m-1 badge badge-soft-info' data-toggle="tooltip" data-placement="top" title="Web Server">${endpoint['webserver']}</span>`;
}
var url = split_into_lines(endpoint['http_url'], 70);
var rand_id = get_randid();
tech_badge += web_server + '</div>';
var http_url_td = "<a href='" + endpoint['http_url'] + `' target='_blank' class='text-primary'>` + url + "</a>" + tech_badge;
$('#endpoint_tbody').append(`
<tr>
<td>${http_url_td}</td>
<td>${get_http_status_badge(endpoint['http_status'])}</td>
<td>${return_str_if_not_null(endpoint['page_title'])}</td>
<td>${parse_comma_values_into_span(endpoint['matched_gf_patterns'], "danger", outline=true)}</td>
<td>${return_str_if_not_null(endpoint['content_type'])}</td>
<td>${return_str_if_not_null(endpoint['content_length'])}</td>
<td>${get_response_time_text(endpoint['response_time'])}</td>
</tr>
`);
}
$("#endpoint-modal-datatable").DataTable({
"oLanguage": {
"oPaginate": {
"sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>',
"sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>'
},
"sInfo": "Showing page _PAGE_ of _PAGES_",
"sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
"sSearchPlaceholder": "Search...",
"sLengthMenu": "Results : _MENU_",
},
"dom": "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'f><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center'l>>>" + "<'table-responsive'tr>" + "<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
"order": [
[5, "desc"]
],
drawCallback: function() {
$(".dataTables_paginate > .pagination").addClass("pagination-rounded")
}
});
}