mirror of https://github.com/CIRCL/lookyloo
new: easy way to find other captures with same favicon
parent
95a660cbda
commit
40ca3ed9bc
|
@ -339,6 +339,9 @@ class Indexing():
|
||||||
def favicons(self) -> list[tuple[str, float]]:
|
def favicons(self) -> list[tuple[str, float]]:
|
||||||
return self.redis.zrevrange('favicons', 0, 200, withscores=True)
|
return self.redis.zrevrange('favicons', 0, 200, withscores=True)
|
||||||
|
|
||||||
|
def favicon_frequency(self, favicon_sha512: str) -> float | None:
|
||||||
|
return self.redis.zscore('favicons', favicon_sha512)
|
||||||
|
|
||||||
def favicon_number_captures(self, favicon_sha512: str) -> int:
|
def favicon_number_captures(self, favicon_sha512: str) -> int:
|
||||||
return self.redis.scard(f'favicons|{favicon_sha512}|captures')
|
return self.redis.scard(f'favicons|{favicon_sha512}|captures')
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
||||||
import base64
|
import base64
|
||||||
import calendar
|
import calendar
|
||||||
import functools
|
import functools
|
||||||
|
import hashlib
|
||||||
import http
|
import http
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -833,6 +834,25 @@ def mark_as_legitimate(tree_uuid: str) -> Response:
|
||||||
return jsonify({'message': 'Legitimate entry added.'})
|
return jsonify({'message': 'Legitimate entry added.'})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/tree/<string:tree_uuid>/favicons', methods=['GET'])
|
||||||
|
def tree_favicons(tree_uuid: str) -> str:
|
||||||
|
favicons = []
|
||||||
|
favicons_zip = lookyloo.get_potential_favicons(tree_uuid, all_favicons=True, for_datauri=False)
|
||||||
|
with ZipFile(favicons_zip, 'r') as myzip:
|
||||||
|
for name in myzip.namelist():
|
||||||
|
if not name.endswith('.ico'):
|
||||||
|
continue
|
||||||
|
favicon = myzip.read(name)
|
||||||
|
if not favicon:
|
||||||
|
continue
|
||||||
|
favicon_sha512 = hashlib.sha512(favicon).hexdigest()
|
||||||
|
frequency = lookyloo.indexing.favicon_frequency(favicon_sha512)
|
||||||
|
number_captures = lookyloo.indexing.favicon_number_captures(favicon_sha512)
|
||||||
|
b64_favicon = base64.b64encode(favicon).decode()
|
||||||
|
favicons.append((favicon_sha512, frequency, number_captures, b64_favicon))
|
||||||
|
return render_template('tree_favicons.html', tree_uuid=tree_uuid, favicons=favicons)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/tree/<string:tree_uuid>/body_hashes', methods=['GET'])
|
@app.route('/tree/<string:tree_uuid>/body_hashes', methods=['GET'])
|
||||||
def tree_body_hashes(tree_uuid: str) -> str:
|
def tree_body_hashes(tree_uuid: str) -> str:
|
||||||
body_hashes = lookyloo.get_all_body_hashes(tree_uuid)
|
body_hashes = lookyloo.get_all_body_hashes(tree_uuid)
|
||||||
|
|
|
@ -84,6 +84,13 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
$('#faviconsModal').on('show.bs.modal', function(e) {
|
||||||
|
var button = $(e.relatedTarget);
|
||||||
|
var modal = $(this);
|
||||||
|
modal.find('.modal-body').load(button.data("remote"));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
$('#bodyHashesModal').on('show.bs.modal', function(e) {
|
$('#bodyHashesModal').on('show.bs.modal', function(e) {
|
||||||
var button = $(e.relatedTarget);
|
var button = $(e.relatedTarget);
|
||||||
var modal = $(this);
|
var modal = $(this);
|
||||||
|
@ -287,6 +294,10 @@
|
||||||
<a href="#bodyHashesModal" data-remote="{{ url_for('tree_body_hashes', tree_uuid=tree_uuid) }}"
|
<a href="#bodyHashesModal" data-remote="{{ url_for('tree_body_hashes', tree_uuid=tree_uuid) }}"
|
||||||
data-bs-toggle="modal" data-bs-target="#bodyHashesModal" role="button">Ressources Capture</a>
|
data-bs-toggle="modal" data-bs-target="#bodyHashesModal" role="button">Ressources Capture</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<a href="#faviconsModal" data-remote="{{ url_for('tree_favicons', tree_uuid=tree_uuid) }}"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#faviconsModal" role="button">Favicons Capture</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
|
@ -509,6 +520,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="faviconsModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="faviconsModalLabel">Favicons in tree</h5>
|
||||||
|
<button type="button" class="btn btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
... loading favicons ...
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" id="bodyHashesModal" tabindex="-1" role="dialog">
|
<div class="modal fade" id="bodyHashesModal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog modal-xl" role="document">
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<script type="text/javascript">
|
||||||
|
$('#faviconsTable')
|
||||||
|
.on('order.dt', () => {
|
||||||
|
$(function () {
|
||||||
|
$('[data-bs-toggle="tooltip"]').tooltip()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.on('search.dt', () => {
|
||||||
|
$(function () {
|
||||||
|
$('[data-bs-toggle="tooltip"]').tooltip()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.on('page.dt', () => {
|
||||||
|
$(function () {
|
||||||
|
$('[data-bs-toggle="tooltip"]').tooltip()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.DataTable( {
|
||||||
|
"order": [[ 1, "desc" ]],
|
||||||
|
"pageLength": 50
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% if from_popup %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
function openTreeInNewTab(treeUUID) {
|
||||||
|
window.opener.openTreeInNewTab(treeUUID);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<table id="faviconsTable" class="table w-auto">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Favicon</th>
|
||||||
|
<th>Frequency</th>
|
||||||
|
<th>Number of captures</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for favicon_sha512, freq, number_captures, b64_favicon in favicons %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('favicon_detail', favicon_sha512=favicon_sha512) }}">
|
||||||
|
<img src="data:image/ico;base64,{{ b64_favicon }}" style="width:32px;height:32px;"/>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ freq }}</td>
|
||||||
|
<td>{{ number_captures }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
Loading…
Reference in New Issue