mirror of https://github.com/CIRCL/lookyloo
321 lines
12 KiB
HTML
321 lines
12 KiB
HTML
{% macro taxonomy_table(tree_uuid, categories_info, add_category) %}
|
|
<div class="table-responsive">
|
|
<table id="table" class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Description</th>
|
|
<th>Machinetag</th>
|
|
{% if add_category %}
|
|
<th>Click to add category</th>
|
|
{% else %}
|
|
<th>Click to remove category</th>
|
|
{% endif %}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for mt, val in categories_info.items() %}
|
|
<tr>
|
|
<td><a href="https://www.misp-project.org/taxonomies.html#_{{ val[0].name }}">{{ val[0].name }}</a></td>
|
|
<td>
|
|
{% if val|length == 3 %}
|
|
{% if val[2].description %}
|
|
{{ val[2].description }}
|
|
{% elif val[2].expanded %}
|
|
{{ val[2].expanded }}
|
|
{%endif%}
|
|
{% elif val[1].description %}
|
|
{{ val[1].description }}
|
|
{% else %}
|
|
{{ val[1].predicate }}
|
|
{%endif%}
|
|
</td>
|
|
<td>{{ mt }}</td>
|
|
<td>
|
|
<button type="button" class="btn btn-info {% if add_category %}categorize_capture{% else %}uncategorize_capture{% endif %}" value="{{ mt }}">
|
|
{% if add_category %}
|
|
Categorize capture.
|
|
{% else %}
|
|
Uncategorize capture.
|
|
{% endif %}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<script>
|
|
$('.categorize_capture').on('click',function(e){
|
|
var button = $(this);
|
|
$.get("{{ url_for('categorize_capture', tree_uuid=tree_uuid) }}" + button.val())
|
|
$('.modal-body').load("{{ url_for('categories_capture', tree_uuid=tree_uuid) }}")
|
|
});
|
|
$('.uncategorize_capture').on('click',function(e){
|
|
var button = $(this);
|
|
$.get("{{ url_for('uncategorize_capture', tree_uuid=tree_uuid) }}" + button.val())
|
|
$('.modal-body').load("{{ url_for('categories_capture', tree_uuid=tree_uuid) }}")
|
|
});
|
|
</script>
|
|
{% endmacro %}
|
|
|
|
|
|
{% macro known_content_details(details) %}
|
|
<div>
|
|
{% if details is string %}
|
|
<b>{{ details }} </b>
|
|
{% else %}
|
|
This file is known as part of <b>{{ details[0] }}</b>
|
|
version <b>{{ details[1] }}</b>: <b>{{ details[2] }}</b>.
|
|
{% if details[3] > 1%}
|
|
It is also present in <b>{{ details[3] -1 }}</b> other libraries.
|
|
{%endif%}
|
|
{%endif%}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro context_form(tree_uuid, urlnode_uuid, hostnode_uuid, hash, callback_str) %}
|
|
<button class="btn btn-info collapsed" type="button" data-toggle="collapse" data-target="#context_response_{{ urlnode_uuid }}" aria-expanded="false" aria-controls="collapseContextForm">
|
|
<span class="if-collapsed">Add context</span>
|
|
<span class="if-not-collapsed">Hide context form</span>
|
|
</button>
|
|
<div class="collapse" id="context_response_{{ urlnode_uuid }}">
|
|
<div class="card card-body">
|
|
<form role="form" action="{{ url_for('add_context', tree_uuid=tree_uuid, node_uuid=urlnode_uuid) }}" method=post enctype=multipart/form-data>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="legitimate" id="legitimate">
|
|
<label for="legitimate" class="form-check-label">Legitimate</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="legitimate_domain">Domain serving the file when considered legitimate:</label>
|
|
<input type="text" class="form-control" name="legitimate_domain" id="legitimate_domain" placeholder="Domain name">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="legitimate_description">Other context for this content (library name, owner, ...):</label>
|
|
<input type="text" class="form-control" name="legitimate_description" id="legitimate_description" placeholder="Description">
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="malicious"></input>
|
|
<label for="malicious" class="form-check-label">Malicious</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="malicious_type">Type of malicious content (phishing, malware, ...):</label>
|
|
<input type="text" class="form-control" name="malicious_type" id="malicious_type" placeholder="Type of malicious content">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="malicious_target">Legitimate target of the malicious content (expecially for phishing):</label>
|
|
<input type="text" class="form-control" name="malicious_target" id="malicious_target" placeholder="Target">
|
|
</div>
|
|
<input type="hidden" id="hash_to_contextualize" name="hash_to_contextualize" value="{{ hash }}">
|
|
<input type="hidden" id="hostnode_uuid" name="hostnode_uuid" value="{{ hostnode_uuid }}">
|
|
<input type="hidden" id="callback_str" name="callback_str" value="{{ callback_str }}">
|
|
<button type="submit" class="btn btn-info" id="btn-looking">Submit context</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro get_ressource_button(capture_uuid, urlnode_uuid, hash, text, can_preview=False) %}
|
|
<form method="post" action="{{ url_for('get_ressource', tree_uuid=capture_uuid, node_uuid=urlnode_uuid) }}">
|
|
<button class="btn btn-info" name="ressource_hash" value="{{ hash }}"
|
|
{% if can_preview %}
|
|
data-toggle="tooltip" data-placement="bottom" data-html="true"
|
|
title='<img src="{{ url_for('get_ressource_preview', tree_uuid=capture_uuid, node_uuid=urlnode_uuid, h_ressource=hash) }}"/>'
|
|
{% endif %}
|
|
>{{ text }}</button>
|
|
</form>
|
|
{% endmacro %}
|
|
|
|
{% macro ressource_legitimacy_details(details, ressource_size) %}
|
|
{% if details and details[0] == False %}
|
|
<img src="/static/bomb.svg" title="Known malicious content in the response." width="21" height="21"/>
|
|
{%endif%}
|
|
<b>Body size</b>: {{ sizeof_fmt(ressource_size) }}
|
|
{% if details %}
|
|
{% if details[0] %}
|
|
- This file is known <b>legitimate</b> on the following domains: {{ ', '.join(details[1]) }}.
|
|
{% elif details[0] == False %}
|
|
</br>
|
|
<p>
|
|
The response sould be considered as
|
|
{% if details[1] is mapping and details[1].get('tag') %}
|
|
<b>{{ ', '.join(details[1]['tag']) }}</b>
|
|
{% else %}
|
|
<b>phishing</b>
|
|
{%endif%}
|
|
{% if details[1] is mapping and details[1].get('target') %}
|
|
and is targeting <b>the following domain(s)</b>: {{ ', '.join(details[1]['target']) }}
|
|
{% else %}
|
|
unless it is served by <b>the following domain(s)</b>: {{ ', '.join(details[1]) }}
|
|
{%endif%}
|
|
</p>
|
|
{%endif%}
|
|
{%endif%}
|
|
{% endmacro %}
|
|
|
|
{% macro indexed_hash(details, identifier_for_toggle) %}
|
|
{% set total_captures = details[0] %}
|
|
{% set other_captures = details[1] %}
|
|
{# Only show details if the hits are in an other capture #}
|
|
{% if total_captures > 0 %}
|
|
<p>
|
|
The same file was seen in <b>{{ total_captures }}</b> other captures.
|
|
<button class="btn btn-info collapsed" type="button" data-toggle="collapse" data-target="#captureslist_{{ identifier_for_toggle }}" aria-expanded="false" aria-controls="collapseExample">
|
|
<span class="if-collapsed">Show other captures</span>
|
|
<span class="if-not-collapsed">Hide other captures</span>
|
|
</button>
|
|
</p>
|
|
{# Lists of other captures loading the same content... #}
|
|
<div class="collapse" id="captureslist_{{ identifier_for_toggle }}">
|
|
<div class="card card-body">
|
|
{% if total_captures > 20 %}
|
|
Note that only 20 captures are displayed here.
|
|
{% endif %}
|
|
{% if other_captures['different_url']|length > 0 %}
|
|
{# ... on other URLs #}
|
|
<div>
|
|
<p>The following captures get the same file from a <b>different URL</b></p>
|
|
{{ other_captures_table(other_captures['different_url']) }}
|
|
</div>
|
|
{% endif %}
|
|
</br>
|
|
{% if other_captures['same_url']|length > 0 %}
|
|
{# ... on the same URL #}
|
|
<div>
|
|
<p>The following captures get the same file from the <b>same URL</b></p>
|
|
{{ other_captures_table(other_captures['same_url']) }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro other_captures_table(entries) %}
|
|
<div class="table-responsive">
|
|
<table id="table_other_captures" class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Title</th>
|
|
<th>Timestamp</th>
|
|
<th>Domain</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for capture_uuid, urlnode_uuid, title, timestamp, hostname in entries %}
|
|
<tr>
|
|
<td>
|
|
<a href="#/" onclick="openTreeInNewTab('{{ capture_uuid }}', '{{ urlnode_uuid }}')">{{ title }}</a>
|
|
</td>
|
|
<td>{{ timestamp }}</td>
|
|
<td>{{ hostname }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro indexed_cookies(header_text, button_text, cookies) %}
|
|
{% if cookies %}
|
|
<div>{{ header_text }}</div>
|
|
<ul>
|
|
{% for cookie, details in cookies.items() %}
|
|
{% set cookie_name_value = cookie.split('=', 1) %}
|
|
{% for detail in details %}
|
|
{% if detail|length == 1 %}
|
|
<li>
|
|
{{ detail[0] }}: <a href="{{ url_for('cookies_name_detail', cookie_name=cookie_name_value[0]) }}">
|
|
{{ cookie_name_value[0] }}</a>={{ shorten_string(cookie_name_value[1], 200) }}
|
|
</li>
|
|
{% else %}
|
|
<li>
|
|
{{ detail[0] }}: <a href="{{ url_for('cookies_name_detail', cookie_name=cookie_name_value[0]) }}">
|
|
{{ cookie_name_value[0] }}</a>={{ shorten_string(cookie_name_value[1], 200) }} -
|
|
</br>
|
|
{{ button_text }}
|
|
<button type="button" class="btn btn-info" onclick="whereAmI('{{ detail[1] }}')">Locate</button>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
</ul>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro popup_icons(lookup_dict, urlnode, tree_uuid) %}
|
|
<div>
|
|
{% for key, icon_info in lookup_dict.items() %}
|
|
{% if urlnode[key] %}
|
|
{% if key == "request_cookie" %}
|
|
<a href="{{ url_for('urlnode_request_cookies', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"
|
|
title="Download all the cookies in the request to the server">
|
|
<img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}"
|
|
width="21" height="21"/>
|
|
</a>
|
|
{% elif key == "response_cookie"%}
|
|
<a href="{{ url_for('urlnode_response_cookies', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"
|
|
title="Download all the cookies in the response from the server">
|
|
<img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}"
|
|
width="21" height="21"/>
|
|
</a>
|
|
{% elif key in ["js", "exe", "css", "font", "html", "json", "image", "video",
|
|
"unknown_mimetype", "text", "unset_mimetype", "octet-stream", "livestream"]
|
|
and not urlnode.empty_response %}
|
|
<a href="{{ url_for('get_ressource', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}">
|
|
<img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}"
|
|
width="21" height="21"
|
|
{% if key == "image" %}
|
|
data-toggle="tooltip" data-placement="bottom" data-html="true" title='<img src="{{ url_for('get_ressource_preview', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"/> </br>Click to download the content of the response in a zip file'
|
|
{% else %}
|
|
data-toggle="tooltip" data-placement="bottom" data-html="true" title="{{icon_info['tooltip']}} <br/>Click to download."
|
|
{% endif %}
|
|
/>
|
|
</a>
|
|
{% elif key != "redirect" %}
|
|
<img src="{{ url_for('static', filename=icon_info['icon']) }}"
|
|
alt="{{ icon_info['tooltip'] }}" title="{{ icon_info['tooltip'] }}" width="21" height="21"/>
|
|
{%endif%}
|
|
{%endif%}
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div>
|
|
{% if "redirect" in lookup_dict and urlnode["redirect"] %}
|
|
{% for child in urlnode.children if child.name == urlnode.redirect_url %}
|
|
<div title='{{ urlnode.redirect_url }}'>
|
|
<b>Redirect to</b>: {{ shorten_string(urlnode.redirect_url, 50) }}
|
|
<a href="#/" role="button" onclick="whereAmI('{{ child.hostnode_uuid }}')" title="See the node the URL redirects to.">
|
|
<img src="{{ url_for('static', filename=lookup_dict['redirect']['icon']) }}" alt="{{ lookup_dict['redirect']['tooltip'] }}" width="21" height="21"/>
|
|
</a>
|
|
</div>
|
|
{% else %}
|
|
<img src="{{ url_for('static', filename=lookup_dict['redirect']['icon']) }}"
|
|
alt="{{ lookup_dict['redirect']['tooltip'] }}" title="{{ lookup_dict['redirect']['tooltip'] }}"
|
|
width="21" height="21"/>
|
|
{% endfor %}
|
|
{%endif%}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro shorten_string(string, cut_length, with_title=False) %}
|
|
{% if with_title %}
|
|
<div title={{string}}>
|
|
{%endif%}
|
|
|
|
{% if string|length > cut_length %}
|
|
{{ string[:cut_length] }} [...]
|
|
{% else %}
|
|
{{ string }}
|
|
{%endif%}
|
|
|
|
{% if with_title %}
|
|
</div>
|
|
{%endif%}
|
|
|
|
{% endmacro %}
|