From 4a9a50e2895971572a8cf4038131ad14d40398e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vinot?= Date: Mon, 31 Aug 2020 15:21:41 +0200 Subject: [PATCH] chg: Add icon for hostnodes with empty content. --- lookyloo/lookyloo.py | 11 ++++++++- website/web/static/tree.js | 50 ++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/lookyloo/lookyloo.py b/lookyloo/lookyloo.py index 0b853996..bb3dd410 100644 --- a/lookyloo/lookyloo.py +++ b/lookyloo/lookyloo.py @@ -285,6 +285,9 @@ class Context(): hostnodes_with_malicious_content = set() known_content = self.find_known_content(tree) for urlnode in tree.root_hartree.url_tree.traverse(): + if urlnode.empty_response: + continue + malicious = self.is_malicious(urlnode, known_content) if malicious is True: urlnode.add_feature('malicious', malicious) @@ -292,6 +295,8 @@ class Context(): elif malicious is False: # Marked as legitimate urlnode.add_feature('legitimate', True) + elif not urlnode.empty_response and urlnode.body_hash in known_content: + urlnode.add_feature('legitimate', True) for hostnode_with_malicious_content in hostnodes_with_malicious_content: hostnode = tree.root_hartree.get_host_node_by_uuid(hostnode_with_malicious_content) @@ -299,8 +304,12 @@ class Context(): for hostnode in tree.root_hartree.hostname_tree.traverse(): if 'malicious' not in hostnode.features: + if all(urlnode.empty_response for urlnode in hostnode.urls): + hostnode.add_feature('all_empty', True) + continue + legit = [urlnode.legitimate for urlnode in hostnode.urls if hasattr(urlnode, 'legitimate')] - if legit and all(legit): + if len(legit) == len(hostnode.urls) and all(legit): hostnode.add_feature('legitimate', True) return tree diff --git a/website/web/static/tree.js b/website/web/static/tree.js index aaa2c63c..e432c414 100644 --- a/website/web/static/tree.js +++ b/website/web/static/tree.js @@ -477,14 +477,14 @@ function update(root, computed_node_width=0) { }) .on('mouseout', () => d3.select('#tooltip').style('opacity', 0)); }; - const malicious_icon_size = 24; + const context_icon_size = 24; if (d.data.malicious) { // set bomb d3.select(this).append("svg").append('rect') .attr('x', selected_node_bbox.width - 22 - http_icon_size) .attr('y', selected_node_bbox.height - 13) - .attr('width', malicious_icon_size) - .attr('height', malicious_icon_size) + .attr('width', context_icon_size) + .attr('height', context_icon_size) .attr('fill', 'white') .attr('stroke', 'black'); @@ -492,8 +492,8 @@ function update(root, computed_node_width=0) { .attr('x', selected_node_bbox.width - 22 - http_icon_size) .attr('y', selected_node_bbox.height - 13) .attr('id', 'insecure_image') - .attr("width", malicious_icon_size) - .attr("height", malicious_icon_size) + .attr("width", context_icon_size) + .attr("height", context_icon_size) .attr("xlink:href", '/static/bomb.svg') .on('mouseover', () => { d3.select('#tooltip') @@ -503,14 +503,13 @@ function update(root, computed_node_width=0) { .text('This node containts known malicious content'); }) .on('mouseout', () => d3.select('#tooltip').style('opacity', 0)); - }; - if (d.data.legitimate) { + } else if (d.data.legitimate) { // set checkmark d3.select(this).append("svg").append('rect') .attr('x', selected_node_bbox.width - 22 - http_icon_size) .attr('y', selected_node_bbox.height - 13) - .attr('width', malicious_icon_size) - .attr('height', malicious_icon_size) + .attr('width', context_icon_size) + .attr('height', context_icon_size) .attr('fill', 'white') .attr('stroke', 'black'); @@ -518,18 +517,43 @@ function update(root, computed_node_width=0) { .attr('x', selected_node_bbox.width - 22 - http_icon_size) .attr('y', selected_node_bbox.height - 13) .attr('id', 'insecure_image') - .attr("width", malicious_icon_size) - .attr("height", malicious_icon_size) + .attr("width", context_icon_size) + .attr("height", context_icon_size) .attr("xlink:href", '/static/check.svg') .on('mouseover', () => { d3.select('#tooltip') .style('opacity', 1) .style('left', `${d3.event.pageX + 10}px`) .style('top', `${d3.event.pageY + 10}px`) - .text('This node containts only legitimate content'); + .text('This node has only legitimate content'); }) .on('mouseout', () => d3.select('#tooltip').style('opacity', 0)); - } + } else if (d.data.all_empty) { + // set empty + d3.select(this).append("svg").append('rect') + .attr('x', selected_node_bbox.width - 22 - http_icon_size) + .attr('y', selected_node_bbox.height - 13) + .attr('width', context_icon_size) + .attr('height', context_icon_size) + .attr('fill', 'white') + .attr('stroke', 'black'); + + d3.select(this).append('image') + .attr('x', selected_node_bbox.width - 22 - http_icon_size) + .attr('y', selected_node_bbox.height - 13) + .attr('id', 'insecure_image') + .attr("width", context_icon_size) + .attr("height", context_icon_size) + .attr("xlink:href", '/static/empty.svg') + .on('mouseover', () => { + d3.select('#tooltip') + .style('opacity', 1) + .style('left', `${d3.event.pageX + 10}px`) + .style('top', `${d3.event.pageY + 10}px`) + .text('This node has only empty content'); + }) + .on('mouseout', () => d3.select('#tooltip').style('opacity', 0)); + }; }); return node_group;