mirror of https://github.com/CIRCL/lookyloo
fix: Support rendering non-icon favicons
parent
dcbec2efef
commit
104129bbe2
|
@ -3629,4 +3629,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.8.1,<3.13"
|
||||
content-hash = "6ed31d5e656cec63bfd4e1402b09b449ea7c3d5edb2ada0ec38e79b4784a38b7"
|
||||
content-hash = "0ae3318c2969c455c7d29bd34a9b28689a17cda4f10ca8352bcb0c7ebcb0a6ec"
|
||||
|
|
|
@ -80,6 +80,7 @@ urllib3 = [
|
|||
{version = "^2.0.7", python = ">=3.10"}
|
||||
]
|
||||
pypdns = "^2.2.2"
|
||||
python-magic = "^0.4.27"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
mypy = "^1.8.0"
|
||||
|
|
|
@ -15,6 +15,7 @@ import sys
|
|||
import time
|
||||
|
||||
import filetype # type: ignore[import-untyped]
|
||||
import magic
|
||||
|
||||
from datetime import date, datetime, timedelta, timezone
|
||||
from importlib.metadata import version
|
||||
|
@ -838,6 +839,7 @@ def mark_as_legitimate(tree_uuid: str) -> Response:
|
|||
def tree_favicons(tree_uuid: str) -> str:
|
||||
favicons = []
|
||||
favicons_zip = lookyloo.get_potential_favicons(tree_uuid, all_favicons=True, for_datauri=False)
|
||||
f = magic.Magic(mime=True)
|
||||
with ZipFile(favicons_zip, 'r') as myzip:
|
||||
for name in myzip.namelist():
|
||||
if not name.endswith('.ico'):
|
||||
|
@ -845,11 +847,12 @@ def tree_favicons(tree_uuid: str) -> str:
|
|||
favicon = myzip.read(name)
|
||||
if not favicon:
|
||||
continue
|
||||
mimetype = f.from_buffer(favicon)
|
||||
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))
|
||||
favicons.append((favicon_sha512, frequency, number_captures, mimetype, b64_favicon))
|
||||
return render_template('tree_favicons.html', tree_uuid=tree_uuid, favicons=favicons)
|
||||
|
||||
|
||||
|
@ -1243,11 +1246,14 @@ def hhh_detail(hhh: str) -> str:
|
|||
def favicon_detail(favicon_sha512: str) -> str:
|
||||
captures, favicon = lookyloo.get_favicon_investigator(favicon_sha512.strip())
|
||||
if favicon:
|
||||
f = magic.Magic(mime=True)
|
||||
mimetype = f.from_buffer(favicon)
|
||||
b64_favicon = base64.b64encode(favicon).decode()
|
||||
else:
|
||||
b64_favicon = ''
|
||||
mimetype = ''
|
||||
return render_template('favicon_details.html', favicon_sha512=favicon_sha512,
|
||||
captures=captures, b64_favicon=b64_favicon)
|
||||
captures=captures, mimetype=mimetype, b64_favicon=b64_favicon)
|
||||
|
||||
|
||||
@app.route('/body_hashes/<string:body_hash>', methods=['GET'])
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"favicon.ico": "KOmrfwRbOQqhhwSeBkNpMRAxSVMmmLg+2kRMg9iSv7OWjE9spJc7x4MKB4AE/hi0knaV7UBVctAU6XZ7AC72ZA==",
|
||||
"font.png": "RwoQkj9dT9SLUL2F7cAA16Nat9t2hDb58eQlHF9ThUar829p0INUXG+5XuDaFOC8SsmCZK5vw2f+YAQ6mLC1Qw==",
|
||||
"generic.css": "Sh/BcxFMLYYaLdCluVt9efGvJ9CF5d+YJ7lkL2M24PRGu8VZHI9lJiUlFObIocjQgwss3Ve2U5cUAE5WiAdpQQ==",
|
||||
"generic.js": "UmFl4fHmB/UjMdUuYdFy9BfzQlJTyeImNHCFyBO4SdLxBCwCGxkF3NQvel1PKqW8JTnoPlPpq/n9d+vCfPeegA==",
|
||||
"generic.js": "h2tLqpn8r1mZ/5FqiBDK6Er6mY5MdRuyir2mS9piT8VUUco2daxdKWSkiEtIsH2Ok+/W+NJb95A1ob5J/6sW4A==",
|
||||
"html.png": "T7pZrb8MMDsA/JV/51hu+TOglTqlxySuEVY0rpDjTuAEyhzk2v+W4kYrj7vX+Tp3n2d2lvVD08PwhCG62Yfbzg==",
|
||||
"ifr.png": "rI5YJypmz1QcULRf9UaOYSqV4tPUSxUdLAycoYzCwywt4Pw4eWzBg9SUr769VyIimoiIyJR+aNuoIA4p5WO2fQ==",
|
||||
"img.png": "bknBlmIfSb9qv9/lSaJ2idn2a8bDyvJ2pATj4oOpehRlCdXlWYOyb2jN3wV1QGHFoqyxNqOv5MfCpI0tbqkicg==",
|
||||
|
|
|
@ -24,3 +24,18 @@ function checkAllBoxes(name) {
|
|||
checkboxs[i].checked = !checkboxs[i].checked;
|
||||
}
|
||||
}
|
||||
|
||||
// Parameters:
|
||||
// contentType: The content type of your file.
|
||||
// its like application/pdf or application/msword or image/jpeg or
|
||||
// image/png and so on
|
||||
// base64Data: Its your actual base64 data
|
||||
// fileName: Its the file name of the file which will be downloaded.
|
||||
// Source: https://stackoverflow.com/questions/14011021/how-to-download-a-base64-encoded-image
|
||||
function downloadBase64File(contentType, base64Data, fileName) {
|
||||
const linkSource = `data:${contentType};base64,${base64Data}`;
|
||||
const downloadLink = document.createElement("a");
|
||||
downloadLink.href = linkSource;
|
||||
downloadLink.download = fileName;
|
||||
downloadLink.click();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</script>
|
||||
|
||||
<center>
|
||||
<img src="data:image/ico;base64,{{ b64_favicon }}" style="width:64px;height:64px;"/>
|
||||
<img src="data:{{mimetype}};base64,{{ b64_favicon }}" style="width:64px;height:64px;"/>
|
||||
</center>
|
||||
<table id="faviconDetailsTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
|
|
|
@ -15,13 +15,14 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for favicon_sha512, freq, number_captures, b64_favicon in favicons %}
|
||||
{% for favicon_sha512, freq, number_captures, mimetype, b64_favicon in favicons %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="#faviconDetailsModal" data-remote="{{ url_for('favicon_detail', favicon_sha512=favicon_sha512) }}"
|
||||
data-bs-toggle="modal" data-bs-target="#faviconDetailsModal" role="button">
|
||||
<img src="data:image/ico;base64,{{ b64_favicon }}" style="width:32px;height:32px;"/>
|
||||
<img src="data:{{mimetype}};base64,{{ b64_favicon }}" style="width:32px;height:32px;"/>
|
||||
</a>
|
||||
<button type="button" class="btn btn-light" onclick="downloadBase64File('{{mimetype}}', '{{b64_favicon}}', 'favicon.ico')">Download favicon</button>
|
||||
</td>
|
||||
<td>{{ freq }}</td>
|
||||
<td>{{ number_captures }}</td>
|
||||
|
|
Loading…
Reference in New Issue