lookyloo/website/web/templates/macros.html

396 lines
15 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>
{% if categories_info is mapping %}
{% 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-primary {% if add_category %}categorize_capture{% else %}uncategorize_capture{% endif %}" value="{{ mt }}">
{% if add_category %}
Categorize capture.
{% else %}
Uncategorize capture.
{% endif %}
</button>
</td>
</tr>
{% endfor %}
{% else %}
{% for mt in categories_info %}
<tr>
<td></td>
<td>
</td>
<td>{{ mt }}</td>
<td>
<button type="button" class="btn btn-primary {% if add_category %}categorize_capture{% else %}uncategorize_capture{% endif %}" value="{{ mt }}">
{% if add_category %}
Categorize capture.
{% else %}
Uncategorize capture.
{% endif %}
</button>
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
<script nonce="{{ csp_nonce() }}">
$('.categorize_capture').on('click',function(e){
var button = $(this);
$.get("{{ url_for('categorize_capture', tree_uuid=tree_uuid) }}" + button.val())
$('#categoriesModal .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())
$('#categoriesModal .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, hash, callback_str) %}
<button class="btn btn-primary collapsed" type="button" data-bs-toggle="collapse" data-bs-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="row mb-3">
<div class="col-sm-10">
<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>
<div class="row mb-3">
<div class="col-sm-10">
<label for="legitimate_domain" class="form-label">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>
<div class="row mb-3">
<div class="col-sm-10">
<label for="legitimate_description" class="form-label">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>
<div class="row mb-3">
<div class="col-sm-10">
<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>
<div class="row mb-3">
<div class="col-sm-10">
<label for="malicious_type" class="form-label">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>
<div class="row mb-3">
<div class="col-sm-10">
<label for="malicious_target" class="form-label">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>
</div>
<input type="hidden" id="hash_to_contextualize" name="hash_to_contextualize" value="{{ hash }}">
<input type="hidden" id="callback_str" name="callback_str" value="{{ callback_str }}">
<button type="submit" class="btn btn-primary" 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-primary" name="ressource_hash" value="{{ hash }}"
{% if can_preview %}
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true"
title='<img class="ressource_preview" 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> (in the HTTP response): {{ 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 > 1 %}
<p>
The same file was seen in <b>{{ total_captures - 1 }}</b> other captures.
</br>
<button class="btn btn-primary collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#captureslist_{{ identifier_for_toggle }}"
aria-expanded="false" aria-controls="collapseExample">
<span class="if-collapsed">Show other recent captures</span>
<span class="if-not-collapsed">Hide other recent 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">
Note that only the most recent cached captures are displayed here, click on the link below to see more.
{% 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'], 20, identifier_for_toggle + '_same') }}
</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'], 20, identifier_for_toggle + '_different') }}
</div>
{% endif %}
</div>
</div>
{% endif %}
{% endmacro %}
{% macro other_captures_table(entries, max_entries, identifier) %}
<script type="text/javascript" nonce="{{ csp_nonce() }}">
document.addEventListener("DOMContentLoaded", () => {
new DataTable('#table_other_captures_{{identifier}}', {
"order": [[ 1, "desc" ]],
"paging": false,
"info": false,
"columns": [
{ "orderable": false},
{ "orderable": false},
{ "orderable": false}
],
"columnDefs": [{
"targets": 1,
"render": (data) => {
const date = new Date(data);
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
}
}]
} );
});
</script>
<div>
<table id="table_other_captures_{{identifier}}" class="table table-striped" style="width:100%">
<thead>
<tr>
<th>Title</th>
<th>Timestamp</th>
<th>Domain</th>
</tr>
</thead>
<tbody>
{% for capture_uuid, urlnode_uuid, title, timestamp, hostname in entries[:max_entries] %}
<tr>
<td>
<button type="button" class="btn btn-link openNewTab" data-capture="{{capture_uuid}}" data-hostnode="{{urlnode_uuid}}">{{ title }}</button>
</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-primary locateInTree" data-hostnode="{{ detail[1] }}">Locate</button>
</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{% macro popup_icons_request(urlnode, tree_uuid) %}
<div>
{% if urlnode.request_cookie %}
{% set icon_info = get_icon("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>
{% endif %}
</div>
{% endmacro %}
{% macro pandora_submit(tree_uuid, node_uuid, ressource_hash) %}
<div class="col-sm-8">
<button type="button" class="btn btn-primary btn-sm submitPandoraButton"
title="open a new tab with the pandora report"
data-hostnode="{{ node_uuid }}"
data-hash="{{ ressource_hash }}"
data-pandorasubmit="{{ url_for('pandora_submit', tree_uuid=tree_uuid)}}">
Submit to Pandora
</button>
</div>
{% endmacro %}
{% macro popup_icons_response(urlnode, tree_uuid) %}
<div>
{% if urlnode.response_cookie %}
{% set icon_info = get_icon("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>
{% endif %}
{% if urlnode.generic_type in ["js", "exe", "css", "font", "html", "json", "image", "video",
"unknown_mimetype", "text", "unset_mimetype", "octet-stream",
"livestream"] %}
{% set icon_info = get_icon(urlnode.generic_type) %}
<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 urlnode.generic_type == "image" %}
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true"
title='<img class="ressource_preview" src="{{ url_for('get_ressource_preview', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"/> </br>Click to download.'
{% else %}
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true"
title="{{icon_info['tooltip']}} <br/>Click to download."
{% endif %}
/>
</a>
{%endif%}
</div>
<div>
{% if urlnode["redirect"] %}
{% set icon_info = get_icon('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) }}
<button type="button" class="btn btn-link locateInTree" data-hostnode="{{ child.hostnode_uuid }}" title="See the node the URL redirects to.">
<img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}" width="21" height="21"/>
</button>
</div>
{% else %}
<img src="{{ url_for('static', filename=icon_info['icon']) }}"
alt="{{ icon_info['tooltip'] }}" title="{{ icon_info['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 %}