diff --git a/startScan/templates/startScan/detail_scan.html b/startScan/templates/startScan/detail_scan.html index 5d695a91..9252478b 100644 --- a/startScan/templates/startScan/detail_scan.html +++ b/startScan/templates/startScan/detail_scan.html @@ -157,7 +157,7 @@ Detailed Scan Results for {{history.domain_name}}
-
+ +
+
+
+
{{discovered_ip_length}} Discovered IP Addresses
+
+
+
+ {% for ip in ip_list %} + {{ip}} + {% endfor %} +
+
+
+
{% include 'base/_items/interesting_recon.html' %}
{% if new_urls.count or removed_urls.count or new_subdomains or removed_subdomains %}
-
+
Subdomain Changes

@@ -581,18 +595,28 @@ Detailed Scan Results for {{history.domain_name}} }, { "render": function ( data, type, row ) { + badges = ''; interesting_badge = ''; + cdn_badge = ''; + if (row['is_cdn']) + { + cdn_badge = "CDN" + } if(row['is_interesting']) { - interesting_badge = "Interesting
" + interesting_badge = "Interesting" + } + if(cdn_badge || interesting_badge) + { + badges = cdn_badge + interesting_badge + '
'; } if (row['http_url']) { if (row['cname']) { - return interesting_badge + `
`+data+`
CNAME
❯ ` + row['cname'].replace(',', '
❯ ')+`
`; + return badges + ``+data+`
CNAME
❯ ` + row['cname'].replace(',', '
❯ ')+`
`; } - return interesting_badge + ``+data+`
`; + return badges + ``+data+`
`; } - return interesting_badge + ``+data+``; + return badges + ``+data+``; }, "targets": 1 }, @@ -616,11 +640,9 @@ Detailed Scan Results for {{history.domain_name}} }, { "render": function ( data, type, row ) { - // display badge based on http status - // green for http status 2XX, orange for 3XX and warning for everything else if (data) { - return span_values(data, "info"); + return parse_ip(data, row['is_cdn']); } return ""; }, @@ -1101,114 +1123,102 @@ Detailed Scan Results for {{history.domain_name}} }); }); - - + - {% endblock page_level_script %} +var chart = new ApexCharts( + document.querySelector("#vulnerability-chart"), + options +); + +chart.render(); + +//to remove the image element if there is no screenshot captured +function removeImageElement(element) +{ + element.parentElement.remove(); +} + +function subdomain_status_change(checkbox, id) +{ + if (checkbox.checked) { + checkbox.parentNode.parentNode.parentNode.className = "table-secondary text-strike"; + } + else { + checkbox.parentNode.parentNode.parentNode.classList.remove("table-secondary"); + checkbox.parentNode.parentNode.parentNode.classList.remove("text-strike"); + } + change_subdomain_status(id); +} + + +{% endblock page_level_script %} diff --git a/startScan/views.py b/startScan/views.py index aba639f5..f413de68 100644 --- a/startScan/views.py +++ b/startScan/views.py @@ -1,5 +1,6 @@ import os import requests +import itertools from datetime import datetime @@ -114,6 +115,13 @@ def detail_scan(request, id=None): context['removed_urls'] = endpoint_q2.difference(endpoint_q1) context['last_scan_endpoint'] = last_scan + ip_addresses = Subdomain.objects.filter(scan_history=id).values('ip_addresses').distinct() + if ip_addresses: + ip_list = [ip['ip_addresses'].split(',') for ip in ip_addresses if ip['ip_addresses'] is not None] + ip_list = list(set(list(itertools.chain(*ip_list)))) + context['ip_list'] = ip_list + context['discovered_ip_length'] = len(ip_list) + return render(request, 'startScan/detail_scan.html', context) diff --git a/static/assets/css/custom.css b/static/assets/css/custom.css index 7933eca3..8a961a85 100644 --- a/static/assets/css/custom.css +++ b/static/assets/css/custom.css @@ -278,3 +278,165 @@ div.dataTables_wrapper div.dataTables_filter { width: 22px; border-radius: 50%; } + +.widget.widget-ip { + position: relative; + background: #fff; + border-radius: 6px; + height: 250px; + padding: 0; } + .widget.widget-ip .widget-heading { + display: flex; + justify-content: space-between; + border-bottom: 1px dashed #e0e6ed; + padding: 20px 20px; + padding-bottom: 20px; + margin-bottom: 0; } + .widget.widget-ip .widget-heading h5 { + font-size: 17px; + display: block; + color: #0e1726; + font-weight: 600; + margin-bottom: 0; } + .widget.widget-ip .widget-heading .task-action svg { + color: #888ea8; + width: 19px; + height: 19px; } + .widget.widget-ip .widget-heading .task-action .dropdown-menu { + transform: translate3d(-141px, 0, 0px); } + +/* + ===================== + Unique Visitors + ===================== +*/ +/* + ========================= + Organic Vs Direct + ========================= +*/ +/* + ======================== + Recent Activities + ======================== +*/ +.widget-ip .widget-content { + padding: 12px 10px 21px 20px; } + +.widget-ip .w-shadow-top { + display: block; + position: absolute; + z-index: 2; + height: 17px; + width: 97%; + pointer-events: none; + margin-top: -10px; + left: 2px; + -webkit-filter: blur(9px); + filter: blur(9px); + background: -webkit-linear-gradient(180deg, #060818 44%, #060818eb 73%, #2C303C00); + background: linear-gradient(180deg, #ffffff 44%, #ffffffde 73%, #2C303C00); } + +.widget-ip .w-shadow-bottom { + display: block; + position: absolute; + z-index: 2; + height: 17px; + width: 97%; + pointer-events: none; + margin-top: -3px; + left: 2px; + -webkit-filter: blur(9px); + filter: blur(9px); + background: -webkit-linear-gradient(180deg, #ffffff 44%, #ffffffde 73%, #2C303C00); + background: linear-gradient(180deg, #ffffff 44%, #ffffffde 73%, #2C303C00); } + +.widget-ip .mt-container { + position: relative; + height: 170px; + overflow: auto; + padding: 15px 12px 0 12px; } + +.widget-ip .timeline-line .item-timeline { + display: flex; + margin-bottom: 35px; } + .widget-ip .timeline-line .item-timeline .t-dot { + position: relative; } + .widget-ip .timeline-line .item-timeline .t-dot div { + background: transparent; + border-radius: 50%; + padding: 5px; + margin-right: 11px; + display: flex; + height: 32px; + justify-content: center; + width: 32px; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-primary { + background-color: #c2d5ff; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-primary svg { + color: #4361ee; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-secondary { + background-color: #dccff7; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-secondary svg { + color: #805dca; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-success { + background-color: #c7e6e4; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-success svg { + color: #009688; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-danger { + background-color: #ffe1e2; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-danger svg { + color: #e7515a; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-warning { + background-color: #ffeccb; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-warning svg { + color: #e2a03f; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-dark { + background-color: #acb0c3; } + .widget-ip .timeline-line .item-timeline .t-dot div.t-dark svg { + color: #3b3f5c; } + .widget-ip .timeline-line .item-timeline .t-dot svg { + color: #fff; + height: 15px; + width: 15px; + align-self: center; } + .widget-ip .timeline-line .item-timeline .t-content { + width: 100%; } + .widget-ip .timeline-line .item-timeline .t-content .t-uppercontent { + display: flex; + justify-content: space-between; } + .widget-ip .timeline-line .item-timeline .t-content .t-uppercontent h5 { + font-size: 14px; + letter-spacing: 0; + font-weight: 600; + margin-bottom: 0; } + .widget-ip .timeline-line .item-timeline .t-content .t-uppercontent span { + margin-bottom: 0; + font-size: 13px; + font-weight: 600; + color: #009688; } + .widget-ip .timeline-line .item-timeline .t-content p { + margin-bottom: 0; + font-size: 12px; + font-weight: 600; + color: #888ea8; } + .widget-ip .timeline-line .item-timeline .t-content p a { + font-weight: 700; } + .widget-ip .timeline-line .item-timeline .t-dot:after { + content: ''; + position: absolute; + border-width: 1px; + border-style: solid; + left: 39%; + transform: translateX(-50%); + border-color: #bfc9d4; + width: 0; + height: auto; + top: 45px; + bottom: -23px; + border-right-width: 0; + border-top-width: 0; + border-bottom-width: 0; + border-radius: 0; } + .widget-ip .timeline-line .item-timeline:last-child .t-dot:after { + display: none; } diff --git a/static/custom/custom.js b/static/custom/custom.js index 764e46ae..ad9582f3 100644 --- a/static/custom/custom.js +++ b/static/custom/custom.js @@ -131,42 +131,42 @@ function vuln_status_change(checkbox, id) // truncate the long string and put ... in the end function truncate(source, size) { - return source.length > size ? source.slice(0, size - 1) + "…" : source; + return source.length > size ? source.slice(0, size - 1) + "…" : source; } // splits really long strings into multiple lines // Souce: https://stackoverflow.com/a/52395960 function split(str, maxWidth) { - const newLineStr = "
"; - done = false; - res = ''; - do { - found = false; - // Inserts new line at first whitespace of the line - for (i = maxWidth - 1; i >= 0; i--) { - if (testWhite(str.charAt(i))) { - res = res + [str.slice(0, i), newLineStr].join(''); - str = str.slice(i + 1); - found = true; - break; - } - } - // Inserts new line at maxWidth position, the word is too long to wrap - if (!found) { - res += [str.slice(0, maxWidth), newLineStr].join(''); - str = str.slice(maxWidth); - } + const newLineStr = "
"; + done = false; + res = ''; + do { + found = false; + // Inserts new line at first whitespace of the line + for (i = maxWidth - 1; i >= 0; i--) { + if (testWhite(str.charAt(i))) { + res = res + [str.slice(0, i), newLineStr].join(''); + str = str.slice(i + 1); + found = true; + break; + } + } + // Inserts new line at maxWidth position, the word is too long to wrap + if (!found) { + res += [str.slice(0, maxWidth), newLineStr].join(''); + str = str.slice(maxWidth); + } - if (str.length < maxWidth) - done = true; - } while (!done); + if (str.length < maxWidth) + done = true; + } while (!done); - return res + str; + return res + str; } function testWhite(x) { - const white = new RegExp(/^\s$/); - return white.test(x.charAt(0)); + const white = new RegExp(/^\s$/); + return white.test(x.charAt(0)); }; @@ -180,3 +180,30 @@ function get_response_time_text(response_time){ } return `${response_time.toFixed(4)}s`; } + +// span values function will seperate the values by comma and put badge around it +function span_values(data, color) +{ + var badge = ``; + var data_with_span =""; + data.split(/\s*,\s*/).forEach(function(split_vals) { + data_with_span+=badge + split_vals + ""; + }); + return data_with_span; +} + +// span values function will seperate the values by comma and put badge around it +function parse_ip(data, cdn){ + if (cdn) + { + var badge = ``; + } + else{ + var badge = ``; + } + var data_with_span =""; + data.split(/\s*,\s*/).forEach(function(split_vals) { + data_with_span+=badge + split_vals + ""; + }); + return data_with_span; +}